33

Java Swing アプリケーション用のアプリケーション全体のキーボード ショートカットを作成したいと考えています。すべてのコンポーネントをループし、それぞれにショートカットを追加すると、フォーカスに関連する副作用があり、ブルート フォース ソリューションのように見えます。

誰もがよりクリーンなソリューションを持っていますか?

4

6 に答える 6

41

各ウィンドウについてJComponent.registerKeyboardAction、 の条件で使用しますWHEN_IN_FOCUSED_WINDOW。または、次を使用します。

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

registerKeyboardAction API docsで説明されているとおりです。

于 2008-09-19T09:35:47.053 に答える
19

カスタム KeyEventDispatcher をインストールします。KeyboardFocusManager クラスも、この機能に適しています。

KeyEventDispatcher

于 2008-09-19T06:58:36.543 に答える
13

(私のように) 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() を使用する必要はないかもしれませんが、グローバル イベント ループをブロックしないことをお勧めします。

于 2011-12-13T07:52:07.780 に答える
6

メニューがある場合、グローバル キーボード ショートカットをメニュー項目に追加できます。

    JMenuItem item = new JMenuItem(action);
    KeyStroke key = KeyStroke.getKeyStroke(
        KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK);
    item.setAccelerator(key);
    menu.add(item);
于 2011-12-13T07:19:57.970 に答える
2

少し単純化した例:

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

});
于 2015-04-21T10:48:30.893 に答える