代码之家  ›  专栏  ›  技术社区  ›  Louis Jacomet

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

  •  34
  • Louis Jacomet  · 技术社区  · 17 年前

    我想为Java Swing应用程序创建一个应用程序范围的键盘快捷键。 遍历所有组件并在每个组件上添加快捷方式,会产生与焦点相关的副作用,看起来像是一种蛮力解决方案。

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

    6 回复  |  直到 12 年前
        1
  •  20
  •   Karl    17 年前

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

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

    如所述 registerKeyboardAction API docs .

        2
  •  39
  •   daniel kullmann    14 年前

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

    KeyEventDispatcher

        3
  •  14
  •   daniel kullmann    14 年前

    对于像我一样想知道如何使用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()可能不是必需的,但最好不要阻塞全局事件循环。

        4
  •  6
  •   daniel kullmann    14 年前

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

        JMenuItem item = new JMenuItem(action);
        KeyStroke key = KeyStroke.getKeyStroke(
            KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK);
        item.setAccelerator(key);
        menu.add(item);
    
        5
  •  1
  •   mortalis    11 年前

    一个简单的例子:

    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;
      }
      
    });
    
        6
  •  -1
  •   JavaTechnical    13 年前

    使用以下代码

    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”替换为您想要的快捷方式。