How to write own CellEditor
that accepts list of non-String
objects, shows the JComboBox
dropdown with one filed of the Object, but when selected it adds another field of the Object to the JTable
model.
To write a custom cell editor that accepts a list of non-String
objects and shows a JComboBox
dropdown with one field of the object, but adds another field of the object to the JTable
model when selected, we create a class that extends AbstractCellEditor
and implements TableCellEditor
. Here's an example:
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;
}
}
In this example, the custom cell editor takes a list of non-String objects in the constructor and creates a JComboBox
with a custom renderer that displays one field of the object. The actionPerformed method of the JComboBox
is overridden to set the selectedObject
field and fire an editingStopped
event. The getCellEditorValue
method returns the fieldToAdd
of the selectedObject
. The getTableCellEditorComponent
method sets the selectedObject
to the value of the cell being edited and sets the selected item of the JComboBox
to the selectedObject
.
To use this custom cell editor, we create a JTable
and set the cell editor for a specific column:
JTable table = new JTable();
List<MyObject> objectList = new ArrayList<>();
// add objects to objectList
table.getColumnModel().getColumn(0).setCellEditor(new MyObjectCellEditor(objectList));
But how to make the list of Object
s for JComboBox
to be dynamically updated by the external events?
JComboBox has own model too!
This will use the MyObjectCellEditor
for the first column of the JTable
with the list of objects passed to the constructor. When an item is selected from the dropdown, the fieldToAdd of the selected object will be added to the JTable
model.
public void updateObjectList(List<Object> objectList) {
comboBox.setModel(new DefaultComboBoxModel<>(objectList.toArray()));
}
This method takes a new list of objects and sets it as the model for the JComboBox
. To use this method, you can call it whenever the list of objects needs to be updated. For example:
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);
In this example, a new MyObject
is added to the objectList and the updateObjectList method is called on the cell editor to update the JComboBox
with the new list of objects. When the JComboBox
is opened, it will show the new object in the dropdown list.