Domanda

Vorrei creare un'applicazione ampia scelta rapida da tastiera per una applicazione Java Swing.Iterare su tutti i componenti e aggiungere il collegamento di ciascuna, è attivo effetti collaterali, e mi sembra una soluzione di forza bruta.

Qualcuno ha una soluzione di pulitura?

È stato utile?

Soluzione

Installare un custom KeyEventDispatcher.Il KeyboardFocusManager classe è anche un buon posto per questa funzionalità.

KeyEventDispatcher

Altri suggerimenti

Per ogni finestra, utilizzare JComponent.registerKeyboardAction con una condizione di WHEN_IN_FOCUSED_WINDOW.In alternativa, utilizzare:

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

come descritto nel registerKeyboardAction API docs.

Per gente che si chiede (come me) come utilizzare KeyEventDispatcher, qui c'è un esempio che ho messo insieme.Esso utilizza un HashMap per la memorizzazione di tutte le azioni globali, perché non mi piace grande if (key == ..) then .. else if (key == ..) then .. else if (key ==..) .. costrutti.

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

L'uso di SwingUtils.invokeLater() non è forse necessario, ma è probabilmente una buona idea di non bloccare l'evento globale loop.

Quando si dispone di un menu, è possibile aggiungere scorciatoie da tastiera globali per le voci di menu:

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

Un po ' semplificato, ad esempio:

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

});

Utilizzare il seguente pezzo di codice

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

Sostituire "ctrl + D", con il collegamento che si desidera.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top