Swing/PopupWithoutClickOnMenu のバックアップの現在との差分(No.4)
- 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.getSource()).doClick();
if (check.isSelected()) {
((AbstractButton) e.getComponent()).doClick();
}
}
#spanadd
#spanend
@Override public void mouseEntered(MouseEvent e) {
if(check.isSelected()) {
((AbstractButton)e.getSource()).doClick();
if (check.isSelected()) {
((AbstractButton) e.getComponent()).doClick();
}
}
});
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JMenuBar
の子コンポーネントになっているJMenu
の領域内にマウスカーソルが入った場合に自動的にポップアップメニューが開くように、JMenu#doClick()
を実行するMouseListener
を追加しています。
解説
上記のサンプルでは、トップレベルの(JMenuBar
の子コンポーネントになっている)JMenu
の領域内にマウスカーソルが入った場合に自動的にポップアップメニューが開くように、JMenu#doClick()
を実行するMouseListener
を追加しています。
- 注:
- マウスボタンを押した場合も、入った場合にすでに表示したポップアップメニューが非表示にならないように
JMenu#doClick()
を実行 - このサンプルのすべての
JMenuItem
は、beep
音を鳴らすだけのダミー
- マウスボタンを押した場合も、入った場合にすでに表示したポップアップメニューが非表示にならないように
- -
- マウスボタンを押した場合も入った場合にすでに表示したポップアップメニューが非表示にならないように
JMenu#doClick()
を実行 - このサンプルのすべての
JMenuItem
はbeep
音を鳴らすだけのアクションを設定している - この
JMenu
の入った、JPopupMenu
をJComponent#setComponentPopupMenu(...)
でJMenuBar
以外のコンポーネントに設定すると無限ループする - 回避方法:
- マウスイベントを作成し、
menu.dispatchEvent(new MouseEvent(menu, MouseEvent.MOUSE_ENTERED, e.getWhen(), 0, 0, 0, 0, false));
を実行する - Bug ID: JDK-6949414 JMenu.buildMenuElementArray() endless loop
- マウスイベントを作成し、
- 回避方法:
- マウスイベントを作成して
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 エンジンで使用されるため、クライアントアプリケーションからは呼び出さないでください。」と記述されているが、現状では
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;
}
}
}
参考リンク
参考リンク
- JMenuBarの動作 - Java Solution - @IT
- java - Activate JMenuBar on hover - Stack Overflow
- java - Activate JMenuBar on hover - Stack Overflow