JComboBoxのComboBoxEditorに編集可能なJCheckBoxを追加する
Total: 2599
, Today: 1
, Yesterday: 2
Posted by aterai at
Last-modified:
概要
JComboBox
を編集可能に設定し、ComboBoxEditor
として複数のJCheckBox
とJTextField
を配置したJPanel
を設定します。
Screenshot
Advertisement
サンプルコード
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);
}
}
View in GitHub: Java, Kotlin解説
setEditable(false), setRenderer(...)
- 編集不可の
JComboBox
にレンダラーとして複数のJCheckBox
とJTextField
を配置したJPanel
を使用 - 編集不可の
JComboBox
やドロップダウンリストの描画にのみ(このためイベントなどは無効)レンダラーとして設定したJPanel
が使用される
- 編集不可の
class CheckComboBoxRenderer<E extends ComboItem> implements ListCellRenderer<E> {
private static final Color SBGC = new Color(100, 200, 255);
private final EditorPanel renderer = new EditorPanel(new ComboItem());
@Override public Component getListCellRendererComponent(
JList<? extends E> list, E value, int index,
boolean isSelected, boolean cellHasFocus) {
renderer.setItem(value);
if (isSelected && index >= 0) {
renderer.setOpaque(true);
renderer.setBackground(SBGC);
} else {
renderer.setOpaque(false);
renderer.setBackground(Color.WHITE);
}
return renderer;
}
}
setEditable(true), setRenderer(...), setEditor(...)
- 編集可能な
JComboBox
にレンダラーとエディタとして複数のJCheckBox
とJTextField
を配置したJPanel
を使用 - 編集可能な
JComboBox
のエディタとして設定したJPanel
がそのまま使用されるためJCheckBox
などに設定したActionListener
なども有効- 左
JCheckBox
: 右JCheckBox
とJTextField
のsetEnabled(...)
を切り替える - 右
JCheckBox
:JTextField
のsetEditable(...)
を切り替える
- 左
- 編集可能な
参考リンク
- JComboBoxのEditorComponentにJButtonを配置
- JComboBoxのアイテムとして表示したJCheckBoxを複数選択する
- java - Using the ComboBoxEditor interface with Custom JComponent, and allow edit, and display the List - Stack Overflow