Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Swing - Add leniency when selecting items in submenus

When attempting to click on an item in a submenu, it is natural to quickly draw your mouse across the menu items below it. Both Windows and Mac natively handle this by putting a small delay before the a menu is opened. Swing JMenus do not handle this, and the menu the mouse briefly hovers over would be opened before the mouse reaches the intended menu item.

For example, in the image below, if I tried to select Item 3, but in the process my mouse briefly slid across Menu 2, the Menu 1 submenu would disappear before I got to it.

Does anyone have any tips or suggestions for getting around this? My idea was to define a custom MenuUI that added a timer to its mouse handler.

a screen

Here is some simple example code that illustrates my problem:

public class Thing extends JFrame {
    public Thing()
    {
        super();
        this.setSize(new Dimension(500, 500));
        final JPopupMenu pMenu = new JPopupMenu();
        for (int i = 0; i < 5; i++)
        {
            JMenu menu = new JMenu("Menu " + i);
            pMenu.add(menu);
            for (int j = 0; j < 10; j++)
            {
                menu.add(new JMenuItem("Item " + j));
            }
        }

        this.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseReleased(MouseEvent e) {
                pMenu.show(Thing.this, e.getX(), e.getY());
            }
        });
    }

    public static void main(String[] args)
    {
        Thing t = new Thing();
        t.setVisible(true);
    }
}
like image 210
flutillie Avatar asked Sep 24 '13 20:09

flutillie


1 Answers

Call setDelay(delay) on your menu variable, where the delay parameter is the amount of milliseconds to wait for the menu to show, as an int.

This following line of code will set the delay to 1 second, so the user has to mouseover the menu item "Menu n" 1 second, before the submenu is displayed: menu.setDelay(1000);

Here's a snippet of the edited code:

for (int i = 0; i < 5; i++)
{
    JMenu menu = new JMenu("Menu " + i);
    pMenu.add(menu);
    for (int j = 0; j < 10; j++)
    {
        menu.add(new JMenuItem("Item " + j));
    }
    menu.setDelay(1000);
}
like image 120
Birb Avatar answered Oct 17 '22 05:10

Birb