2013-08-01 8 views
7

Ich versuche, Tastenbelegungen in Java auf einem JPanel zu machen. Ich möchte eine bestimmte Aktion ausführen, wenn ich die Taste 'w' drücke. Ich befolge das Java-Tutorial zum Erstellen von Bindungen, aber die actionPerformed-Methode wird nicht ausgeführt (d. H., Kein Text wird ausgegeben). Das Folgende ist die Gesamtheit des Code für meinen Test GUI, mit dem entsprechenden Teil hervorgehoben:Java Key Bindings funktioniert nicht

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 

import javax.swing.AbstractAction; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.KeyStroke; 

@SuppressWarnings("serial") 
public class Test extends JFrame{ 

private JPanel panel; 

public Test(){ 
    super(); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setSize(500,500); 
    setLayout(new BorderLayout()); 
    setVisible(true);   
    panel = new JPanel(); 

    // HERE ARE THE KEY BINDINGS 
    panel.getInputMap().put(KeyStroke.getKeyStroke('w'),"forward"); 
    panel.getActionMap().put("forward", new AbstractAction(){ 
     @Override 
     public void actionPerformed(ActionEvent e){ 
      System.out.println("test"); 
     } 
    }); 
    // END OF KEY BINDINGS 

    add(panel, BorderLayout.CENTER); 
} 

public static void main(String[] args){ 
    new Test();  
} 

} 

Der Text „Test“ wird nie gedruckt. Ich habe viele Male mit vielen verschiedenen Varianten, verschiedenen Schlüsseln ausprobiert, und ich stelle sicher, dass das Panel im Fokus steht, aber kein Glück. Was mache ich falsch?

Antwort

13

Das Problem ist die Art und Weise, in der Sie die KeyStroke nachschlagen. KeyStroke.getKeyStroke('w') gibt typed w zurück, was aus irgendeinem Grund kein Schlüsselereignis auslöst. Deshalb tendiere ich dazu, diese Methode zu vermeiden. Stattdessen verwenden

panel.getInputMap().put(KeyStroke.getKeyStroke("W"),"forward"); 

oder

panel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0),"forward"); 

Auch können Sie den Fokus-Einschränkung für die InputMap, so etwas wie

panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)... 

definieren wollen wäre sicherer ... aber Sie müssen um zu entscheiden, auf welcher Ebene die Tastenanschläge ausgelöst werden sollen von

Siehe JComponent und How to use Key Bindings für mehr Details

mit Beispiel Aktualisiert

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import javax.swing.AbstractAction; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.KeyStroke; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test extends JFrame { 

    private JPanel panel; 

    public Test() { 
     super(); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setSize(500, 500); 
     setLayout(new BorderLayout()); 
     setVisible(true); 
     panel = new JPanel(); 

     // HERE ARE THE KEY BINDINGS 
     panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "forward"); 
     panel.getActionMap().put("forward", new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("test"); 
      } 
     }); 
     // END OF KEY BINDINGS 

     add(panel, BorderLayout.CENTER); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       new Test(); 
      } 
     }); 
    } 
} 
+0

Haben Sie ' 'w'' nicht bemerkt, verwendet haben, haben Sie' "w" 'verwendet haben. Mit Arbeitsbeispiel aktualisiert – MadProgrammer