如何编写自己的
CellEditor
来接受非 String
对象列表,显示带有对象的一个字段的 JComboBox
下拉列表,但选择后,会将对象的另一个字段添加到 JTable
模型中。
要编写一个自定义单元格编辑器,它接受非
String
对象的列表,并显示带有对象的一个字段的 JComboBox
下拉列表,但在选择时将对象的另一个字段添加到 JTable
模型中,我们创建扩展 AbstractCellEditor
并实现 TableCellEditor
的类。这是一个例子:
public class MyObjectCellEditor extends AbstractCellEditor implements TableCellEditor {
private JComboBox<Object> comboBox;
private Object selectedObject;
public MyObjectCellEditor(List<Object> objectList) {
comboBox = new JComboBox<>(objectList.toArray());
comboBox.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
setText(((MyObject)value).getFieldToShow());
return this;
}
});
comboBox.addActionListener(e -> {
selectedObject = comboBox.getSelectedItem();
fireEditingStopped();
});
}
@Override
public Object getCellEditorValue() {
return selectedObject.getFieldToAdd();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
selectedObject = (MyObject)value;
comboBox.setSelectedItem(selectedObject);
return comboBox;
}
}
在此示例中,自定义单元格编辑器在构造函数中获取一系列非 String 对象,并使用显示该对象的一个字段的自定义渲染器创建一个
JComboBox
。 JComboBox
的 actionPerformed 方法被重写以设置 selectedObject
字段并触发 editingStopped
事件。 getCellEditorValue
方法返回 fieldToAdd
的 selectedObject
。 getTableCellEditorComponent
方法将selectedObject
设置为正在编辑的单元格的值,并将JComboBox
的所选项目设置为selectedObject
。
要使用此自定义单元格编辑器,我们创建一个
JTable
并为特定列设置单元格编辑器:
JTable table = new JTable();
List<MyObject> objectList = new ArrayList<>();
// add objects to objectList
table.getColumnModel().getColumn(0).setCellEditor(new MyObjectCellEditor(objectList));
但是如何让
Object
的JComboBox
列表能够根据外部事件动态更新呢?
JComboBox 也有自己的模型!
这将使用
MyObjectCellEditor
作为 JTable
的第一列,并将对象列表传递给构造函数。当从下拉列表中选择一个项目时,所选对象的 fieldToAdd 将被添加到 JTable
模型中。
public void updateObjectList(List<Object> objectList) {
comboBox.setModel(new DefaultComboBoxModel<>(objectList.toArray()));
}
此方法采用新的对象列表并将其设置为
JComboBox
的模型。要使用此方法,您可以在需要更新对象列表时调用它。例如:
MyObjectCellEditor cellEditor = new MyObjectCellEditor(objectList);
table.getColumnModel().getColumn(0).setCellEditor(cellEditor);
// update the objectList and the cell editor
objectList.add(new MyObject("new object", "new value"));
cellEditor.updateObjectList(objectList);
在此示例中,新的
MyObject
添加到 objectList 中,并在单元格编辑器上调用 updateObjectList 方法,以使用新的对象列表更新 JComboBox
。当JComboBox
打开时,它将在下拉列表中显示新对象。