Application wide keyboard shortcut - Java Swing

后端 未结 6 792
[愿得一人]
[愿得一人] 2020-11-30 01:58

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 sid

相关标签:
6条回答
  • 2020-11-30 02:20

    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);
    
    0 讨论(0)
  • 2020-11-30 02:25

    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;
      }
    
    });
    
    0 讨论(0)
  • 2020-11-30 02:27

    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.

    0 讨论(0)
  • 2020-11-30 02:30

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

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

    as described in the registerKeyboardAction API docs.

    0 讨论(0)
  • 2020-11-30 02:30

    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.

    /** 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.

    0 讨论(0)
  • 2020-11-30 02:38

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

    KeyEventDispatcher

    0 讨论(0)
提交回复
热议问题