首先声明,这些内容都是借鉴来的,稍微改动了一下。
主要就是三个应用类ColumnGroup, GroupableTableHeader,GroupableTableHeaderU 和一个示例类GroupableHeaderExample
1、ColumnGroup类主要负责多表头的构建
import java.awt.Component; import java.awt.Dimension; import java.util.Enumeration; import java.util.Vector;
import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn;
public class ColumnGroup { protected TableCellRenderer renderer;
protected Vector v;
protected String text;
protected int margin = 0;
public ColumnGroup(String text) { this(null, text); }
public ColumnGroup(TableCellRenderer renderer, String text) { if (renderer == null) { this.renderer = new DefaultTableCellRenderer() { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JTableHeader header = table.getTableHeader(); if (header != null) { setForeground(header.getForeground()); setBackground(header.getBackground()); setFont(header.getFont()); } setHorizontalAlignment(JLabel.CENTER); this.setText((value == null) ? "" : value.toString()); setBorder(UIManager.getBorder("TableHeader.cellBorder")); return this; } }; } else { this.renderer = renderer; } this.text = text; v = new Vector(); }
/** * @param obj * TableColumn or ColumnGroup */ public void add(Object obj) { if (obj == null) { return; } v.addElement(obj); }
/** * @param c * TableColumn * @param v * ColumnGroups */ public Vector getColumnGroups(TableColumn c, Vector g) { g.addElement(this); if (v.contains(c)) return g; Enumeration enumeration = v.elements(); while (enumeration.hasMoreElements()) { Object obj = enumeration.nextElement(); if (obj instanceof ColumnGroup) { Vector groups = (Vector) ((ColumnGroup) obj).getColumnGroups(c, (Vector) g.clone()); if (groups != null) return groups; } } return null; }
public TableCellRenderer getHeaderRenderer() { return renderer; }
public Object getHeaderValue() { return text; }
public int getSize() { return v == null ? 0 : v.size(); }
public Dimension getSize(JTable table) { Component comp = renderer.getTableCellRendererComponent(table, getHeaderValue(), false, false, -1, -1); int height = comp.getPreferredSize().height; int width = 0; Enumeration enumeration = v.elements(); while (enumeration.hasMoreElements()) { Object obj = enumeration.nextElement(); if (obj instanceof TableColumn) { TableColumn aColumn = (TableColumn) obj; width += aColumn.getWidth(); width += margin; } else { width += ((ColumnGroup) obj).getSize(table).width; } } return new Dimension(width, height); }
/** * * 创建日期:(2003-7-14 10:53:26) * * @return java.lang.String */ public java.lang.String getText() { return text; }
/** * 列表头中删除Column 创建日期:(2002-9-25 15:49:00) */ public boolean removeColumn(ColumnGroup ptg, TableColumn tc) { boolean retFlag = false; if (tc != null) { for (int i = 0; i < ptg.v.size(); i++) { Object tmpObj = ptg.v.get(i); if (tmpObj instanceof ColumnGroup) { retFlag = removeColumn((ColumnGroup) tmpObj, tc); // 如果找到返回 if (retFlag) break; } else if (tmpObj instanceof TableColumn) { // 判断是否查找的对象 if (tmpObj == tc) { ptg.v.remove(i); retFlag = true; break; } } } } return retFlag; }
/** * 列表头中删除ColumnGrp 删除返回true,否则返回false; 创建日期:(2002-9-25 15:49:00) */ public boolean removeColumnGrp(ColumnGroup ptg, ColumnGroup tg) { boolean retFlag = false; if (tg != null) { for (int i = 0; i < ptg.v.size(); i++) { Object tmpObj = ptg.v.get(i); if (tmpObj instanceof ColumnGroup) { // 判断是否查找的对象 if (tmpObj == tg) { ptg.v.remove(i); retFlag = true; break; } else { retFlag = removeColumnGrp((ColumnGroup) tmpObj, tg); // 如果找到返回 if (retFlag) break;
} } else if (tmpObj instanceof TableColumn) { break; } } } return retFlag; }
public void setColumnMargin(int margin) { this.margin = margin; Enumeration enumeration = v.elements(); while (enumeration.hasMoreElements()) { Object obj = enumeration.nextElement(); if (obj instanceof ColumnGroup) { ((ColumnGroup) obj).setColumnMargin(margin); } } }
public void setHeaderRenderer(TableCellRenderer renderer) { if (renderer != null) { this.renderer = renderer; } }
/** * * 创建日期:(2003-7-14 10:53:26) * * @param newText * java.lang.String */ public void setText(java.lang.String newText) { text = newText; } }
2、GroupableHeader继承自JTableHeader,为多表头结构的管理者
import java.util.Enumeration; import java.util.Vector;
import javax.swing.table.JTableHeader; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel;
/** * GroupableTableHeader * @author flyx */
public class GroupableTableHeader extends JTableHeader { private static final String uiClassID = "GroupableTableHeaderUI"; protected Vector columnGroups = null; public GroupableTableHeader(TableColumnModel model) { super(model); setUI(new GroupableTableHeaderUI()); setReorderingAllowed(false); setRequestFocusEnabled(false); } public void addColumnGroup(ColumnGroup g) { if (columnGroups == null) { columnGroups = new Vector(); } columnGroups.addElement(g); } /** * * 创建日期:(2001-8-31 15:54:29) */ public void clearColumnGroups() { columnGroups = null; } public ColumnGroup[] getColumnGroups() { ColumnGroup[] retg=null; if (columnGroups.size()>0) { retg=new ColumnGroup[columnGroups.size()]; columnGroups.copyInto(retg); } return retg; } public Enumeration getColumnGroups(TableColumn col) { if (columnGroups == null) return null; Enumeration enum = columnGroups.elements(); while (enum.hasMoreElements()) { ColumnGroup cGroup = (ColumnGroup) enum.nextElement(); Vector v_ret = (Vector) cGroup.getColumnGroups(col, new Vector()); if (v_ret != null) { return v_ret.elements(); } } return null; } /** * Identifies whether or not this component can receive the focus. * A disabled button, for example, would return false. * * @return true if this component can receive the focus */ public boolean isFocusTraversable() { return super.isFocusTraversable() && isRequestFocusEnabled(); } public void setColumnMargin() { if (columnGroups == null) return; int columnMargin = getColumnModel().getColumnMargin(); Enumeration enum = columnGroups.elements(); while (enum.hasMoreElements()) { ColumnGroup cGroup = (ColumnGroup) enum.nextElement(); cGroup.setColumnMargin(columnMargin); } } public void setReorderingAllowed(boolean b) { reorderingAllowed = b; } }
3、GroupableTableHeaderUI继承自BasicTableHeaderUI,是多表头的画匠
import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Rectangle; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector;
import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.plaf.basic.BasicTableHeaderUI; import javax.swing.table.*;
/** * 多表头TableHeaderUI * * @author flyx */ public class GroupableTableHeaderUI extends BasicTableHeaderUI { private int m_height;
private Dimension createHeaderSize(long width) { TableColumnModel columnModel = header.getColumnModel(); width += columnModel.getColumnMargin() * columnModel.getColumnCount(); if (width > Integer.MAX_VALUE) { width = Integer.MAX_VALUE; } return new Dimension((int) width, getHeaderHeight()); }
/** * 获得该多表头下的基本列数(zjb) 递归 创建日期:(02-4-8 18:03:56) * * @return int * @param cg * nc.ui.pub.beans.table.ColumnGroup */ private int getColCountUnderColGroup(ColumnGroup cg, int iCount) { Vector v = cg.v; for (int i = 0; i < v.size(); i++) { Object obj = v.elementAt(i); if (obj instanceof ColumnGroup) iCount = getColCountUnderColGroup((ColumnGroup) obj, iCount); else iCount++; } return iCount; }
public int getHeaderHeight() { int height = 0; TableColumnModel columnModel = header.getColumnModel(); for (int column = 0; column < columnModel.getColumnCount(); column++) { TableColumn aColumn = columnModel.getColumn(column); TableCellRenderer renderer = aColumn.getHeaderRenderer(); // if (renderer == null) { renderer = new DefaultTableCellRenderer() { public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JTableHeader header = table.getTableHeader(); if (header != null) { setForeground(header.getForeground()); setBackground(header.getBackground()); setFont(header.getFont()); } setHorizontalAlignment(JLabel.CENTER); setText((value == null) ? "" : value.toString()); setBorder(UIManager.getBorder("TableHeader.cellBorder")); return this; } }; } // Component comp = renderer.getTableCellRendererComponent(header .getTable(), aColumn.getHeaderValue(), false, false, -1, column); int cHeight = comp.getPreferredSize().height; Enumeration enumeration = ((GroupableTableHeader) header) .getColumnGroups(aColumn); if (enumeration != null) { while (enumeration.hasMoreElements()) { ColumnGroup cGroup = (ColumnGroup) enumeration .nextElement(); cHeight += cGroup.getSize(header.getTable()).height; } } height = Math.max(height, cHeight); } height = Math.max(height, m_height); return height; }
public Dimension getPreferredSize(JComponent c) { long width = 0; Enumeration enumeration = header.getColumnModel().getColumns(); while (enumeration.hasMoreElements()) { TableColumn aColumn = (TableColumn) enumeration.nextElement(); width = width + aColumn.getWidth(); }
return createHeaderSize(width); }
public void paint(Graphics g, JComponent c) { Rectangle clipBounds = g.getClipBounds(); if (header.getColumnModel() == null) return; ((GroupableTableHeader) header).setColumnMargin(); int column = 0; Dimension size = header.getSize(); Rectangle cellRect = new Rectangle(0, 0, size.width, size.height); Hashtable h = new Hashtable(); int columnMargin = header.getColumnModel().getColumnMargin(); Enumeration enumeration = header.getColumnModel().getColumns(); while (enumeration.hasMoreElements()) { cellRect.height = size.height; cellRect.y = 0; TableColumn aColumn = (TableColumn) enumeration.nextElement(); Enumeration cGroups = ((GroupableTableHeader) header) .getColumnGroups(aColumn); if (cGroups != null) { int groupHeight = 0; while (cGroups.hasMoreElements()) { ColumnGroup cGroup = (ColumnGroup) cGroups.nextElement(); Rectangle groupRect = (Rectangle) h.get(cGroup); if (groupRect == null) { groupRect = new Rectangle(cellRect); Dimension d = cGroup.getSize(header.getTable()); if (!System.getProperty("java.vm.version").startsWith( "1.2")) { int iColCount = getColCountUnderColGroup(cGroup, 0); // 获得该多表头下的基本列数(zjb) // System.out.println(iColCount); groupRect.width = d.width - iColCount * columnMargin; } else groupRect.width = d.width; groupRect.height = d.height; h.put(cGroup, groupRect); } paintCell(g, groupRect, cGroup); groupHeight += groupRect.height; cellRect.height = size.height - groupHeight; cellRect.y = groupHeight; } } if (!System.getProperty("java.vm.version").startsWith("1.2")) cellRect.width = aColumn.getWidth(); else cellRect.width = aColumn.getWidth() + columnMargin;
if (cellRect.intersects(clipBounds)) { paintCell(g, cellRect, column); } cellRect.x += cellRect.width; column++; } }
private void paintCell(Graphics g, Rectangle cellRect, int columnIndex) { TableColumn aColumn = header.getColumnModel().getColumn(columnIndex); TableCellRenderer renderer = aColumn.getHeaderRenderer(); // if (renderer == null) { renderer = new DefaultTableCellRenderer() { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JTableHeader header = table.getTableHeader(); if (header != null) { setForeground(header.getForeground()); setBackground(header.getBackground()); setFont(header.getFont()); } setHorizontalAlignment(JLabel.CENTER); setText((value == null) ? "" : value.toString()); setBorder(UIManager.getBorder("TableHeader.cellBorder")); return this; } }; } // // Component component = // renderer.getTableCellRendererComponent(header.getTable(), // aColumn.getHeaderValue(), false, false, -1, columnIndex); // String headerValue = aColumn.getHeaderValue().toString(); Component component = renderer.getTableCellRendererComponent(header .getTable(), headerValue, false, false, -1, columnIndex); rendererPane.add(component); rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); }
private void paintCell(Graphics g, Rectangle cellRect, ColumnGroup cGroup) { TableCellRenderer renderer = cGroup.getHeaderRenderer(); // if (renderer == null) { renderer = new DefaultTableCellRenderer() { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JTableHeader header = table.getTableHeader(); if (header != null) { setForeground(header.getForeground()); setBackground(header.getBackground()); setFont(header.getFont()); } setHorizontalAlignment(JLabel.CENTER); setText((value == null) ? "" : value.toString()); setBorder(UIManager.getBorder("TableHeader.cellBorder")); return this; } }; } // // Component component = // renderer.getTableCellRendererComponent(header.getTable(), // cGroup.getHeaderValue(), false, false, -1, -1); // String headerValue = cGroup.getHeaderValue().toString(); Component component = renderer.getTableCellRendererComponent(header .getTable(), headerValue, false, false, -1, -1);
rendererPane.add(component); rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); }
public void setHeaderHeight(int iHeight) { m_height = iHeight; } }
4、一个简单的测试用例 GroupableHeaderExample
import java.awt.Color; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent;
import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader;
import org.f5.ui.table.ColumnGroup; import org.f5.ui.table.GroupableTableHeader;
/** * @version 1.0 11/09/98 */ public class GroupableHeaderExample extends JFrame {
GroupableHeaderExample() { super("Groupable Header Example");
initialize(); } private void initialize() { DefaultTableModel dm = new DefaultTableModel(); dm.setDataVector(new Object[][] { { "119", "foo", "bar", "ja", "ko", "zh" }, { "911", "bar", "foo", "en", "fr", "pt" } }, new Object[] { "SNo.", "1", "2", "Native", "2", "3" }); JTable table = new JTable(dm) { protected JTableHeader createDefaultTableHeader() { return new GroupableTableHeader(columnModel); } }; GroupableTableHeader header = (GroupableTableHeader) table .getTableHeader(); javax.swing.table.TableColumnModel cm = table.getColumnModel(); // 接受类型 ColumnGroup g_jslx = new ColumnGroup( "接收类型"); g_jslx.add(cm.getColumn(1)); g_jslx.add(cm.getColumn(2)); header.addColumnGroup(g_jslx); JScrollPane scroll = new JScrollPane(table); getContentPane().add(scroll); setSize(400, 120); //设置列头背景为红色 header.setBackground(Color.RED); }
public static void main(String[] args) { GroupableHeaderExample frame = new GroupableHeaderExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } }
5、效果图 等我会贴图了再贴上来吧 |