Swing/RemoveButtonInComboItem のバックアップの現在との差分(No.1)
TITLE:JComboBoxのドロップダウンリストにJButtonを追加
Posted by aterai at 2012-07-09
JComboBoxのドロップダウンリストにJButtonを追加
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:
hreflang:
href: https://java-swing-tips.blogspot.com/2012/10/delete-button-in-jcombobox-popup-menu.html lang: en
概要
JButton
のドロップダウンリストで、各アイテムにクリック可能なJButton
を追加しこれを削除します。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#spanend
#spandel
class CellButtonsMouseListener extends MouseAdapter{
#spanend
private int prevIndex = -1;
private JButton prevButton = null;
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
#spanadd
class CellButtonsMouseListener extends MouseAdapter {
#spanend
@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();
}
#spanadd
#spanend
@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();
}
#spanadd
#spanend
@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);
#spanadd
#spanend
@Override public void mouseExited(MouseEvent e) {
JList<?> list = (JList<?>) e.getComponent();
((ButtonsRenderer<?>) list.getCellRenderer()).rolloverIndex = -1;
}
#spanadd
#spanend
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);
}
}
解説
JComboBoxのドロップダウンリスト(BasicComboPopup)からJListを取得し、これに上記のようなMouseListenerを追加しています。このJListがクリックされた場合、レンダラーから対応するセルに表示されているJButtonを取得し、button.doClick()を呼び出します。解説
JComboBox
のドロップダウンリスト(ComboPopup
)からJList
を取得し、これに上記のようなMouseListener
を追加しています。
-
JList
がクリックされた場合、レンダラーから対応するセルに表示されているJButton
を取得してJButton#doClick()
メソッドを実行Accessible a = getAccessibleContext().getAccessibleChild(0); #spandel if(a instanceof BasicComboPopup) { #spanend BasicComboPopup pop = (BasicComboPopup)a; #spanadd if (a instanceof ComboPopup) { #spanend 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
)場合、一旦閉じてから再度開く様子が見えてしまう
-