Frage

Ich möchte eine Anwendung breite Tastenkombination für eine Java-Swing-Anwendung erstellen. Looping über alle Komponenten und das Hinzufügen der Verknüpfung auf jedem hat damit verbundene Nebenwirkungen konzentrieren, und scheint wie eine Brute-Force-Lösung.

Jeder hat eine sauberere Lösung?

War es hilfreich?

Lösung

Installieren eines benutzerdefinierten KeyEventDispatcher. Die KeyboardFocusManager Klasse ist auch ein guter Ort für diese Funktionalität.

KeyEventDispatcher

Andere Tipps

Für jedes Fenster, benutzen Sie JComponent.registerKeyboardAction mit einer Bedingung von WHEN_IN_FOCUSED_WINDOW. Alternativ verwenden:

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

, wie in der register API-Dokumentation .

Für Menschen (wie ich) fragen, wie KeyEventDispatcher zu verwenden, hier ist ein Beispiel, das ich zusammen. Es verwendet eine HashMap für alle globalen Aktionen zu speichern, weil ich nicht groß if (key == ..) then .. else if (key == ..) then .. else if (key ==..) .. Konstrukte mag.

/** 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;
    }
  });
}

Die Verwendung von SwingUtils.invokeLater () ist vielleicht nicht notwendig, aber es ist wahrscheinlich eine gute Idee, nicht die globale Ereignisschleife zu sperren.

Wenn Sie ein Menü haben, können Sie globale Tastaturkürzel Menüpunkte hinzufügen:

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

Ein wenig vereinfachtes Beispiel:

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

});

Verwenden Sie das folgende Stück Code

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

Ersetzen Sie "Strg D" mit der Verknüpfung, die Sie wollen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top