在coding.mof的回复之后,我终于做到了我想要的。但是,我想为这个问题提供一个更完整的答案,所以我会自己提供一个。
因此,Cell Renderers 只是简单地绘制组件,不允许在其中进行任何交互。而单元格编辑器则可以。
最初,JTable 中的所有单元格都是由注册的渲染器返回的组件。However, when a cell is selected, this component is replaced by a component that is returned by the editor. 这两个实际上可以是不同的组件!我很确定您可以利用这一点并制作一些时髦的细胞:P
无论如何,在本例中,渲染器和编辑器都显示相同的组件,因此我们将创建一个供双方使用的组件。
首先,我们需要创建一个返回 ADT 的 TableModel:
class MyClassTableModel extends DefaultTableModel {
List<MyClass> data;
public MyClassTableModel(List<MyClass> data) {
this.data = data;
}
public Class<?> getColumnClass(int columnIndex) { return MyClass.class; }
public int getColumnCount() { return 1; }
public String getColumnName(int columnIndex) { return "MyClass"; }
public int getRowCount() { return (data == null) ? 0 : data.size(); }
public Object getValueAt(int rowIndex, int columnIndex) { return data.get(rowIndex); }
public boolean isCellEditable(int rowIndex, int columnIndex) { return true; }
}
现在,我们创建一个将在渲染器和编辑器之间共享的组件:
class MyClassCellComponent extends JPanel() {
MyClass myClass;
public MyClassCellComponent() {
// initialize components (labels, buttons, etc.)
// add action listeners
}
public void updateData(MyClass myClass, boolean isSelected, JTable table) {
this.myClass = myClass;
// update buttons, labels etc. accordingly
}
}
isSelected 和 table 参数用于渲染面板的背景,是可选的。下面是渲染器如何使用我们的组件:
class MyClassCellRenderer implements TableCellRenderer {
MyClassCellComponent panel;
public MyClassCellRenderer() {
panel = new MyClassCellComponent();
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
MyClass myClass = (MyClass)value;
panel.updateData(myClass, isSelected, table);
return panel;
}
}
以下是编辑器的使用方式:
class MyClassCellEditor extends AbstractCellEditor {
MyClassCellComponent panel;
public MyClassCellEditor() {
panel = new MyClassCellComponent();
}
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
MyClass myClass = (MyClass)value;
panel.updateData(myClass, true, table);
return panel;
}
public Object getCellEditorValue() {
return null;
}
}
就这样。现在我们可以简单地创建一个 JTable,如下所示:
JTable myClassTable = new JTable(new MyClassTableModel());
myClassTable.setDefaultRenderer(MyClass.class, new MyClassCellRenderer());
myClassTable.setDefaultEditor(MyClass.class, new MyClassCellEditor());
我们完成了!
PS 我很确定我们可以将渲染器和编辑器组合成一个类,扩展 AbstractCellEditor 并实现 TableCellRenderer,但我不确定性能。