简体   繁体   English

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

[英]JMenuItem accelerator not working when menu bar is hidden

This question is a follow-up to this question . 这个问题是一个跟进到这个问题

I have a JMenuBar whose behavior is like the menu bars in Firefox and iTunes. 我有一个JMenuBar其行为类似于Firefox和iTunes中的菜单栏。 That is, the menu bar is initially hidden, but when you press Alt , the menu bar appears. 也就是说,菜单栏最初是隐藏的,但是当您按Alt ,菜单栏出现。

The answer to the other question solved the problem of achieving that functionality, but it brought about another issue: The JMenuItem accelerators are not working when the JMenuBar is not visible. 另一个问题的答案解决了实现该功能的问题,但是又带来了另一个问题:当JMenuBar不可见时, JMenuItem加速器不起作用。 In other words, you must press Alt before CTRL+F (the installed accelerator) will work. 换句话说,您必须先按Alt然后才能使用CTRL+F (已安装的加速器)。

This is not supposed to be the case, though, because the setAccelerator() method states the following: 但是,这不是事实,因为setAccelerator()方法声明以下内容:

public void setAccelerator(KeyStroke keyStroke) 公共无效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. UI负责安装正确的操作。 Note that when the keyboard accelerator is typed, it will work whether or not the menu is currently displayed. 请注意,键入键盘加速器后,无论当前是否显示菜单,它都将起作用。

So, I'm wondering if this is another Java bug? 因此,我想知道这是否是另一个Java错误?

SSCCE (to get the menu to appear, you press Alt , and the installed accelerator is CTRL+F for "Find" which brings up a dummy JOptionPane for input): SSCCE (要显示菜单,请按Alt ,安装的加速器为CTRL+F的“ Find”,将弹出一个虚拟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();
            }
        });
    }
}

Read your emphasis carefully 仔细阅读您的重点

Note that when the keyboard accelerator is typed, it will work whether or not the menu is currently displayed. 请注意,键入键盘加速器后,无论当前是否显示菜单,它都将起作用。

This talks about the menu not its parent. 这是在谈论菜单而不是菜单的父菜单 Meaning that the menu might be currently not displayed. 这意味着该菜单可能当前未显示。 Nevertheless, the real (probably not overly well documented) desisive property is that it must be showing . 但是,真正的(可能记录得不够充分)的抗辩性是它必须显示出来 Had updated my answer to your previous question. 更新了我对您先前问题的回答。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM