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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/100123/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:17:53  来源:igfitidea点击:

Application wide keyboard shortcut - Java Swing

javaswingshortcutkeystroke

提问by Louis Jacomet

I would like to create an application wide keyboard shortcut for a Java Swing application. Looping over all components and adding the shortcut on each, has focus related side effects, and seems like a brute force solution.

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

Anyone has a cleaner solution?

有人有更清洁的解决方案吗?

采纳答案by Karl

Install a custom KeyEventDispatcher. The KeyboardFocusManager class is also a good place for this functionality.

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

KeyEventDispatcher

KeyEventDispatcher

回答by Tom Hawtin - tackline

For each window, use JComponent.registerKeyboardActionwith a condition of WHEN_IN_FOCUSED_WINDOW. Alternatively use:

对于每个窗口,使用JComponent.registerKeyboardAction条件为WHEN_IN_FOCUSED_WINDOW。或者使用:

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

as described in the registerKeyboardAction API docs.

registerKeyboardAction API 文档中所述

回答by daniel kullmann

When you have a menu, you can add global keyboard shortcuts to menu items:

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

    JMenuItem item = new JMenuItem(action);
    KeyStroke key = KeyStroke.getKeyStroke(
        KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK);
    item.setAccelerator(key);
    menu.add(item);

回答by daniel kullmann

For people wondering (like me) how to use KeyEventDispatcher, here is an example that I put together. It uses a HashMap for storing all global actions, because I don't like large if (key == ..) then .. else if (key == ..) then .. else if (key ==..) ..constructs.

对于想知道(像我一样)如何使用 KeyEventDispatcher 的人,这是我放在一起的一个示例。它使用 HashMap 来存储所有全局操作,因为我不喜欢大型if (key == ..) then .. else 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;
    }
  });
}

The use of SwingUtils.invokeLater() is maybe not necessary, but it is probably a good idea not to block the global event loop.

SwingUtils.invokeLater() 的使用可能不是必需的,但最好不要阻塞全局事件循环。

回答by JavaTechnical

Use the following piece of code

使用下面的一段代码

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

Replace "ctrl D" with the shortcut you want.

用你想要的快捷方式替换“ctrl D”。

回答by mortalis

A little simplified example:

一个简单的例子:

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;
  }

});