Java Swing - 在子菜单中选择项目时添加宽大处理 [英] Java Swing - Add leniency when selecting items in submenus

查看:146
本文介绍了Java Swing - 在子菜单中选择项目时添加宽大处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试单击子菜单中的某个项目时,很自然地会在其下方的菜单项中快速绘制鼠标。 Windows和Mac本身都通过在菜单打开之前稍微延迟来处理这个问题。 Swing JMenus不处理这个问题,鼠标暂时悬停的菜单会在鼠标到达预定的菜单项之前打开。

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.

例如,在下图中,如果我尝试选择第3项,但在此过程中我的鼠标短暂滑过菜单2 菜单1 子菜单会在我到达之前消失。

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.

有没有人有任何提示或建议来解决这个问题?我的想法是定义一个自定义MenuUI,为其鼠标处理程序添加一个计时器。

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.

这是一个简单的示例代码,用于说明我的问题:

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


推荐答案

我想出了一个非常讨厌的解决方案。

I came up with a very hacky solution.

我做了一个扩展BasicMenuUI的UI类。我重写 createMouseInputListener 方法返回自定义 MouseInputListener 而不是私有处理程序对象 BasicMenuUI

I made a UI class that extends BasicMenuUI. I override the createMouseInputListener method to return a custom MouseInputListener instead of the private handler object inside BasicMenuUI.

然后我得到了 MouseInputListener的代码从GrepCode [1]中的处理程序中实现,并将其复制到我的自定义侦听器中。我做了一个更改,将计时器放在 mouseEntered 中。我的 mouseEntered 的最终代码如下所示:

I then got the code for the MouseInputListener implementation in handler from GrepCode[1], and copied it into my custom listener. I made one change, putting a timer in mouseEntered. My final code for mouseEntered looks like this:

public void mouseEntered(MouseEvent e) {
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                if (menuItem.isShowing())
                {
                    Point mouseLoc = MouseInfo.getPointerInfo().getLocation();
                    Point menuLoc = menuItem.getLocationOnScreen();
                    if (mouseLoc.x >= menuLoc.x && mouseLoc.x <= menuLoc.x + menuItem.getWidth() &&
                            mouseLoc.y >= menuLoc.y && mouseLoc.y <= menuLoc.y + menuItem.getHeight())
                    {
                        originalMouseEnteredStuff();
                    }
                }
            }
        }, 100);
    }

在调用中的原始代码之前mouseEntered ,我检查确保鼠标仍在此菜单的区域内。我不希望鼠标刷过的所有菜单在100毫秒后弹出。

Before calling the the original code that was in mouseEntered, I check to make sure the mouse is still within this menu's area. I don't want all the menus my mouse brushes over to pop up after 100 ms.

如果有人发现了更好的解决方案,请告诉我。

Please let me know if anyone has discovered a better solution for this.

[1] http://www.grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/7-b147/javax/swing/plaf/basic/BasicMenuUI.java/?v=来源

这篇关于Java Swing - 在子菜单中选择项目时添加宽大处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆