Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
应用程序范围的键盘快捷键-Java Swing_Java_Swing_Shortcut_Keystroke - Fatal编程技术网

应用程序范围的键盘快捷键-Java Swing

应用程序范围的键盘快捷键-Java Swing,java,swing,shortcut,keystroke,Java,Swing,Shortcut,Keystroke,我想为JavaSwing应用程序创建一个应用程序范围的键盘快捷键。 在所有组件上循环并在每个组件上添加快捷方式,会产生与焦点相关的副作用,似乎是一种蛮力解决方案 有人有更干净的解决方案吗?安装自定义KeyEventDispatcher。KeyboardFocusManager类也是实现此功能的好地方 对于每个窗口,当在聚焦窗口中时,使用条件为的JComponent.registerKeyboardAction。或者使用: JComponent.getInputMap(WHEN_IN_FOCUSE

我想为JavaSwing应用程序创建一个应用程序范围的键盘快捷键。 在所有组件上循环并在每个组件上添加快捷方式,会产生与焦点相关的副作用,似乎是一种蛮力解决方案


有人有更干净的解决方案吗?

安装自定义KeyEventDispatcher。KeyboardFocusManager类也是实现此功能的好地方


对于每个窗口,当在聚焦窗口中时,使用条件为
JComponent.registerKeyboardAction
。或者使用:

JComponent.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(keyStroke, command);
JComponent.getActionMap().put(command,action);

如。

中所述,当您有菜单时,可以向菜单项添加全局键盘快捷键:

    JMenuItem item = new JMenuItem(action);
    KeyStroke key = KeyStroke.getKeyStroke(
        KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK);
    item.setAccelerator(key);
    menu.add(item);
对于想知道(像我一样)如何使用KeyEventDispatcher的人,这里有一个我放在一起的示例。它使用HashMap来存储所有全局操作,因为我不喜欢大的
if(key==…)then。。否则,如果(键==…)则。。else if(key==…)
构造

/** map containing all global actions */
private HashMap<KeyStroke, Action> actionMap = new HashMap<KeyStroke, Action>();

/** call this somewhere in your GUI construction */
private void setup() {
  KeyStroke key1 = KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_DOWN_MASK);
  actionMap.put(key1, new AbstractAction("action1") {
    @Override
    public void actionPerformed(ActionEvent e) {
      System.out.println("Ctrl-A pressed: " + e);
    }
  });
  // add more actions..

  KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
  kfm.addKeyEventDispatcher( new KeyEventDispatcher() {

    @Override
    public boolean dispatchKeyEvent(KeyEvent e) {
      KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(e);
      if ( actionMap.containsKey(keyStroke) ) {
        final Action a = actionMap.get(keyStroke);
        final ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), null );
        SwingUtilities.invokeLater( new Runnable() {
          @Override
          public void run() {
            a.actionPerformed(ae);
          }
        } ); 
        return true;
      }
      return false;
    }
  });
}
/**包含所有全局操作的映射*/
私有HashMap actionMap=新HashMap();
/**在GUI构造中的某个地方调用它*/
私有无效设置(){
KeyStroke key1=击键.getKeyStroke(KeyEvent.VK\u A,KeyEvent.CTRL\u DOWN\u掩码);
actionMap.put(键1,新抽象动作(“action1”){
@凌驾
已执行的公共无效操作(操作事件e){
System.out.println(“按下Ctrl-A:+e”);
}
});
//添加更多操作。。
KeyboardFocusManager kfm=KeyboardFocusManager.getCurrentKeyboardFocusManager();
addKeyEventDispatcher(新的KeyEventDispatcher(){
@凌驾
公共布尔dispatchKeyEvent(KeyEvent e){
击键击键=击键。getKeyStrokeForEvent(e);
if(actionMap.containsKey(击键)){
最终操作a=actionMap.get(击键);
最终ActionEvent ae=新的ActionEvent(e.getSource(),e.getID(),null);
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
a、 执行的行动(ae);
}
} ); 
返回true;
}
返回false;
}
});
}

可能没有必要使用SwingUtils.invokeLater(),但最好不要阻止全局事件循环。

使用以下代码

ActionListener a=new ActionListener(){
   public void actionPerformed(ActionEvent ae)
   {
    // your code
   }
};
getRootPane().registerKeyboardAction(a,KeyStroke.getKeyStroke("ctrl D"),JComponent.WHEN_IN_FOCUSED_WINDOW);

将“ctrl D”替换为所需的快捷方式。

一个简单的示例:

KeyboardFocusManager keyManager;

keyManager=KeyboardFocusManager.getCurrentKeyboardFocusManager();
keyManager.addKeyEventDispatcher(new KeyEventDispatcher() {

  @Override
  public boolean dispatchKeyEvent(KeyEvent e) {
    if(e.getID()==KeyEvent.KEY_PRESSED && e.getKeyCode()==27){
      System.out.println("Esc");
      return true;
    }
    return false;
  }

});

+这是我找到的最好、最简单的答案。我将升级此X1000,但JFrame没有getInputMap或getActionMapmethod@Can'tTell
JFrame
不是
JComponent
。需要在顶级窗口中的组件上调用这些方法。例如,第一个解决方案:
window.getRootPane().registerKeyboardAction(save.getActionListeners()[0]、KeyStroke.getKeyStroke(KeyEvent.VK_S、KeyEvent.CTRL_MASK)、JComponent.WHEN_IN_IN_FOCUSED_窗口)
用你的JButton的名字替换
save
,用你的JFrame的名字替换
window
。这不是最简单的解决方案,但绝对是最优雅、最可靠的解决方案。不,这是过时的api(从石器时代的jdk 1.2或1.3开始被actionMap/inputMap取代)@kleopatra-Hmm。谢谢你的评论。我想知道原因。我没找到!不太明白-原因是什么?为什么registerKeyboardAction()被禁用请参阅javadoc(JComponent.registerKeyboardAction(java.awt.event.ActionListener,java.lang.String,javax.swing.KeyStroke,int)):此方法现在已过时,请结合使用getActionMap()和getInputMap()来实现类似的行为。