Swing/PopupWithoutClickOnMenu のバックアップ(No.12)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - 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;
}
}
}