Ich versuche ein KeyListener
für mein zu implementieren JFrame
. Auf dem Konstruktor verwende ich diesen Code:
System.out.println("test");
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) { System.out.println( "tester"); }
public void keyReleased(KeyEvent e) { System.out.println("2test2"); }
public void keyTyped(KeyEvent e) { System.out.println("3test3"); }
});
Wenn ich es ausführe, wird die test
Nachricht in meiner Konsole angezeigt. Wenn ich jedoch eine Taste drücke, erhalte ich keine der anderen Nachrichten, als ob die KeyListener
nicht einmal da wäre.
Ich dachte, dass es sein könnte, weil der Fokus nicht auf dem liegt JFrame
und sie KeyListener
keine Ereignisse erhalten. Aber ich bin mir ziemlich sicher, dass es so ist.
Fehlt mir etwas?
quelle
Wenn Sie nicht über einen Hörer auf jede Komponente registrieren möchten,
können Sie Ihre eigenen hinzufügen
KeyEventDispatcher
, um dieKeyboardFocusManager
:public class MyFrame extends JFrame { private class MyDispatcher implements KeyEventDispatcher { @Override public boolean dispatchKeyEvent(KeyEvent e) { if (e.getID() == KeyEvent.KEY_PRESSED) { System.out.println("tester"); } else if (e.getID() == KeyEvent.KEY_RELEASED) { System.out.println("2test2"); } else if (e.getID() == KeyEvent.KEY_TYPED) { System.out.println("3test3"); } return false; } } public MyFrame() { add(new JTextField()); System.out.println("test"); KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); manager.addKeyEventDispatcher(new MyDispatcher()); } public static void main(String[] args) { MyFrame f = new MyFrame(); f.pack(); f.setVisible(true); } }
quelle
InputMaps und ActionMaps wurden entwickelt, um die wichtigsten Ereignisse für die Komponente, sie und alle ihre Unterkomponenten oder das gesamte Fenster zu erfassen. Dies wird über den Parameter in JComponent.getInputMap () gesteuert. Siehe Wie Verwenden Tastenbelegungen für die Dokumentation.
Das Schöne an diesem Design ist, dass man auswählen kann, welche Tastenanschläge wichtig sind, um zu überwachen, und basierend auf diesen Tastenanschlägen verschiedene Aktionen auslösen kann.
Dieser Code ruft dispose () in einem JFrame auf, wenn die Escape-Taste irgendwo im Fenster gedrückt wird. JFrame leitet sich nicht von JComponent ab, daher müssen Sie eine andere Komponente im JFrame verwenden, um die Schlüsselbindung zu erstellen. Der Inhaltsbereich kann eine solche Komponente sein.
InputMap inputMap; ActionMap actionMap; AbstractAction action; JComponent component; inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); actionMap = component.getActionMap(); action = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { dispose(); } }; inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "dispose"); actionMap.put("dispose", action);
quelle
KeyListener
ist niedrig und gilt nur für eine einzelne Komponente. Trotz der Versuche, die Benutzerfreundlichkeit zuJFrame
verbessern, werden eine Reihe von Komponentenkomponenten erstellt, von denen die offensichtlichste der Inhaltsbereich ist.JComboBox
Die Benutzeroberfläche wird häufig auf ähnliche Weise implementiert.Es ist erwähnenswert, dass die Mausereignisse auf seltsame Weise funktionieren, etwas anders als bei Schlüsselereignissen.
Einzelheiten dazu, was Sie tun sollten, finden Sie in meiner Antwort unter Anwendungsweite Tastenkombination - Java Swing .
quelle
Ich habe das gleiche Problem, bis ich gelesen habe, dass das eigentliche Problem FOCUS ist, das Ihr JFrame bereits Listener hinzugefügt hat, aber der Tour-Frame ist nie auf Focus eingestellt, da Sie viele Komponenten in Ihrem JFrame haben, die auch fokussierbar sind. Versuchen Sie also:
JFrame.setFocusable(true);
Viel Glück
quelle
Deion (und jeder andere, der eine ähnliche Frage stellt), Sie könnten den obigen Peter-Code verwenden, aber anstatt auf die Standardausgabe zu drucken, testen Sie den Schlüsselcode PRESSED, RELEASED oder TYPED.
@Override public boolean dispatchKeyEvent(KeyEvent e) { if (e.getID() == KeyEvent.KEY_PRESSED) { if (e.getKeyCode() == KeyEvent.VK_F4) { dispose(); } } else if (e.getID() == KeyEvent.KEY_RELEASED) { if (e.getKeyCode() == KeyEvent.VK_F4) { dispose(); } } else if (e.getID() == KeyEvent.KEY_TYPED) { if (e.getKeyCode() == KeyEvent.VK_F4) { dispose(); } } return false; }
quelle
Um Schlüsselereignisse ALLER Textfelder in einem JFrame zu erfassen , kann ein Schlüsselereignis- Postprozessor verwendet werden. Hier ist ein funktionierendes Beispiel, nachdem Sie die offensichtlichen Includes hinzugefügt haben.
public class KeyListenerF1Demo extends JFrame implements KeyEventPostProcessor { public static final long serialVersionUID = 1L; public KeyListenerF1Demo() { setTitle(getClass().getName()); // Define two labels and two text fields all in a row. setLayout(new FlowLayout()); JLabel label1 = new JLabel("Text1"); label1.setName("Label1"); add(label1); JTextField text1 = new JTextField(10); text1.setName("Text1"); add(text1); JLabel label2 = new JLabel("Text2"); label2.setName("Label2"); add(label2); JTextField text2 = new JTextField(10); text2.setName("Text2"); add(text2); // Register a key event post processor. KeyboardFocusManager.getCurrentKeyboardFocusManager() .addKeyEventPostProcessor(this); } public static void main(String[] args) { JFrame f = new KeyListenerF1Demo(); f.setName("MyFrame"); f.pack(); f.setVisible(true); } @Override public boolean postProcessKeyEvent(KeyEvent ke) { // Check for function key F1 pressed. if (ke.getID() == KeyEvent.KEY_PRESSED && ke.getKeyCode() == KeyEvent.VK_F1) { // Get top level ancestor of focused element. Component c = ke.getComponent(); while (null != c.getParent()) c = c.getParent(); // Output some help. System.out.println("Help for " + c.getName() + "." + ke.getComponent().getName()); // Tell keyboard focus manager that event has been fully handled. return true; } // Let keyboard focus manager handle the event further. return false; } }
quelle
Hmm .. für welche Klasse ist dein Konstruktor? Wahrscheinlich eine Klasse, die JFrame erweitert? Der Fensterfokus sollte natürlich auf dem Fenster liegen, aber ich denke nicht, dass das das Problem ist.
Ich habe Ihren Code erweitert, versucht, ihn auszuführen, und es hat funktioniert - die Tastendrücke ergaben sich als Druckausgabe. (mit Ubuntu durch Eclipse laufen lassen):
public class MyFrame extends JFrame { public MyFrame() { System.out.println("test"); addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { System.out.println("tester"); } public void keyReleased(KeyEvent e) { System.out.println("2test2"); } public void keyTyped(KeyEvent e) { System.out.println("3test3"); } }); } public static void main(String[] args) { MyFrame f = new MyFrame(); f.pack(); f.setVisible(true); } }
quelle
Das sollte helfen
yourJFrame.setFocusable(true); yourJFrame.addKeyListener(new java.awt.event.KeyAdapter() { @Override public void keyTyped(KeyEvent e) { System.out.println("you typed a key"); } @Override public void keyPressed(KeyEvent e) { System.out.println("you pressed a key"); } @Override public void keyReleased(KeyEvent e) { System.out.println("you released a key"); } });
quelle
Ich hatte das gleiche Problem. Ich habe Brunos Rat befolgt und festgestellt, dass das Hinzufügen eines KeyListener nur zur "ersten" Schaltfläche im JFrame (dh oben links) den Trick getan hat. Aber ich stimme Ihnen zu, es ist eine beunruhigende Lösung. Also habe ich herumgespielt und einen besseren Weg gefunden, das Problem zu beheben. Fügen Sie einfach die Zeile hinzu
zu Ihrer Hauptmethode, nachdem Sie Ihre Instanz Ihrer Unterklasse von JFrame erstellt und sichtbar gemacht haben.
quelle
lol .... alles was du tun musst ist sicherzustellen, dass
addKeyListener (this);
ist korrekt in Ihrem Code platziert.
quelle
Sie können benutzerdefinierte JComponents festlegen, dass der übergeordnete JFrame fokussierbar ist.
Fügen Sie einfach einen Konstruktor hinzu und übergeben Sie den JFrame. Rufen Sie dann setFocusable () in paintComponent auf.
Auf diese Weise empfängt der JFrame immer KeyEvents, unabhängig davon, ob andere Komponenten gedrückt werden.
quelle