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

mwg9r5ms  于 2023-01-24  发布在  Java
关注(0)|答案(6)|浏览(146)

我想为一个Java Swing应用程序创建一个应用程序范围的键盘快捷键。循环所有组件并在每个组件上添加快捷键,有与焦点相关的副作用,看起来像是一个蛮力解决方案。
有人有更干净的解决方案吗?

mlnl4t2r

mlnl4t2r1#

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

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

如API文档中所述。

blpfk2vs

blpfk2vs2#

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

58wvjzkj

58wvjzkj3#

对于那些想知道如何使用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;
    }
  });
}

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

2nbm6dog

2nbm6dog4#

如果有菜单,则可以向菜单项添加全局键盘快捷键:

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

rbpvctlc5#

一个简单的例子:

import java.awt.KeyboardFocusManager;
import java.awt.KeyEventDispatcher;
import java.awt.event.KeyEvent;

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

ql3eal8s6#

使用以下代码段

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”替换为所需的快捷键。

相关问题