---
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 [#summary]
`JButton`のドロップダウンリストで、各アイテムにクリック可能な`JButton`を追加しこれを削除します。
#download(https://lh6.googleusercontent.com/-x9uTOO9fSds/T_pElwy8GBI/AAAAAAAABPM/Jx30phjG3bM/s800/RemoveButtonInComboItem.png)
* Source Code Examples [#sourcecode]
#code(link){{
class CellButtonsMouseListener extends MouseAdapter {
@Override public void mouseMoved(MouseEvent e) {
JList<?> list = (JList<?>) e.getComponent();
Point pt = e.getPoint();
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) {
e.getComponent().repaint();
}
@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 (Objects.nonNull(button)) {
button.doClick();
}
}
((ButtonsRenderer<?>) list.getCellRenderer()).rolloverIndex = -1;
list.repaint();
}
@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);
// 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);
}
}
}}
* Description [#explanation]
* Description [#description]
`JComboBox`のドロップダウンリスト(`ComboPopup`)から`JList`を取得し、これに上記のような`MouseListener`を追加しています。
- `JList`がクリックされた場合、レンダラーから対応するセルに表示されている`JButton`を取得して`JButton#doClick()`メソッドを実行
#code{{
Accessible a = getAccessibleContext().getAccessibleChild(0);
if (a instanceof ComboPopup) {
ComboPopup pop = (ComboPopup) a;
JList list = pop.getList();
CellButtonsMouseListener cbml = new CellButtonsMouseListener();
list.addMouseListener(cbml);
list.addMouseMotionListener(cbml);
}
}}
- 削除ボタンがクリックされてもドロップダウンリスト(`ComboPopup`)は表示状態のまま残したい
-- `MutableComboBoxModel#removeElementAt(index)`のあとで`JComboBox#showPopup()`を実行して開き直す
-- `ComboPopup`が`JFrame`の外に表示されている(`Heavy weight`)場合、一旦閉じてから再度開く様子が見えてしまう
* Reference [#reference]
- [[JListのセル内にJButtonを配置する>Swing/ButtonsInListCell]]
* Comment [#comment]
#comment
#comment