Swing/RemoveButtonInComboItem のバックアップ(No.8)
- バックアップ一覧
 - 差分 を表示
 - 現在との差分 を表示
 - 現在との差分 - 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)
 - 16 (2025-01-03 (金) 08:57:02)
 - 17 (2025-01-03 (金) 09:01:23)
 - 18 (2025-01-03 (金) 09:02:38)
 - 19 (2025-01-03 (金) 09:03:21)
 - 20 (2025-01-03 (金) 09:04:02)
 - 21 (2025-06-19 (木) 12:41:37)
 - 22 (2025-06-19 (木) 12:43:47)
 
 
- title: JComboBoxのドロップダウンリストに追加したJButtonで項目を削除する
tags: [JComboBox, JButton, JList, BasicComboPopup, ListCellRenderer, MouseListener]
author: aterai
pubdate: 2012-07-09T12:02:11+09:00
description: JButtonのドロップダウンリストで、各アイテムにクリック可能なJButtonを追加しこれを削除します。
hreflang:
href: http://java-swing-tips.blogspot.com/2012/10/delete-button-in-jcombobox-popup-menu.html lang: en
 
概要
JButtonのドロップダウンリストで、各アイテムにクリック可能なJButtonを追加しこれを削除します。
Screenshot

Advertisement
サンプルコード
class CellButtonsMouseListener extends MouseAdapter {
  private int prevIndex = -1;
  private JButton prevButton;
  private static void listRepaint(JList list, Rectangle rect) {
    if (rect != null) {
      list.repaint(rect);
    }
  }
  @Override public void mouseMoved(MouseEvent e) {
    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);
        listRepaint(list, 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) {
        renderer.rolloverIndex = -1;
        Rectangle r = null;
        if (prevIndex == index) {
          if (prevIndex >= 0 && prevButton != null) {
            r = list.getCellBounds(prevIndex, prevIndex);
          }
        } else {
          r = list.getCellBounds(index, index);
        }
        listRepaint(list, r);
        prevIndex = -1;
      } else {
        button.getModel().setRollover(true);
        renderer.rolloverIndex = index;
        if (!button.equals(prevButton)) {
          Rectangle r = list.getCellBounds(prevIndex, index);
          listRepaint(list, r);
        }
      }
      prevButton = button;
    }
    prevIndex = index;
  }
  @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;
        Rectangle r = list.getCellBounds(index, index);
        listRepaint(list, r);
      }
    }
  }
  @Override public void mouseReleased(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 = null;
        button.doClick();
        Rectangle r = list.getCellBounds(index, index);
        listRepaint(list, r);
      }
    }
  }
  @SuppressWarnings("unchecked")
  private static JButton getButton(JList list, Point pt, int index) {
    Container c = (Container) list.getCellRenderer().getListCellRendererComponent(
        list, "", index, false, false);
    Rectangle r = list.getCellBounds(index, index);
    c.setBounds(r);
    //c.doLayout(); //may be needed for mone LayoutManager
    pt.translate(-r.x, -r.y);
    Component b = SwingUtilities.getDeepestComponentAt(c, pt.x, pt.y);
    if (b instanceof JButton) {
      return (JButton) b;
    } else {
      return null;
    }
  }
}
View in GitHub: Java, Kotlin解説
JComboBoxのドロップダウンリスト(BasicComboPopup)からJListを取得し、これに上記のようなMouseListenerを追加しています。このJListがクリックされた場合、レンダラーから対応するセルに表示されているJButtonを取得し、button.doClick()を呼び出します。
Accessible a = getAccessibleContext().getAccessibleChild(0);
if (a instanceof BasicComboPopup) {
  BasicComboPopup pop = (BasicComboPopup) a;
  JList list = pop.getList();
  CellButtonsMouseListener cbml = new CellButtonsMouseListener();
  list.addMouseListener(cbml);
  list.addMouseMotionListener(cbml);
}
- 削除ボタンがクリックされてもドロップダウンリストは表示状態のまま残るように、
MutableComboBoxModel#removeElementAt(index);のあとでcomboBox.showPopup();を実行 BasicComboPopupが、フレーム外に表示されている場合(Heavy weight)、一旦閉じたあとで再度開かれるように見える