Swing/CheckedComboBox のバックアップソース(No.7)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- バックアップ を表示
- Swing/CheckedComboBox へ行く。
- 1 (2016-06-08 (水) 13:05:32)
- 2 (2016-07-26 (火) 15:25:46)
- 3 (2016-08-15 (月) 15:29:45)
- 4 (2017-06-09 (金) 14:03:45)
- 5 (2017-06-12 (月) 17:20:29)
- 6 (2017-11-14 (火) 15:45:15)
- 7 (2018-01-17 (水) 19:29:17)
- 8 (2018-02-24 (土) 19:51:30)
- 9 (2020-01-08 (水) 20:44:22)
- 10 (2021-07-06 (火) 18:56:18)
- 11 (2021-07-10 (土) 03:25:51)
- 12 (2021-10-30 (土) 19:24:02)
- 13 (2023-05-21 (日) 13:39:57)
--- category: swing folder: CheckedComboBox title: JComboBoxのアイテムとして表示したJCheckBoxを複数選択する tags: [JComboBox, JCheckBox] author: aterai pubdate: 2016-05-23T00:06:37+09:00 description: JComboBoxのアイテムとしてJCheckBoxを表示し、ドロップダウンリストを開いたままこれを複数選択可能に設定します。 image: https://lh3.googleusercontent.com/-I-fHfvCX-IU/V0G4uliNHdI/AAAAAAAAOX0/-746I_MG_jQkqTu1cniGzJqqu3xbc1khACCo/s800/CheckedComboBox.png hreflang: href: http://java-swing-tips.blogspot.com/2016/07/select-multiple-jcheckbox-in-jcombobox.html lang: en --- * 概要 [#summary] `JComboBox`のアイテムとして`JCheckBox`を表示し、ドロップダウンリストを開いたままこれを複数選択可能に設定します。 #download(https://lh3.googleusercontent.com/-I-fHfvCX-IU/V0G4uliNHdI/AAAAAAAAOX0/-746I_MG_jQkqTu1cniGzJqqu3xbc1khACCo/s800/CheckedComboBox.png) * サンプルコード [#sourcecode] #code(link){{ class CheckedComboBox<E extends CheckableItem> extends JComboBox<E> { private boolean keepOpen; private transient ActionListener listener; protected CheckedComboBox() { super(); } protected CheckedComboBox(ComboBoxModel<E> aModel) { super(aModel); } protected CheckedComboBox(E[] m) { super(m); } @Override public Dimension getPreferredSize() { return new Dimension(200, 20); } @Override public void updateUI() { setRenderer(null); removeActionListener(listener); super.updateUI(); listener = e -> { if ((e.getModifiers() & InputEvent.MOUSE_EVENT_MASK) != 0) { updateItem(getSelectedIndex()); keepOpen = true; } }; setRenderer(new CheckBoxCellRenderer<CheckableItem>()); addActionListener(listener); getInputMap(JComponent.WHEN_FOCUSED).put( KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "checkbox-select"); getActionMap().put("checkbox-select", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { Accessible a = getAccessibleContext().getAccessibleChild(0); if (a instanceof BasicComboPopup) { BasicComboPopup pop = (BasicComboPopup) a; updateItem(pop.getList().getSelectedIndex()); } } }); } private void updateItem(int index) { if (isPopupVisible()) { E item = getItemAt(index); item.selected ^= true; setSelectedIndex(-1); setSelectedItem(item); } } @Override public void setPopupVisible(boolean v) { if (keepOpen) { keepOpen = false; } else { super.setPopupVisible(v); } } } }} * 解説 [#explanation] - タイトルと選択状態をもつアイテムオブジェクト`CheckableItem`を作成し、そのモデルとして`ComboBoxModel<CheckableItem>`を作成 - `CheckBoxCellRenderer<E extends CheckableItem>`を作成し、チェック状態を表示 -- `JComboBox`本体: レンダラーに`JLabel`を使用し、選択されている`CheckableItem`のタイトルを収集してカンマで結合して一覧表示 -- ドロップダウンリスト: レンダラーに`JCheckBox`を使用し、チェック状態とタイトルを表示 - `JComboBox`に`ActionListener`を追加し、マウスの左クリックかつドロップダウンリストが表示されている場合は、選択されたアイテムのチェック状態を反転 -- この場合は、ドロップダウンリストを閉じないように、`JComboBox#setPopupVisible(...)`をオーバーライド - KBD{Space}キーでアイテムが選択された場合は、`BasicComboPopup`から`JList`を取得し、その選択アイテムを取得する -- この場合、`JComboBox#getSelectedIndex()`などを使用すると、ハイライト(`cellHasFocus`)されているアイテムではなく、選択状態(`isSelected`)のアイテムが取得される * 参考リンク [#reference] - [[JComboBoxのドロップダウンリスト中にあるアイテムの状態を更新する>Swing/UpdateComboBoxItem]] * コメント [#comment] #comment #comment