2010-01-07 11 views
7

Ich habe einen Menüpunkt "rename", für den F2 als Beschleuniger eingestellt ist. In der Tat, wenn das Menü angezeigt wird, gibt es eine kleine "F2" -Anzeige neben "Umbenennen".Swing: Einstellen einer Funktionstaste (F2) als Beschleuniger

Leider funktioniert das nicht. Dieser Beschleuniger löst keine Antwort aus. Wenn ich den Beschleuniger zu STRG + F2 ändere - es funktioniert.

Es scheint, dass ich eine InpoutMpa/ActionMap verwenden sollte. Das Problem dabei ist, dass ich möchte, dass dies überall in der App funktioniert, also versuche ich, es mit dem JFrame der obersten Ebene zu verbinden. JFrame verfügt jedoch nicht über eine getInputMap() -Methode.

Verloren.

[Added]

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

Bitte zeigen Sie uns die Codierung Sie den Beschleuniger setzen verwenden! –

+3

Könnte es sein, dass Ihr OS/Window-Manager den Tastendruck "konsumiert", so dass er in Ihrer Swing-Anwendung tatsächlich nicht ankommt (z. B. weil F2 etwas Besonderem zugeordnet ist und Strg-F2 nicht)? – netzwerg

Antwort

4

Dies ist wahrscheinlich geschieht, weil JTable F2 verwendet die StartEditing Aktion aufzurufen (sah ich das gleiche Verhalten auf einem meiner Programme und verfolgt es dazu).

Es gibt ein paar Lösungen. Die drastischsten ist diese Eingabe-Mapping zu entfernen (ich glaube, dieser Code tatsächlich die Zuordnung von allen JTables entfernt):

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

Oder, wenn Sie die Tabelle für die Anzeige verwenden nur, und nicht planen zu lassen, der Benutzer bearbeiten es, könnten Sie es nicht fokussierbar machen:

table.setFocusable(false); 

Auf einem ganz anderen Thema, ich empfehlen, eine AbstractAction Unterklasse für die Menüpunkte zu schaffen, anstatt sie „von Grund auf“ zu schaffen. Abgesehen davon, dass Sie einen sehr einfachen Menüeinrichtungscode erhalten, können Sie die gleiche Aktionsinstanz sowohl für das Hauptmenü als auch für ein Popup/eine Symbolleiste verwenden und sie beide gleichzeitig aktivieren/deaktivieren.

4

Ich weiß, das ist ein alter Thread, aber ich habe mit genau der gleichen Sache wie das Original-Poster gekämpft und die Lösung gefunden. Der JFrame selbst verfügt nicht über eine Methode "getInputMap", aber sein Stammbereich tut dies. Sie müssen stattdessen "getRootPane.getInputMap" verwenden.

Beispielcode:

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 .. glaube nicht, dass diese Bindung funktioniert, wenn ein Menübeschleuniger nicht funktioniert. – kleopatra

+0

Der Beschleuniger ist eine Bindung, die irgendwo hinzugefügt wird. Das Problem ist, dass etwas entlang des Komponentenbaums den Tastenanschlag erfasst, bevor er die Bindung erreicht. Ich habe das gelöst, indem ich eine Methode geschrieben habe, die einen gesamten Container-Baum durchquert und den Tastenanschlag aus der Eingabe-Map einer gefundenen J-Komponente entfernt. –

Verwandte Themen