by cszhao1980
JTable将Cell的绘制工作委托给CellRenderer来完成——如果我们没有显示的设置CellRenderer,JTable会使用默认的CellRenderer(默认CellRenderer也有多种,会根据ColumnClass的不同而选取)
所有的CellRenderer必须实现TableCellRenderer接口,该接口只有一个方法:
Component |
getTableCellRendererComponent(JTable table,Object value, boolean isSelected, boolean hasFocus, int row, int column) 返回用于绘制单元格的组件。 |
Swing给出了一个标准的接口实现——defaultTableCellRenderer,该实现继承自JLabel,可以通过JLabel的方法对其进行控制,如前景色、背景色、等等。除此之外,它还定义了一个钩子方法:
protected void |
setValue(Object value) |
defaultTableCellRenderer会在返回绘制组件时,调用此方法格式化Value,我们可以通过继承defaultTableCellRenderer,修改该方法,以达到格式化Valued的方法,如:
class TableCellCurrencyRenderer extends DefaultTableCellRenderer { public void setValue(Object value) { Format format = NumberFormat.getCurrencyInstance(); super.setValue(value == null ? "" : format.format(value)); } } |
通过这个简单的扩展,我们就将浮点数格式化成了Currency格式。
一般来说,如果我们需要JLabel作为CellRenderer,我们就可以直接使用、或扩展defaultTableCellRenderer;否则我们就自行实现TableCellRenderer接口。
与JTable、TableColumn的关系:
倾向使用“列”控制CellRenderer,TableColumn中有相应的get、set方法:
TableCellRenderer |
getCellRenderer() |
void |
setCellRenderer(TableCellRenderer cellRenderer) |
而JTable中,仅有get方法:
public TableCellRenderer getCellRenderer(int row,int column) 返回适于由此行和列所指定单元格的渲染器。如果此列的 |
此接口定义任何通用编辑器应该能够实现的方法。子接口: TableCellEditor,TreeCellEditor。
让此接口启用复杂组件(编辑器的客户端),比如 JTree
和 JTable
,从而允许任何一般编辑器编辑表单元格值、树单元格值等等。如果没有此一般编辑器接口,则JTable
不得不了解特定编辑器,比如 JTextField
、JCheckBox
、JComboBox
等等。此外,如果没有此接口,则编辑器(如JTable
)的客户端无法使用用户或第三方 ISV 将来开发的其他任何编辑器。
void |
addCellEditorListener(CellEditorListener l) |
void |
removeCellEditorListener(CellEditorListener l) |
void |
cancelCellEditing() 显然,该方法应该通知相关的监听器。 |
boolean |
stopCellEditing() 显然,该方法应该通知相关的监听器。 |
Object |
getCellEditorValue() |
boolean |
isCellEditable(EventObject anEvent) |
boolean |
shouldSelectCell(EventObject anEvent) (返回true时,编辑该cell时,该cell即刻被选中) |
TableCellEditor扩展了CellEditor接口,提供了如下方法:
Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) 为编辑器设置初始 返回应该添加到客户端 参数:
返回: 要编辑的组件 |
在进行Cell Edit操作之前,TableCell使用CellRenderer进行显示(CellRenderer类似橡皮图章,直接在其上绘制)。但一旦进入Edit状态,会将CellEditor组件插入到Cell中。
这是个复杂的过程,如下图所示:
一旦安装好Editor组件,就可以在其上进行edit,其设置值的过程如下图所示:
其基本过程均是监听鼠标事件,然后再确定安装、取消CellEditor,或修改编辑值。
一般情况下,会使用CellRenderer的一个副本来作CellEditor组件。
因为,JTable会通过CellEditor接口真正修改其model内的值,所以不能使用CellRenderer本身作为其CellEditor,否则,将无法实现CancelCellEditing的功能。
Swing提供了TableCellEditor接口的一个实现,即DefaultCellEditor(它同时还实现了TreeCellEditor接口)。它有三个构造函数:
DefaultCellEditor(JCheckBox checkBox) |
DefaultCellEditor(JComboBox comboBox) |
DefaultCellEditor(JTextField textField) |
显然,使用不同的构造函数可以提供不同的组件作为CellEditor component。
除了CellEditor接口的各种方法外,还提供了若干方法:
int |
getClickCountToStart() |
void |
setClickCountToStart(int count) |
可以通过这对方法设置进入Edit状态的门槛(默认为单击)。
【内部实现】:DefaultCellEditor在实现isCellEditable(EventObject anEvent)方法时,会检查鼠标单、双、三击状态,如不满足门槛要求,会返回False,阻止进入Edit状态。