2010-01-07 51 views
7

我有一个菜单项“rename”,其中F2设置为加速器。事实上,当菜单显示时,在“重命名”旁边有一个小小的“F2”指示。摆动:将功能键(F2)设置为加速器

不幸的是,这是行不通的。这个加速器不会触发任何响应。当我将加速器更改为CTRL + F2时 - 它可以工作。

看来我应该使用InpoutMpa/ActionMap。问题在于,我希望这可以在应用程序中的任何地方工作,所以我试图将它与顶层JFrame关联起来。但是,JFrame没有getInputMap()方法。

丢失。

[新增]

 ks = KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0); 
    JMenuItem mi = new JMenuItem("Rename"); 
    mi.setAccelerator(ks); 
    mi.addActionListener(action); 
+1

请告诉我们编码用于设置加速器! – 2010-01-07 10:02:06

+3

难道你的操作系统/窗口管理器“消耗”了按键,所以它实际上永远不会到达你的Swing应用程序(例如,因为F2被映射到特殊的东西,而Ctrl-F2没有)? – netzwerg 2010-01-07 15:47:07

回答

4

这可能发生,因为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子类,而不是“从头开始”创建它们。除了给你非常简单的菜单设置代码之外,你可以为主菜单和弹出菜单/工具栏使用相同的动作实例,并同时启用/禁用它们。

4

我知道这是一个古老的线索,但我与原始海报完全相同的东西挣扎,并找到了解决方案。 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 2012-10-26 10:20:55

+0

加速器是添加到某处的绑定。问题在于组件树中的某些内容在达到绑定之前捕获键击。我通过编写遍历整个Container树并从其找到的任何JComponent的输入映射中移除击键的方法来解决此问题。 – 2013-11-22 22:55:35