Swing/ToolButtonPopup のバックアップの現在との差分(No.12)
TITLE:JToggleButtonからポップアップメニューを開く
Posted by aterai at 2006-07-10
JToggleButtonからポップアップメニューを開く
クリックするとポップアップメニューを表示するJToggleButtonを作成し、これをツールバーに追加します。-
category: swing
folder: ToolButtonPopup
title: JToggleButtonからポップアップメニューを開く
tags: [JToggleButton, JPopupMenu, JToolBar, Icon]
author: aterai
pubdate: 2006-07-10T10:10:27+09:00
description: クリックするとポップアップメニューを表示するJToggleButtonを作成し、これをツールバーに追加します。
image:
hreflang:
href: https://java-swing-tips.blogspot.com/2008/12/adding-jpopupmenu-to-jtoolbar-button.html lang: en
概要
クリックするとポップアップメニューを表示するJToggleButton
を作成し、これをツールバーに追加します。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
class MenuArrowIcon implements Icon {
@Override public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D)g;
Graphics2D g2 = (Graphics2D) g.create();
g2.setPaint(Color.BLACK);
g2.translate(x,y);
g2.drawLine( 2, 3, 6, 3 );
g2.drawLine( 3, 4, 5, 4 );
g2.drawLine( 4, 5, 4, 5 );
g2.translate(-x,-y);
g2.translate(x, y);
g2.drawLine(2, 3, 6, 3);
g2.drawLine(3, 4, 5, 4);
g2.drawLine(4, 5, 4, 5);
g2.dispose();
}
@Override public int getIconWidth() { return 9; }
@Override public int getIconHeight() { return 9; }
#spanadd
#spanend
@Override public int getIconWidth() {
return 9;
}
#spanadd
#spanend
@Override public int getIconHeight() {
return 9;
}
}
#spanadd
#spanend
class MenuToggleButton extends JToggleButton {
private static final Icon i = new MenuArrowIcon();
public MenuToggleButton() {
private static final Icon ARROW_ICON = new MenuArrowIcon();
private JPopupMenu popup;
#spanadd
#spanend
protected MenuToggleButton() {
this("", null);
}
public MenuToggleButton(Icon icon) {
#spanadd
#spanend
protected MenuToggleButton(Icon icon) {
this("", icon);
}
public MenuToggleButton(String text) {
#spanadd
#spanend
protected MenuToggleButton(String text) {
this(text, null);
}
public MenuToggleButton(String text, Icon icon) {
#spanadd
#spanend
protected MenuToggleButton(String text, Icon icon) {
super();
Action a = new AbstractAction(text) {
public void actionPerformed(ActionEvent ae) {
MenuToggleButton b = (MenuToggleButton)ae.getSource();
if(pop!=null) pop.show(b, 0, b.getHeight());
Action action = new AbstractAction(text) {
@Override public void actionPerformed(ActionEvent e) {
Component b = (Component) e.getSource();
Optional.ofNullable(getPopupMenu()).ifPresent(p -> p.show(b, 0, b.getHeight()));
}
};
a.putValue(Action.SMALL_ICON, icon);
setAction(a);
action.putValue(Action.SMALL_ICON, icon);
setAction(action);
setFocusable(false);
setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4+i.getIconWidth()));
setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4 + ARROW_ICON.getIconWidth()));
}
protected JPopupMenu pop;
@Override public void setPopupMenu(final JPopupMenu pop) {
this.pop = pop;
#spanadd
#spanend
public JPopupMenu getPopupMenu() {
return popup;
}
#spanadd
#spanend
public void setPopupMenu(JPopupMenu pop) {
this.popup = pop;
pop.addPopupMenuListener(new PopupMenuListener() {
public void popupMenuCanceled(PopupMenuEvent e) {}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
@Override public void popupMenuCanceled(PopupMenuEvent e) {
/* not needed */
}
#spanadd
#spanend
@Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
/* not needed */
}
#spanadd
#spanend
@Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
setSelected(false);
}
});
}
#spanadd
#spanend
@Override protected void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension dim = getSize();
Insets ins = getInsets();
int x = dim.width-ins.right;
int y = ins.top+(dim.height-ins.top-ins.bottom-i.getIconHeight())/2;
i.paintIcon(this, g, x, y);
int x = dim.width - ins.right;
int y = ins.top + (dim.height - ins.top - ins.bottom - ARROW_ICON.getIconHeight()) / 2;
ARROW_ICON.paintIcon(this, g, x, y);
}
}
解説
上記のサンプルでは、JToggleButtonの右側に余白を設定して、そこに下向きの矢印を上書きしています。解説
-
JToggleButton
の右側に余白を設定してそこに下向きの矢印アイコンを描画 -
JToggleButton
にActionListener
を追加しクリックするとJPopupMenu#show(...)
メソッドでJPopupMenu
を表示-
JPopupMenu
の表示位置はクリック位置ではなくJToggleButton
の下辺になるよう調整
-
参考リンク
- XP Style Icons - Windows Application Icon, Software XP Icons
- アイコン(矢印ではない)を利用しています。
- Swing - Swing bug? cannot set width of JToggleButton
参考リンク
コメント
- いつもお世話になっております。JToggleButtonをOn/Off時、背景色を変える方法はありますか?jToggleButton.setBackground(Color.RED);で試してみましたが、色変化はありませんでした。ご教示、よろしくお願いいたします -- Panda?
- こんばんは。JToggleButton#setBackground(Color)は、LookAndFeelによっては適用されない場合があります。このため、独自のToggleButtonUIを用意したり、例えば以下のような方法を使用する必要があります。 -- aterai
- 例1: 文字列から背景色、縁などのすべてを含めたアイコンを用意してsetSelectedIconで設定する
- 例2: setContentAreaFilled(false);として、自前で選択時の背景を描画する
コメント
- いつもお世話になっております。
JToggleButton
をOn/Off
時、背景色を変える方法はありますか?jToggleButton.setBackground(Color.RED);
で試してみましたが、色変化はありませんでした。ご教示、よろしくお願いいたします -- Panda - こんばんは。
JToggleButton#setBackground(Color)
は、LookAndFeel
によっては適用されない場合があります。このため、独自のToggleButtonUI
を用意したり、例えば以下のような方法を使用する必要があります。 -- aterai- 例
1
: 文字列から背景色、縁などのすべてを含めたアイコンを用意してsetSelectedIcon
で設定する - 例
2
:setContentAreaFilled(false);
として、自前で選択時の背景を描画する
- 例
JToggleButton button = new JToggleButton("text", icon) {
@Override public void paintComponent(Graphics g) {
if(getModel().isSelected()) {
Graphics2D g2 = (Graphics2D)g.create();
@Override protected void paintComponent(Graphics g) {
if (getModel().isSelected()) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(getBackground());
g2.fillRoundRect(0,0,getWidth(),getHeight(),4,4);
g2.fillRoundRect(0, 0, getWidth(), getHeight(), 4, 4);
g2.dispose();
}
super.paintComponent(g);
//......
// ...
}
};
button.setBackground(Color.RED);
button.setContentAreaFilled(false);