Swing/TreeComboBox のバックアップソース(No.10)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- バックアップ を表示
- Swing/TreeComboBox へ行く。
- 1 (2011-07-12 (火) 19:35:10)
- 2 (2011-07-13 (水) 19:02:23)
- 3 (2012-12-19 (水) 22:13:50)
- 4 (2013-08-17 (土) 00:55:42)
- 5 (2015-01-09 (金) 14:16:08)
- 6 (2015-03-19 (木) 16:33:15)
- 7 (2016-05-27 (金) 15:32:36)
- 8 (2017-08-29 (火) 16:10:07)
- 9 (2018-02-22 (木) 19:13:58)
- 10 (2020-02-13 (木) 15:13:08)
- 11 (2021-07-30 (金) 04:22:23)
- 12 (2024-02-10 (土) 17:44:41)
--- category: swing folder: TreeComboBox title: JComboBoxのItemをTree状に表示する tags: [JComboBox, TreeModel] author: aterai pubdate: 2011-07-11T15:16:42+09:00 description: JComboBoxのドロップダウンリストに表示するItemをTree状に配置します。 image: https://lh6.googleusercontent.com/-5GlQEjeLoH8/ThqUIL9b4UI/AAAAAAAAA_E/9h5dxYzSSm8/s800/TreeComboBox.png --- * 概要 [#summary] `JComboBox`のドロップダウンリストに表示する`Item`を`Tree`状に配置します。 #download(https://lh6.googleusercontent.com/-5GlQEjeLoH8/ThqUIL9b4UI/AAAAAAAAA_E/9h5dxYzSSm8/s800/TreeComboBox.png) * サンプルコード [#sourcecode] #code(link){{ class TreeComboBox<E extends TreeNode> extends JComboBox<E> { private boolean isNotSelectableIndex; private final Action up = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { int si = getSelectedIndex(); for (int i = si - 1; i >= 0; i--) { if (getItemAt(i).isLeaf()) { setSelectedIndex(i); break; } } } }; private final Action down = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { int si = getSelectedIndex(); for (int i = si + 1; i < getModel().getSize(); i++) { if (getItemAt(i).isLeaf()) { setSelectedIndex(i); break; } } } }; @Override public void updateUI() { super.updateUI(); ListCellRenderer<? super E> renderer = getRenderer(); setRenderer(new ListCellRenderer<E>() { @Override public Component getListCellRendererComponent( JList<? extends E> list, E value, int index, boolean isSelected, boolean cellHasFocus) { JLabel l = (JLabel) renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus); l.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); if (index >= 0 && value instanceof DefaultMutableTreeNode) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; int indent = Math.max(0, node.getLevel() - 1) * 16; l.setBorder(BorderFactory.createEmptyBorder(1, indent + 1, 1, 1)); if (!value.isLeaf()) { l.setForeground(Color.WHITE); l.setBackground(Color.GRAY.darker()); } } return l; } }); EventQueue.invokeLater(() -> { ActionMap am = getActionMap(); am.put("selectPrevious3", up); am.put("selectNext3", down); InputMap im = getInputMap(); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "selectPrevious3"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_KP_UP, 0), "selectPrevious3"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "selectNext3"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_KP_DOWN, 0), "selectNext3"); }); } @Override public void setPopupVisible(boolean v) { if (!v && isNotSelectableIndex) { isNotSelectableIndex = false; } else { super.setPopupVisible(v); } } @Override public void setSelectedIndex(int index) { TreeNode node = getItemAt(index); if (Objects.nonNull(node) && node.isLeaf()) { super.setSelectedIndex(index); } else { isNotSelectableIndex = true; } } } }} * 解説 [#explanation] 上記のサンプルでは、`TreeModel`から取得した`TreeNode`を`JComboBox`の`Item`として、ドロップダウンリストに表示しています。 - `TreeNode#isLeaf()`の場合だけ、選択可能 -- [[JComboBoxのアイテムを選択不可にする>Swing/DisableItemComboBox]] - 第`0`レベルのルートノードは非表示で、第`1`レベルノードのインデントは`0`に設定 - 第`2`レベル以降の子ノードのインデントは`BorderFactory.createEmptyBorder(1, indent + 1, 1, 1)`で設定 * 参考リンク [#reference] - [http://www.jroller.com/santhosh/entry/tree_inside_jcombobox Tree inside JComboBox - Santhosh Kumar's Weblog] -- `TreeCellRenderer`を使用し、ノードアイコンなども含めて`JTree`をドロップダウンリストに表示するサンプルがある - [[JComboBoxのアイテムを選択不可にする>Swing/DisableItemComboBox]] * コメント [#comment] #comment - `src.zip`などが正しいディレクトリに配置されてなかったのを修正。 -- &user(aterai); &new{2011-07-13 (水) 19:02:23}; #comment