【问题标题】:JMenuItem does not call action listeners when outside main frameJMenuItem 在主框架外不调用动作监听器
【发布时间】:2023-03-03 00:42:01
【问题描述】:

我在主框架右侧的 JMenu 子菜单中有一个 JMenuItem。

子菜单弹出时显示在主菜单的右侧,位于主框架之外。

在此状态下通过鼠标单击选择菜单项时,不会将 ActionEvent 传播到操作侦听器。

有趣的是,使用 enter 进行键盘选择确实会调用动作侦听器。

当主框架展开以填满屏幕时,子菜单会弹出到主菜单的左侧,因此位于主框架内。

在这种情况下,当鼠标在菜单项中单击时,会传播 ActionEvent。

我向 JMenuItem 添加了一个鼠标侦听器来调试它,我注意到 MOUSE_ENTERED 和 MOUSE_PRESSED 事件确实发生了,但只有当 JMenuItem 在主框架内时才会发生 MOUSE_RELEASED 事件。

我在 Windows 7(64 位)上使用 Java 1.7.0_45。

有没有其他人遇到过这个问题?

【问题讨论】:

  • Has anybody come else encountered this issue? 不。How to Use Menus 上的 Swing 教程中的 MenuDemo 示例对我来说效果很好。将您的代码与工作代码进行比较,看看有什么区别。
  • 为了尽快获得更好的帮助,请发布MCVE(最小完整可验证示例)或SSCCE(简短、独立、正确示例)。
  • 感谢您的建议。我通过添加子菜单修改了 Swing PopupMenuDemo,并验证了当子菜单显示在父框架之外时它是否有效。我将不得不查看父框架中是否有任何东西阻止事件传播。应用程序相当复杂,发布创建菜单的代码没有意义,因为它是微不足道的。

标签: java swing actionlistener jmenu jmenuitem


【解决方案1】:

问题是由我们应用程序中的以下初始化代码引起的,这是 Java 6 中问题的解决方法:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6770457

    // Workaround for issue
    // (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6770457)
    PopupFactory.setSharedInstance(new PopupFactory() {

        @Override
        public Popup getPopup(Component owner, Component contents, int x, int y) {
            Window win = SwingUtilities.getWindowAncestor(owner);
            if (win.isActive()) {
                return super.getPopup(owner, contents, x, y);
            }
            return super.getPopup(JOptionPane.getRootFrame(), contents, x, y);
        }
    });
    // end fix

解决方法是修改if语句如下:

            if (win.isActive() || win.getClass().getName().equalsIgnoreCase("javax.swing.Popup$HeavyWeightWindow")) {

希望这对其他人有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 2012-07-31
    相关资源
    最近更新 更多