flu*_*lie 6 java swing jmenuitem jmenu
尝试单击子菜单中的项目时,很自然地会在其下方的菜单项中快速绘制鼠标.Windows和Mac本身都通过在打开菜单之前稍微延迟来处理这个问题.Swing JMenus不会处理这个问题,鼠标到达目标菜单项之前会打开鼠标暂时悬停的菜单.
例如,在下图中,如果我尝试选择Item 3,但在此过程中我的鼠标短暂滑过Menu 2,Menu 1子菜单将在我到达之前消失.
有没有人有任何提示或建议来解决这个问题?我的想法是定义一个自定义MenuUI,为其鼠标处理程序添加一个计时器.

这是一些简单的示例代码,说明了我的问题:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我想出了一个非常hacky的解决方案。
我创建了一个扩展 BasicMenuUI 的 UI 类。我重写该createMouseInputListener方法以返回自定义对象MouseInputListener而不是handler内部的私有对象BasicMenuUI。
MouseInputListener然后,我从 GrepCode[1] 获取实现代码handler,并将其复制到我的自定义侦听器中。我做了一个改变,在 mouseEntered. 我的最终代码mouseEntered如下所示:
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);
}
Run Code Online (Sandbox Code Playgroud)
在调用 中的原始代码之前mouseEntered,我检查以确保鼠标仍在该菜单的区域内。我不希望鼠标刷过的所有菜单在 100 毫秒后弹出。
如果有人为此找到了更好的解决方案,请告诉我。
| 归档时间: |
|
| 查看次数: |
566 次 |
| 最近记录: |