Is there a way to get the Window which a JMenuItem
belongs to? I tried this proof of-concept:
JFrame testFrame = new JFrame();
testFrame.setSize(300, 100);
testFrame.setLocationRelativeTo(null);
JMenuBar testBar = new JMenuBar();
JMenu testMenu = new JMenu("Test");
JMenuItem testItem = new JMenuItem("Parent Test");
testItem.addActionListener(e -> {
System.out.println("Has Top Level Ancestor: " + (testItem.getTopLevelAncestor() != null));
System.out.println("Has Window Ancestor: " + (SwingUtilities.getWindowAncestor(testItem) != null));
});
testBar.add(testMenu);
testMenu.add(testItem);
testFrame.setJMenuBar(testBar);
testFrame.setVisible(true);
The output was:
Has Top Level Ancestor: false
Has Window Ancestor: false
I changed it to print the parent of the menu item:
testItem.addActionListener(e -> System.out.println(testItem.getParent().getClass().getSimpleName()));
It prints "JPopupMenu" rather than "JMenu", which means that testMenu
is not the parent of testMenuItem
. However, if you cast the parent class and call JPopupMenu#getInvoker
, it will return the JMenu.
With this in mind, I created the following method:
private static Window getWindowAncestor(JMenuItem item) {
Container parent = item.getParent();
if (parent instanceof JPopupMenu)
return SwingUtilities.getWindowAncestor(((JPopupMenu) parent).getInvoker());
else if (parent instanceof Window)
return (Window) parent;
else
return SwingUtilities.getWindowAncestor(parent);
}
It works :)