Java 菜单栏隐藏时JMenuItem加速器不工作

Java 菜单栏隐藏时JMenuItem加速器不工作,java,swing,jmenuitem,jmenubar,Java,Swing,Jmenuitem,Jmenubar,这是一个后续问题 我有一个JMenuBar,它的行为类似于Firefox和iTunes中的菜单栏。也就是说,菜单栏最初是隐藏的,但当您按下Alt时,菜单栏会出现 另一个问题的答案解决了实现该功能的问题,但它带来了另一个问题:JMenuItem加速器在JMenuBar不可见时不工作。换句话说,在CTRL+F(已安装的加速器)工作之前,必须按Alt 但情况并非如此,因为setAccelerator()方法说明了以下内容: 公共无效设置加速器(击键) 设置在不导航菜单层次结构的情况下调用菜单项的操作侦

这是一个后续问题

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

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

但情况并非如此,因为
setAccelerator()
方法说明了以下内容:

公共无效设置加速器(击键)

设置在不导航菜单层次结构的情况下调用菜单项的操作侦听器的组合键。用户界面负责安装正确的操作请注意,当键入键盘加速器时,无论当前是否显示菜单,它都会工作。

所以,我想知道这是否是另一个Java bug

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


仔细阅读你的重点

请注意,当键入键盘加速器时,无论菜单当前是否显示,它都将起作用


这谈论的是菜单,而不是它的父菜单。这意味着菜单当前可能未显示。然而,真正的(可能没有充分的文件记录)决定性的特性是它必须显示出来。已经更新了我对你上一个问题的回答

哇。就像最后一个问题,我自己从来没有想到过。这个社区充满了真正有天赋的开发者!哦,我多么喜欢Java。。。因此,我扩展了
JMenuBar
,并且(好的,不要向我扔西红柿)尝试将新类导入Netbeans(是的,GUI构建器),我遇到了这个有趣的小细节:并非所有
JMenuBar
的方法都已经完成。有人在1999年对此提出了抱怨:至今仍未修复。为了纪念这个bug,我们创建了一篇名为“wtf”的博客文章。。在,哦,2006年。因此,不要调用
JMenuBar.getHelpMenu()
,因为Java还没有调用它。SSCCE:
publicstaticvoidmain(String[]args){JMenuBar bar=new JMenuBar();bar.getHelpMenu();}
@Override public JMenu getHelpMenu(){return null;}
lolmy的诀窍在于这是一个文档问题:此处的“显示”表示菜单栏下的菜单/项处于隐藏状态的正常状态(因为我们只看到菜单栏)。然而,它正在显示(因为它是可见的,并且它的所有祖先都在显示),因此允许绑定工作。
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();
            }
        });
    }
}