java - 隐藏菜单栏时 JMenuItem 加速器不起作用

标签 java swing jmenuitem jmenubar

此问题是 this question 的后续问题.

我有一个 JMenuBar,它的行为类似于 Firefox 和 iTunes 中的菜单栏。也就是说,菜单栏最初是隐藏的,但是当您按下 Alt 时,菜单栏就会出现。

另一个问题的答案解决了实现该功能的问题,但它带来了另一个问题:JMenuItem 加速器在 JMenuBar 时不工作 不可见。换句话说,您必须先按 Alt,然后 CTRL+F(已安装的加速器)才会起作用。

不过,这不应该是这种情况,因为 setAccelerator() 方法声明如下:

public void setAccelerator(KeyStroke keyStroke)

Sets the key combination which invokes the menu item's action listeners without navigating the menu hierarchy. It is the UI's responsibility to install the correct action. Note that when the keyboard accelerator is typed, it will work whether or not the menu is currently displayed.

所以,我想知道这是否是另一个 Java 错误?

SSCCE (要显示菜单,请按 Alt,安装的加速器是 CTRL+F 用于“查找”,它会弹出一个虚拟的 JOptionPane 用于输入):

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class MenuBarTest extends JFrame {

    public MenuBarTest() {
        JMenu jMenu1 = new JMenu();
        JMenu jMenu2 = new JMenu();
        final JMenuBar jMenuBar1 = new JMenuBar();
        JMenuItem jMenuItem1 = new JMenuItem();
        JMenuItem jMenuItem2 = new JMenuItem();

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        jMenu1.setText("File");
        jMenuItem1.setText("jMenuItem1");
        jMenu1.add(jMenuItem1);
        jMenuBar1.add(jMenu1);
        jMenu2.setText("Edit");
        jMenuItem2.setText("Find");
        jMenu2.add(jMenuItem2);
        jMenuBar1.add(jMenu2);
        setJMenuBar(jMenuBar1);

        jMenuBar1.setVisible(false);
        ChangeListener listener = new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                MenuElement[] elements = MenuSelectionManager.defaultManager().getSelectedPath();
                jMenuBar1.setVisible(elements.length > 0 && elements[0] == jMenuBar1);
            }
        };
        MenuSelectionManager.defaultManager().addChangeListener(listener);

        jMenuItem2.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItem2.setText("Find");
        jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                String what = JOptionPane.showInputDialog(MenuBarTest.this, "Search for what?");
                System.out.println(what);
            }
        });

        pack();
        setSize(500,500);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String args[]) {
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            ex.printStackTrace();
        }
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new MenuBarTest();
            }
        });
    }
}

最佳答案

仔细阅读你的重点

Note that when the keyboard accelerator is typed, it will work whether or not the menu is currently displayed.

这里讨论的是菜单,而不是它的父级。这意味着当前可能未显示菜单。然而,真正的(可能没有充分记录的)抑制特性是它必须显示。已更新我对您之前问题的回答。

关于java - 隐藏菜单栏时 JMenuItem 加速器不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18155493/

相关文章:

java - JMenu 子菜单项未正确显示

java - 扩展 JMenu 以给它一个复选框?

java - Java/Scala 的 Deflator 压缩 BitSet 的性能

java - Play Framework 2.0 邮件插件

java - 扫描仪在使用 next() 或 nextFoo() 后跳过 nextLine()?

Java 使用 jbutton 在卡片之间切换

java - 从网络驱动器加载图像?

java - 我可以替换已编译的 Java 项目中的类文件吗?

java - JPopupMenu.show 显示具有奇怪行为的弹出菜单(有时显示为灰色框)

java - 如何为 JMenuItem 创建和设置椭圆形图标