2010-01-07 4 views
7

J'ai un élément de menu, "renommer", pour lequel F2 est défini comme un accélérateur. En effet, lorsque le menu est affiché, il y a une petite indication "F2" à côté de "renommer".Swing: Réglage d'une touche de fonction (F2) en tant qu'accélérateur

Malheureusement, cela ne fonctionne pas. Cet accélérateur ne déclenche aucune réponse. Quand je change l'accélérateur en CTRL + F2 - cela fonctionne.

Il semble que je devrais utiliser un InpoutMpa/ActionMap. Le problème avec cela est que je veux que cela fonctionne partout dans l'application, donc j'essaie de l'associer avec le JFrame de haut niveau. Mais, JFrame n'a pas de méthode getInputMap().

Perdu.

[Ajouté]

 ks = KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0); 
    JMenuItem mi = new JMenuItem("Rename"); 
    mi.setAccelerator(ks); 
    mi.addActionListener(action); 
+1

S'il vous plaît nous montrer la vous utilisez le codage pour régler l'accélérateur! –

+3

Est-ce que votre gestionnaire d'OS/fenêtre "consomme" la frappe de sorte qu'il n'arrive jamais à votre application Swing (par exemple parce que F2 est mappé à quelque chose de spécial, et Ctrl-F2 ne l'est pas)? – netzwerg

Répondre

4

Cela passe probablement parce que JTable utilise F2 pour invoquer l'action StartEditing (j'ai vu le même comportement sur un de mes programmes et traça à ce sujet).

Il existe plusieurs solutions. La plus radicale est de supprimer ce mappage d'entrée (je crois que ce code supprime en fait la mise en correspondance de tous JTables):

KeyStroke keyToRemove = KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0); 

InputMap imap = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 
while (imap != null) 
{ 
    imap.remove(keyToRemove); 
    imap = imap.getParent(); 
} 

Ou, si vous utilisez la table pour afficher uniquement et ne compte pas laisser l'utilisateur de modifier, vous pouvez le faire non focalisable:

table.setFocusable(false); 

sur un tout autre sujet, je vous recommande vivement de créer une sous-classe AbstractAction pour vos éléments de menu, plutôt que de les créer « à partir de zéro ». En plus de vous donner un code de configuration de menu très simple, vous pouvez utiliser la même instance d'action pour le menu principal et une barre d'outils contextuelle, et les activer/désactiver en même temps.

4

Je sais que c'est un vieux fil, mais j'ai lutté avec exactement la même chose que l'affiche originale et trouvé la solution. Le JFrame lui-même n'a pas de méthode getInputMap, mais son volet racine le fait. Vous devez donc utiliser "getRootPane.getInputMap" à la place.

code Exemple:

public class ApplicationFrame extends JFrame { 
    private AbstractAction f2Action = new AbstractAction() { 
     private static final long serialVersionUID = 1L; 

     public void actionPerformed(ActionEvent e) { 
      // Do something useful 
     } 
    }; 

    public ApplicationFrame() { 

     InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); 
     ActionMap actionMap = getRootPane().getActionMap(); 

     inputMap.put(KeyStroke.getKeyStroke("F2"), "f2Action"); 
     actionMap.put("f2Action", f2Action); 

    } 
} 
+1

hmm .. ne pense pas que cette liaison fonctionnerait quand un accélérateur de menu ne fonctionne pas. – kleopatra

+0

L'accélérateur est une liaison qui est ajoutée quelque part. Le problème est que quelque chose le long de l'arborescence des composants capture la frappe avant qu'elle n'atteigne la liaison. J'ai résolu ceci en écrivant une méthode qui traverse une arborescence entière de conteneur et supprime la séquence de touches de la carte en entrée de tout composant JComponent qu'il trouve. –

Questions connexes