Swing/PopupWithoutClickOnMenu のバックアップ(No.15)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/PopupWithoutClickOnMenu へ行く。
- 1 (2013-02-18 (月) 00:29:59)
- 2 (2014-08-12 (火) 20:55:02)
- 3 (2014-08-13 (水) 20:04:35)
- 4 (2014-10-04 (土) 03:35:03)
- 5 (2015-11-10 (火) 01:51:42)
- 6 (2016-06-24 (金) 16:30:47)
- 7 (2017-03-28 (火) 19:41:42)
- 8 (2017-04-07 (金) 13:51:51)
- 9 (2017-11-02 (木) 15:34:40)
- 10 (2018-01-30 (火) 20:57:07)
- 11 (2018-02-27 (火) 13:14:53)
- 12 (2020-03-03 (火) 17:59:56)
- 13 (2021-03-29 (月) 01:34:16)
- 14 (2022-08-20 (土) 22:15:25)
- 15 (2024-02-03 (土) 14:02:34)
- category: swing folder: PopupWithoutClickOnMenu title: JMenuの領域内にマウスカーソルでポップアップメニューを表示する tags: [JMenu, MouseListener] author: aterai pubdate: 2013-02-18T00:29:59+09:00 description: JMenuの領域内にマウスカーソルが入ったときにポップアップメニューが開くように設定します。 image:
概要
JMenu
の領域内にマウスカーソルが入ったときにポップアップメニューが開くように設定します。
Screenshot
Advertisement
サンプルコード
visitAll(menubar, new MouseAdapter() {
@Override public void mousePressed(MouseEvent e) {
if (check.isSelected()) {
((AbstractButton) e.getComponent()).doClick();
}
}
@Override public void mouseEntered(MouseEvent e) {
if (check.isSelected()) {
((AbstractButton) e.getComponent()).doClick();
}
}
});
View in GitHub: Java, Kotlin解説
上記のサンプルでは、トップレベルの(JMenuBar
の子コンポーネントになっている)JMenu
の領域内にマウスカーソルが入った場合に自動的にポップアップメニューが開くように、JMenu#doClick()
を実行するMouseListener
を追加しています。
- マウスボタンを押した場合も入った場合にすでに表示したポップアップメニューが非表示にならないように
JMenu#doClick()
を実行 - このサンプルのすべての
JMenuItem
は、beep
音を鳴らすだけのダミー - この
JMenu
の入った、JPopupMenu
をJComponent#setComponentPopupMenu(...)
でJMenuBar
以外のコンポーネントに設定すると無限ループする - 回避方法:
- マウスイベントを作成して
menu.dispatchEvent(new MouseEvent(menu, MouseEvent.MOUSE_ENTERED, e.getWhen(), 0, 0, 0, 0, false));
を実行する MenuElement
の配列を作成し、MenuSelectionManager.defaultManager().setSelectedPath(new MenuElement[]{...});
を実行する- ドキュメントには、「このメソッドは public ですが、Look & Feel エンジンで使用されるため、クライアントアプリケーションからは呼び出さないでください。」と記述されているが、現状では
JMenu
のbuildMenuElementArray(...)
が以下の状態なので仕方ない
- ドキュメントには、「このメソッドは public ですが、Look & Feel エンジンで使用されるため、クライアントアプリケーションからは呼び出さないでください。」と記述されているが、現状では
- マウスイベントを作成して
/*
* Build an array of menu elements - from <code>PopupMenu</code> to
* the root <code>JMenuBar</code>.
* @param leaf the leaf node from which to start building up the array
* @return the array of menu items
*/
private MenuElement[] buildMenuElementArray(JMenu leaf) {
Vector<MenuElement> elements = new Vector<MenuElement>();
Component current = leaf.getPopupMenu();
JPopupMenu pop;
JMenu menu;
JMenuBar bar;
while (true) {
if (current instanceof JPopupMenu) {
pop = (JPopupMenu) current;
elements.insertElementAt(pop, 0);
current = pop.getInvoker();
} else if (current instanceof JMenu) {
menu = (JMenu) current;
elements.insertElementAt(menu, 0);
current = menu.getParent();
} else if (current instanceof JMenuBar) {
bar = (JMenuBar) current;
elements.insertElementAt(bar, 0);
MenuElement me[] = new MenuElement[elements.size()];
elements.copyInto(me);
return me;
}
}
}