Code
class CheckComboBoxEditor implements ComboBoxEditor {
private final EditorPanel editor = new EditorPanel(new ComboItem());
@Override public void selectAll() {
editor.selectAll();
}
@Override public Object getItem() {
return editor.getItem();
}
@Override public void setItem(Object anObject) {
EventQueue.invokeLater(() -> {
Container c = SwingUtilities.getAncestorOfClass(
JComboBox.class, getEditorComponent());
if (c instanceof JComboBox) {
JComboBox combo = (JComboBox) c;
int idx = combo.getSelectedIndex();
if (idx >= 0 && idx != editor.getEditingIndex()) {
System.out.println("setItem: " + idx);
editor.setEditingIndex(idx);
}
}
});
if (anObject instanceof ComboItem) {
editor.setItem((ComboItem) anObject);
} else {
editor.setItem(new ComboItem());
}
}
@Override public Component getEditorComponent() {
return editor;
}
@Override public void addActionListener(ActionListener l) {
editor.addActionListener(l);
}
@Override public void removeActionListener(ActionListener l) {
editor.removeActionListener(l);
}
}
final class EditorPanel extends JPanel {
private final JCheckBox enabledCheck = new JCheckBox();
private final JCheckBox editableCheck = new JCheckBox();
private final JTextField textField = new JTextField("", 16);
private final transient ComboItem data;
private int editingIndex = -1;
protected EditorPanel(ComboItem data) {
super();
this.data = data;
setItem(data);
enabledCheck.addActionListener(e -> {
Container c = SwingUtilities.getAncestorOfClass(JComboBox.class, this);
if (c instanceof JComboBox) {
JComboBox combo = (JComboBox) c;
ComboItem item = (ComboItem) combo.getItemAt(editingIndex);
item.setEnabled(((JCheckBox) e.getSource()).isSelected());
editableCheck.setEnabled(item.isEnabled());
textField.setEnabled(item.isEnabled());
combo.setSelectedIndex(editingIndex);
}
});
enabledCheck.setOpaque(false);
enabledCheck.setFocusable(false);
editableCheck.addActionListener(e -> {
Container c = SwingUtilities.getAncestorOfClass(JComboBox.class, this);
if (c instanceof JComboBox) {
JComboBox combo = (JComboBox) c;
ComboItem item = (ComboItem) combo.getItemAt(editingIndex);
item.setEditable(((JCheckBox) e.getSource()).isSelected());
textField.setEditable(item.isEditable());
combo.setSelectedIndex(editingIndex);
}
});
editableCheck.setOpaque(false);
editableCheck.setFocusable(false);
textField.addActionListener(e -> {
Container c = SwingUtilities.getAncestorOfClass(JComboBox.class, this);
if (c instanceof JComboBox) {
JComboBox combo = (JComboBox) c;
ComboItem item = (ComboItem) combo.getItemAt(editingIndex);
item.setText(((JTextField) e.getSource()).getText());
combo.setSelectedIndex(editingIndex);
}
});
textField.setBorder(BorderFactory.createEmptyBorder());
textField.setOpaque(false);
setOpaque(false);
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
add(enabledCheck);
add(editableCheck);
add(textField);
}
public int getEditingIndex() {
return editingIndex;
}
public void setEditingIndex(int idx) {
this.editingIndex = idx;
}
public ComboItem getItem() {
data.setEnabled(enabledCheck.isSelected());
data.setEditable(editableCheck.isSelected());
data.setText(textField.getText());
return data;
}
public void setItem(ComboItem item) {
enabledCheck.setSelected(item.isEnabled());
editableCheck.setSelected(item.isEditable());
editableCheck.setEnabled(item.isEnabled());
textField.setText(item.getText());
textField.setEnabled(item.isEnabled());
textField.setEditable(item.isEditable());
}
public void selectAll() {
textField.requestFocusInWindow();
textField.selectAll();
}
public void addActionListener(ActionListener l) {
textField.addActionListener(l);
enabledCheck.addActionListener(l);
editableCheck.addActionListener(l);
}
public void removeActionListener(ActionListener l) {
textField.removeActionListener(l);
enabledCheck.removeActionListener(l);
editableCheck.removeActionListener(l);
}
}
References