【问题标题】:Swing: How to provide delay on opening menu from menu-bar/submenuSwing:如何提供从菜单栏/子菜单打开菜单的延迟
【发布时间】:2015-10-29 09:03:28
【问题描述】:

我有一个带有垂直菜单栏和许多子菜单的应用程序。我的问题是:通过将鼠标悬停在父菜单/菜单栏中的相应标签上输入后,子菜单立即打开。但我需要一秒钟的延迟。

这是一个例子:

当我将鼠标从起点移动到终点(见箭头)时,最初打开的菜单将在进入“第二”菜单后关闭。

子菜单也一样:

在 Windows 原生应用程序中,第二种情况可以正常工作,因此我可以将鼠标移到子元素上而不会丢失当前打开的子菜单。

有人有想法,我该如何实现所需的延迟?

这是代码示例

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);
        }
    }
}

【问题讨论】:

    标签: java swing jmenu jmenubar


    【解决方案1】:
    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);
            }
        }
    }
    

    您需要在代码中添加这三行。他们会延迟您的子菜单。这取决于 delay_ms 值

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

    也请参考以下链接:

    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

    【讨论】:

    • 谢谢!它帮助我的子菜单。可能我也可以找到菜单栏的解决方案。
    • 嗯。在我的测试中,它看起来不太好。它仅适用于打开,但不适用于关闭。因此,如果我查看另一个菜单项,当前打开的菜单会立即关闭。我必须取消我的接受。
    • I need that the currently opened menu don't close immediatelly, when another menu/menu item in parent menu selected (on mouse moving).
    • 哇,我明白你的问题了。你参考第二个链接。它会解决你的问题,谢谢。
    • 好的。可能检查的解决方案更好。我明天测试一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多