Sergiy Medvynskyy
Sergiy Medvynskyy

Reputation: 11327

Swing: How to provide delay on opening menu from menu-bar/submenu

I have an application with a vertical menu bar and lots of submenus. My problem is: submenu goes open immediately after entering by mouse over the corresponded label in parent menu/menu bar. But I need one second delay.

Here is one example:

enter image description here

When I move the mouse from start to end point (see arrow) the initially opened menu will be closed after entering of menu "Second".

Same case is for submenu:

enter image description here

In Windows native applications the second case works correctly, so I can move mouse over the subelement without to lost the currently opened submenu.

Have somebody an idea, how can I implement the required delay?

Here is the code example

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Point;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.WindowConstants;

public class MenuTryout {

    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        final JFrame frm = new JFrame("Menu test");
        final JMenuBar menuBar = new JMenuBar();
        menuBar.setLayout(new GridLayout(15, 1)); // in my application I use a custom layout here
        JMenu m1 = new VerticalMenu("First");
        m1.add("Subelement 1");
        m1.add("Subelement 2");
        m1.add("Subelement 3");
        final JMenu m11 = new JMenu("Submenu");
        m11.add("Subelement 1.1");
        m11.add("Subelement 1.2");
        m11.add("Subelement 1.3");
        m1.add(m11);
        m1.add("Subelement 4");
        m1.add("Subelement 5");
        menuBar.add(m1);
        m1 = new VerticalMenu("Second");
        m1.add("Subelement 1");
        m1.add("Subelement 2");
        m1.add("Subelement 3");
        menuBar.add(m1);
        m1 = new VerticalMenu("Third");
        m1.add("Subelement 1");
        m1.add("Subelement 2");
        m1.add("Subelement 3");
        menuBar.add(m1);
        frm.add(menuBar, BorderLayout.WEST);
        frm.add(new JScrollPane(new JTextArea(20, 80)));
        frm.pack();
        frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frm.setVisible(true);
    }

    private static class VerticalMenu extends JMenu {
        public VerticalMenu(String aText) {
            super(aText);
        }
        @Override
        protected Point getPopupMenuOrigin() {
            return new Point(getWidth() + 5, 0);
        }
    }
}

Upvotes: 3

Views: 1370

Answers (1)

Kumaresan Perumal
Kumaresan Perumal

Reputation: 1956

package swing;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Point;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.WindowConstants;

public class MenuTryout {

    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        final JFrame frm = new JFrame("Menu test");
        final int DELAY_MS = 1000;
        final JMenuBar menuBar = new JMenuBar();
        menuBar.setLayout(new GridLayout(15, 1)); // in my application I use a custom layout here
        JMenu m1 = new VerticalMenu("First");
        m1.add("Subelement 1");
        m1.add("Subelement 2");
        m1.add("Subelement 3");

        final JMenu m11 = new JMenu("Submenu");
        m11.setDelay(DELAY_MS);
        m11.setDelay(DELAY_MS);
        m11.add("Subelement 1.1");
        m11.add("Subelement 1.2");
        m11.add("Subelement 1.3");
        m1.add(m11);
        m1.add("Subelement 4");
        m1.add("Subelement 5");
        menuBar.add(m1);
        m1 = new VerticalMenu("Second");
        m1.add("Subelement 1");
        m1.add("Subelement 2");
        m1.add("Subelement 3");
        menuBar.add(m1);
        m1 = new VerticalMenu("Third");
        m1.add("Subelement 1");
        m1.add("Subelement 2");
        m1.add("Subelement 3");
        menuBar.add(m1);
        frm.add(menuBar, BorderLayout.WEST);
        frm.add(new JScrollPane(new JTextArea(20, 80)));
        frm.pack();
        frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frm.setVisible(true);
    }

    private static class VerticalMenu extends JMenu {
        public VerticalMenu(String aText) {
            super(aText);
        }
        @Override
        protected Point getPopupMenuOrigin() {
            return new Point(getWidth() + 5, 0);
        }
    }
}

you need to add these three lines in your code. they delay your sub menus. it depends on delay_ms value

     final int DELAY_MS = 1000;
     m11.setDelay(DELAY_MS);
     m11.setDelay(DELAY_MS);

Refer the following links too:

http://bugs.java.com/view_bug.do?bug_id=6563939

Java Swing - Add leniency when selecting items in submenus

http://java-demos.blogspot.in/2013/11/jmenu-example-in-swing.html

Upvotes: 3

Related Questions