Swing/RemoveButtonInComboItem のバックアップの現在との差分(No.1)
- バックアップ一覧
- 差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Swing/RemoveButtonInComboItem へ行く。
- 1 (2012-07-09 (月) 12:02:11)
- 2 (2012-12-08 (土) 06:57:28)
- 3 (2014-09-21 (日) 01:11:16)
- 4 (2014-10-18 (土) 12:25:58)
- 5 (2014-11-23 (日) 17:03:06)
- 6 (2015-02-14 (土) 10:13:00)
- 7 (2015-05-12 (火) 14:34:55)
- 8 (2015-05-12 (火) 15:46:41)
- 9 (2015-05-13 (水) 17:59:10)
- 10 (2016-09-30 (金) 15:44:33)
- 11 (2017-10-29 (日) 13:53:00)
- 12 (2018-02-24 (土) 19:51:30)
- 13 (2019-04-10 (水) 13:58:27)
- 14 (2019-06-05 (水) 15:48:56)
- 15 (2021-02-20 (土) 09:53:08)
- 追加された行はこの色です。
- 削除された行はこの色です。
TITLE:JComboBoxのドロップダウンリストにJButtonを追加 #navi(../) RIGHT:Posted by [[aterai]] at 2012-07-09 *JComboBoxのドロップダウンリストにJButtonを追加 [#w66d2f92] JButtonのドロップダウンリストで、各アイテムにクリック可能なJButtonを追加しこれを削除します。 --- category: swing folder: RemoveButtonInComboItem title: JComboBoxのドロップダウンリストに追加したJButtonで項目を削除する tags: [JComboBox, JButton, JList, BasicComboPopup, ListCellRenderer, MouseListener] author: aterai pubdate: 2012-07-09T12:02:11+09:00 description: JButtonのドロップダウンリストで、各アイテムにクリック可能なJButtonを追加しこれを削除します。 image: https://lh6.googleusercontent.com/-x9uTOO9fSds/T_pElwy8GBI/AAAAAAAABPM/Jx30phjG3bM/s800/RemoveButtonInComboItem.png hreflang: href: https://java-swing-tips.blogspot.com/2012/10/delete-button-in-jcombobox-popup-menu.html lang: en --- * 概要 [#summary] `JButton`のドロップダウンリストで、各アイテムにクリック可能な`JButton`を追加しこれを削除します。 -&jnlp; -&jar; -&zip; #download(https://lh6.googleusercontent.com/-x9uTOO9fSds/T_pElwy8GBI/AAAAAAAABPM/Jx30phjG3bM/s800/RemoveButtonInComboItem.png) //#screenshot #ref(https://lh6.googleusercontent.com/-x9uTOO9fSds/T_pElwy8GBI/AAAAAAAABPM/Jx30phjG3bM/s800/RemoveButtonInComboItem.png) **サンプルコード [#o70b5054] #code{{ class CellButtonsMouseListener extends MouseAdapter{ private int prevIndex = -1; private JButton prevButton = null; * サンプルコード [#sourcecode] #code(link){{ class CellButtonsMouseListener extends MouseAdapter { @Override public void mouseMoved(MouseEvent e) { JList list = (JList)e.getComponent(); JList<?> list = (JList<?>) e.getComponent(); Point pt = e.getPoint(); int index = list.locationToIndex(pt); if(!list.getCellBounds(index, index).contains(pt)) { if(prevIndex>=0) { Rectangle r = list.getCellBounds(prevIndex, prevIndex); if(r!=null) { list.repaint(r); } } index = -1; prevButton = null; return; } if(index>=0) { JButton button = getButton(list, pt, index); ButtonsRenderer renderer = (ButtonsRenderer)list.getCellRenderer(); renderer.button = button; if(button != null) { button.getModel().setRollover(true); renderer.rolloverIndex = index; if(!button.equals(prevButton)) { Rectangle r = list.getCellBounds(prevIndex, index); if(r!=null) { list.repaint(r); } } }else{ renderer.rolloverIndex = -1; Rectangle r = null; if(prevIndex != index) { r = list.getCellBounds(index, index); }else if(prevIndex>=0 && prevButton!=null) { r = list.getCellBounds(prevIndex, prevIndex); } if(r!=null) { list.repaint(r); } prevIndex = -1; } prevButton = button; } prevIndex = index; int index = list.locationToIndex(pt); ButtonsRenderer<?> renderer = (ButtonsRenderer<?>) list.getCellRenderer(); renderer.rolloverIndex = Objects.nonNull(getButton(list, pt, index)) ? index : -1; list.repaint(); } @Override public void mousePressed(MouseEvent e) { JList list = (JList)e.getComponent(); Point pt = e.getPoint(); int index = list.locationToIndex(pt); if(index>=0) { JButton button = getButton(list, pt, index); if(button != null) { ButtonsRenderer renderer = (ButtonsRenderer)list.getCellRenderer(); renderer.button = button; list.repaint(list.getCellBounds(index, index)); } } e.getComponent().repaint(); } @Override public void mouseReleased(MouseEvent e) { JList list = (JList)e.getComponent(); JList<?> list = (JList<?>) e.getComponent(); Point pt = e.getPoint(); int index = list.locationToIndex(pt); if(index>=0) { int index = list.locationToIndex(pt); if (index >= 0) { JButton button = getButton(list, pt, index); if(button != null) { ButtonsRenderer renderer = (ButtonsRenderer)list.getCellRenderer(); renderer.button = null; if (Objects.nonNull(button)) { button.doClick(); Rectangle r = list.getCellBounds(index, index); if(r!=null) { list.repaint(r); } } } ((ButtonsRenderer<?>) list.getCellRenderer()).rolloverIndex = -1; list.repaint(); } @SuppressWarnings("unchecked") private static JButton getButton(JList list, Point pt, int index) { Container c = (Container)list.getCellRenderer().getListCellRendererComponent( list, "", index, false, false); @Override public void mouseExited(MouseEvent e) { JList<?> list = (JList<?>) e.getComponent(); ((ButtonsRenderer<?>) list.getCellRenderer()).rolloverIndex = -1; } private static <E> JButton getButton(JList<E> list, Point pt, int index) { E proto = list.getPrototypeCellValue(); Component c = list.getCellRenderer().getListCellRendererComponent( list, proto, index, false, false); Rectangle r = list.getCellBounds(index, index); c.setBounds(r); pt.translate(0,-r.y); Component b = SwingUtilities.getDeepestComponentAt(c, pt.x, pt.y); if(b instanceof JButton) { return (JButton)b; }else{ return null; } // c.doLayout(); // may be needed for other layout managers (eg. FlowLayout) pt.translate(-r.x, -r.y); return Optional.ofNullable(SwingUtilities.getDeepestComponentAt(c, pt.x, pt.y)) .filter(JButton.class::isInstance).map(JButton.class::cast).orElse(null); } } }} **解説 [#sc8b8fec] JComboBoxのドロップダウンリスト(BasicComboPopup)からJListを取得し、これに上記のようなMouseListenerを追加しています。このJListがクリックされた場合、レンダラーから対応するセルに表示されているJButtonを取得し、button.doClick()を呼び出します。 * 解説 [#explanation] `JComboBox`のドロップダウンリスト(`ComboPopup`)から`JList`を取得し、これに上記のような`MouseListener`を追加しています。 - `JList`がクリックされた場合、レンダラーから対応するセルに表示されている`JButton`を取得して`JButton#doClick()`メソッドを実行 #code{{ Accessible a = getAccessibleContext().getAccessibleChild(0); if(a instanceof BasicComboPopup) { BasicComboPopup pop = (BasicComboPopup)a; if (a instanceof ComboPopup) { ComboPopup pop = (ComboPopup) a; JList list = pop.getList(); CellButtonsMouseListener cbml = new CellButtonsMouseListener(); list.addMouseListener(cbml); list.addMouseMotionListener(cbml); } }} ---- - メモ: 削除ボタンがクリックされてもドロップダウンリストは表示されたままになるように、MutableComboBoxModel#removeElementAt(index);のあとでcomboBox.showPopup(); -- BasicComboPopup が、フレーム外に表示されている場合(Heavy weight)、一旦閉じたあとで再度開かれるように見える - 削除ボタンがクリックされてもドロップダウンリスト(`ComboPopup`)は表示状態のまま残したい -- `MutableComboBoxModel#removeElementAt(index)`のあとで`JComboBox#showPopup()`を実行して開き直す -- `ComboPopup`が`JFrame`の外に表示されている(`Heavy weight`)場合、一旦閉じてから再度開く様子が見えてしまう //**参考リンク **コメント [#h9cd9631] * 参考リンク [#reference] - [[JListのセル内にJButtonを配置する>Swing/ButtonsInListCell]] * コメント [#comment] #comment #comment