【问题标题】:JMenuItem accelerator not working when menu bar is hidden隐藏菜单栏时 JMenuItem 加速器不起作用
【发布时间】:2013-08-09 20:53:10
【问题描述】:

这个问题是this question的后续问题。

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

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

但情况并非如此,因为setAccelerator() 方法声明如下:

public void setAccelerator(KeyStroke keyStroke)

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

那么,我想知道这是否是另一个 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();
            }
        });
    }
}

【问题讨论】:

  • 我认为这是一个文档问题:这里的“显示”是指解决菜单栏下的菜单/项目隐藏的正常状态(因为我们只看到菜单栏)。尽管如此,它是显示(因为它是可见的并且它的所有祖先都显示),因此允许绑定工作。

标签: java swing jmenuitem jmenubar


【解决方案1】:

仔细阅读你的重点

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

这谈论的是 menu 而不是它的父级。这意味着 menu 当前可能不显示。然而,真正的(可能没有充分记录的)渴望属性是它必须显示。已经更新了我对您上一个问题的回答。

【讨论】:

  • 哇。就像最后一个问题一样,我自己从来没有想过这个问题。这个社区充满了真正有天赋的开发者!
  • 哦,我多么喜欢 Java...所以,我扩展了 JMenuBar 并且(好吧,不要向我扔西红柿)尝试将新类导入 Netbeans(是的,GUI 构建器) ,我遇到了这个有趣的小细节:JMenuBar 的所有方法都没有完成。有人在 1999 年(得到这个)抱怨这个:bugs.sun.com/bugdatabase/view_bug.do?bug_id=4087846,它仍然没有得到修复。为纪念这个错误,在 2006 年创建了一篇名为“wtf”的博客文章。tsareto.blogspot.com/2006/05/wtf.html。所以,不要打电话给JMenuBar.getHelpMenu(),因为Java还没有搞定。
  • SSCCE:public static void main(String[] args) { JMenuBar bar = new JMenuBar(); bar.getHelpMenu(); }
  • @Override public JMenu getHelpMenu() { return null; } 成功了,哈哈
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 2014-06-12
  • 1970-01-01
  • 2013-09-08
  • 1970-01-01
相关资源
最近更新 更多