I know how to create Java Swing submenus using JMenu. When we hover the mouse over a JMenu object, it displays a JPopupMenu showing the submenu items, like this:
Submenu using JMenu
My problem is that in my application, determining which menu elements will have a submenu is expensive. I don't want to have to determine in advance whether a particular menu element should be a JMenu or just a JMenuItem. I want to make every element a JMenuItem and display a submenu for it only if the user requests it by, e.g., hovering the mouse over a menu item. Like this:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Menu2 extends JFrame
{
public Menu2()
{
super("Menu2");
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu mItems = new JMenu("Items");
menuBar.add(mItems);
mItems.add(new JMI("A"));
mItems.add(new JMI("B"));
mItems.add(new JMI("C"));
JLabel stuff = new JLabel("Other stuff");
stuff.setPreferredSize(new Dimension(200,200));
getContentPane().add(stuff);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private class JMI extends JMenuItem
implements MouseListener
{
public JPopupMenu childrenPopup = null;
public JMI(String label)
{
super(label);
addMouseListener(this);
}
// MouseListener
public void mouseClicked(MouseEvent ev) {}
public void mouseEntered(MouseEvent ev)
{
// Show a submenu for item "B" only.
// In real life we'd want a Timer to delay showing the submenu
// until we are sure the user is hovering the mouse.
// For simplicity I've omitted it.
if (getText().equals("B")) {
if (childrenPopup == null) {
childrenPopup = new JPopupMenu();
// Expensive processing to determine submenu elements...
childrenPopup.add("D");
childrenPopup.add("E");
}
// Display the submenu
childrenPopup.show(this,getWidth(),0);
}
}
public void mouseExited(MouseEvent ev) {}
public void mousePressed(MouseEvent ev) {}
public void mouseReleased(MouseEvent ev) {}
}
public static void main(String[] args)
throws Exception
{
new Menu2().setVisible(true);
}
}
The only problem is that when my manually created JPopupMenu is displayed, the rest of the menu gets closed. The resulting display does not look like the earlier one, but rather like this:
Submenu displayed manually
Note that I did not click on the "B" menu item, only moved the mouse into it. The menu did not close due to a mouse click.
How can I do what JMenu does -- display a JPopupMenu without closing the rest of the menu?

