Swing/CheckableComboBoxEditor のバックアップソース(No.1)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- バックアップ を表示
- Swing/CheckableComboBoxEditor へ行く。
- 1 (2018-11-05 (月) 16:29:27)
- 2 (2018-11-06 (火) 19:12:29)
- 3 (2018-11-29 (木) 16:39:31)
- 4 (2020-11-08 (日) 02:00:41)
- 5 (2022-10-22 (土) 22:49:45)
--- category: swing folder: CheckableComboBoxEditor title: JComboBoxのComboBoxEditorに編集可能なJCheckBoxを追加する tags: [JComboBox, ComboBoxEditor, JCheckBox] author: aterai pubdate: 2018-11-05T16:25:10+09:00 description: JComboBoxを編集可能に設定し、ComboBoxEditorとして複数のJCheckBoxとJTextFieldを配置したJPanelを設定します。 image: https://drive.google.com/uc?id=1f3vhPqkXg-Jg6AK0p01Pn7aGRTo-Wlv0pw --- * 概要 [#summary] `JComboBox`を編集可能に設定し、`ComboBoxEditor`として複数の`JCheckBox`と`JTextField`を配置した`JPanel`を設定します。 #download(https://drive.google.com/uc?id=1f3vhPqkXg-Jg6AK0p01Pn7aGRTo-Wlv0pw) * サンプルコード [#sourcecode] #code(link){{ 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) { 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) { System.out.println("addActionListener: " + l.getClass().getName()); editor.addActionListener(l); } @Override public void removeActionListener(ActionListener l) { System.out.println("removeActionListener: " + l.getClass().getName()); 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 ComboItem data; 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(data.getIndex()); item.setEnabled(((JCheckBox) e.getSource()).isSelected()); editableCheck.setEnabled(item.isEnabled()); textField.setEnabled(item.isEnabled()); } }); 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(data.getIndex()); item.setEditable(((JCheckBox) e.getSource()).isSelected()); textField.setEditable(item.isEditable()); } }); 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(data.getIndex()); item.setText(((JTextField) e.getSource()).getText()); } }); textField.setBorder(BorderFactory.createEmptyBorder()); textField.setOpaque(false); setOpaque(false); setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS)); add(enabledCheck); add(editableCheck); add(textField); } public ComboItem getItem() { // data.index(this.data.index); data.setEnabled(enabledCheck.isSelected()); data.setEditable(editableCheck.isSelected()); data.setText(textField.getText()); return data; } public void setItem(ComboItem item) { data.setIndex(item.getIndex()); 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); } } }} * 解説 [#explanation] - `setEditable(false), setRenderer(...)` -- 編集不可の`JComboBox`にレンダラーとして複数の`JCheckBox`と`JTextField`を配置した`JPanel`を使用 -- 編集不可の`JComboBox`やドロップダウンリストの描画にのみ(このためイベントなどは無効)レンダラーとして設定した`JPanel`が使用される #code{{ 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`なども有効 --- 左`JCeckBox`: 右`JCeckBox`と`JTextField`の`setEnabled(...)`を切り替える --- 右`JCeckBox`: `JTextField`の`setEditable(...)`を切り替える * 参考リンク [#reference] - [[JComboBoxのEditorComponentにJButtonを配置>Swing/ButtonInComboEditor]] - [[JComboBoxのアイテムとして表示したJCheckBoxを複数選択するSwing/CheckedComboBox]] - [https://stackoverflow.com/questions/53037906/using-the-comboboxeditor-interface-with-custom-jcomponent-and-allow-edit-and-d java - Using the ComboBoxEditor interface with Custom JComponent, and allow edit, and display the List - Stack Overflow] * コメント [#comment] #comment #comment