Swing:将功能键(F2)设置为加速键

7
我有一个菜单项名为“重命名”,其中F2被设置为加速键。实际上,当菜单显示时,“重命名”旁边会有一个小的“F2”指示。
遗憾的是,这不起作用。这个加速器没有触发任何响应。当我将加速键更改为CTRL + F2时,它可以正常工作。
看来我应该使用InpoutMap/ActionMap。但问题是,我想让它在应用程序的任何地方都能工作,所以我试图将其与顶级JFrame相关联。但是,JFrame没有getInputMap()方法。
迷失了。
     ks = KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0);
     JMenuItem mi = new JMenuItem("Rename");
     mi.setAccelerator(ks);
     mi.addActionListener(action); 

1
请展示您用于设置加速器的编码! - Carl Smotricz
3
你的操作系统或窗口管理器是否“吞噬”了按键,导致它实际上不会传递到你的Swing应用程序中(例如,因为F2被映射到某个特殊功能,而Ctrl-F2则没有)? - Rahel Lüthy
2个回答

5

这可能是因为JTable使用F2来调用StartEditing操作(我在我的一个程序中看到了相同的行为,并追踪到了这个问题)。

有几种解决方案。最激进的方法是删除此输入映射(我认为此代码实际上会从所有JTable中删除映射):

KeyStroke keyToRemove = KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0);

InputMap imap = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
while (imap != null)
{
    imap.remove(keyToRemove);
    imap = imap.getParent();
}

或者,如果您仅将表格用于显示,而不打算让用户编辑它,您可以使其无法聚焦:

table.setFocusable(false);

完全不同的话题,我强烈建议为您的菜单项创建一个AbstractAction子类,而不是从头开始创建它们。除了给您非常简单的菜单设置代码外,您还可以在主菜单和弹出/工具栏中使用相同的操作实例,并同时启用/禁用它们。


5

我知道这是一个旧的帖子,但我和原始发布者一样也遇到了同样的问题,并找到了解决方法。JFrame本身没有getInputMap方法,但它的根窗格有。因此,您必须使用"getRootPane.getInputMap"。

示例代码:

public class ApplicationFrame extends JFrame {
    private AbstractAction f2Action = new AbstractAction() {
        private static final long serialVersionUID = 1L;

        public void actionPerformed(ActionEvent e) {
            // Do something useful
        }
    };

    public ApplicationFrame() {

        InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap actionMap = getRootPane().getActionMap(); 

        inputMap.put(KeyStroke.getKeyStroke("F2"), "f2Action");
        actionMap.put("f2Action", f2Action);

    }
}

1
嗯...我认为当菜单加速器无法工作时,这个绑定可能不起作用。 - kleopatra
加速器是在某个地方添加的绑定。问题在于,组件树中的某个位置会在它到达绑定之前捕获按键。我通过编写一个遍历整个容器树并从任何发现的JComponent的输入映射中删除按键的方法来解决了这个问题。 - Mad Physicist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接