1.什么是Row Header? 先来了解什么是Column Header. 打开Excel, 位于表格列上方,标有A,B,C,D...的地方就叫Column Header. 那Row Header就是左方标有行号的地方了.
2.为什么要为JTable加Row Header? Swing中的JTable提供了强大的表格处理能力, 但只提供了Column Header功能,却没有直接提供加Row Header功能.
3.如何实现? 要想为JTable加上Row Header或Column Header, 要先将JTable放入一个JScrollPane. 我们先来看看JScrollPane的结构:
 如图所示,JScrollPane有9个部分组成,我们可以用JScrollPane的以下这些方法,为这9个区域加上不同的组件: setColumnHeaderView(Component view) setCorner(String key, Component corner) setHorizontalScrollBar(JScrollBar horizontalScrollBar) setRowHeaderView(Component view) setVerticalScrollBar(JScrollBar verticalScrollBar) setViewportView(Component view) 其中有些方法的参数是Component,而几乎所有的swing组件都是由Component继承而来的,也就是说,我们可以为这些区域加上任意的swing组件. 再看如下代码: public class ScrollableTable extends JFrame { public ScrollableTable() { JScrollPane scrollPane = new JScrollPane(new JTable(10,10)); this.getContentPane().add(scrollPane); } } 这个类将一个10*10单元格大小的Table加入了JScrollPane中,即图中的JViewPort的位置放置JTable,并且自动会为JTable加上Column Header,这个是Swing为我们自动完成的,我们只告诉它JTable加入了JScrollPane,ColumnHeader是它自动加上的.
要想为JTable加上row header实际上是为JScrollPane的Row Header区域加上一个类似于row header的东东.那什么组件最适于充当row header呢? 还是JTable! 对.我们再放一个JTable在JScrollPane的Row Header区域,让其行数与JViewPort中的JTable一样,并显示每一行的行号.如下: DefaultTableModel model = new DefaultTableModel(50,10); DefaultTableModel rowheadmodel = new DefaultTableModel(50,10); JTable table = new JTable(model); JTable rowHeaderTable = new JTable(rowheadmodel); rowheadmodel.setColumnCount(1); rowheadmodel.setColumnIdentifiers(new Object[]{""}); rowHeaderTable.setEnabled(false); rowHeaderTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); rowHeaderTable.getColumnModel().getColumn(0).setPreferredWidth(50); /*为rowHeaderTable设置预设的绘制器*/ rowHeaderTable.setDefaultRenderer(rowHeaderTable.getColumnClass(0),new RowHeaderRenderer(table)); rowHeaderTable.setPreferredScrollableViewportSize ( new Dimension ( rowHeaderTable.getColumnModel().getColumn(0).getPreferredWidth() ,0 ) ); /*将table加入JScrollPane*/ JScrollPane scrollPane = new JScrollPane(table); /*将rowHeaderTable作为row header加入JScrollPane的RowHeaderView区域*/ scrollPane.setRowHeaderView(rowHeaderTable); this.getContentPane().add(scrollPane); 大家发现没有,在代码中有一个RowHeaderRenderer类(标为蓝色字体的),这个类是做什么的呢? 为了实现在table中新增、删除行时,rowHeaderTable的行数与行号一起变化,也为了Row Header看起来更像Header,我们实现了一个TableCellRenderer,用JLabel作为单元格的绘制器,并用: public class RowHeaderRenderer extends JLabel implements TableCellRenderer { JTable reftable;
public RowHeaderRenderer(JTable reftable) { this.reftable = reftable; }
public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int col) { ((DefaultTableModel)table.getModel()).setRowCount(reftable.getRowCount()); JTableHeader header = reftable.getTableHeader(); this.setOpaque(true); /*设为TableHeader的边框类型*/ setBorder(UIManager.getBorder("TableHeader.cellBorder")); setHorizontalAlignment(CENTER); /*设置背景色为TableHeader的背景色*/ setBackground(header.getBackground()); Font font = header.getFont(); if ( isSelect(row) ) /* 当选取单元格时,在row header上设置成选取颜色 */ { setForeground(Color.white); setBackground(Color.lightGray); setFont(font); setText(String.valueOf(row+1)); } else { setForeground(header.getForeground()); setFont(font); setText(String.valueOf(row+1)); } return this; } private boolean isSelect(int row) { int[] sel = reftable.getSelectedRows(); for ( int i=0; i<sel.length; i++ ) { if (sel[i] == row ) return true; } return false; } }

|