Question

Je souhaite créer un raccourci clavier large pour une application Java Swing. La boucle sur tous les composants et l’ajout du raccourci sur chacun d’entre eux a des effets secondaires liés à la mise au point et semble être une solution de force brute.

Quelqu'un a-t-il une solution plus propre?

Était-ce utile?

La solution

Installez un KeyEventDispatcher personnalisé. La classe KeyboardFocusManager est également un bon endroit pour cette fonctionnalité.

KeyEventDispatcher

Autres conseils

Pour chaque fenêtre, utilisez JComponent.registerKeyboardAction avec la condition WHEN_IN_FOCUSED_WINDOW . Vous pouvez également utiliser:

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

comme décrit dans le documentation de l'API registerKeyboardAction .

Pour les personnes se demandant (comme moi) comment utiliser KeyEventDispatcher, voici un exemple que j'ai rassemblé. Il utilise un HashMap pour stocker toutes les actions globales, parce que je n'aime pas les gros if (key == ..) then .. else if (key == ..) puis .. else if (key ==. .) .. construit.

/** 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’utilisation de SwingUtils.invokeLater () n’est peut-être pas nécessaire, mais c’est probablement une bonne idée de ne pas bloquer la boucle d’événements globale.

Lorsque vous avez un menu, vous pouvez ajouter des raccourcis clavier globaux aux éléments de menu:

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

Un petit exemple simplifié:

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

});

Utilisez le code suivant

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

Remplacer "ctrl D" avec le raccourci que vous voulez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top