PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Java] Keylistener in JFrame


Talion
2004-03-21, 14:16:48
Zu eigenen Testzwecken und damit ihr nicht so viel Quellcode durchgucken "müsst", habe ich hier einmal ein kleines Programm geschrieben, bei dem das Problem sichtbar wird, dass ich auch bei einem größeren Programm habe. Es geht um Keylistener in Java.

import java.awt.event.*;
import javax.swing.*;

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

public Key()
{
JFrame frame = new JFrame();
frame.setBounds(100, 100, 200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextField input = new JTextField();
keyl kl = this.new keyl();
// frame.addKeyListener(kl);
input.addKeyListener(kl);
frame.getContentPane().add(input);
frame.show();
}

class keyl extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
System.out.println(e);
}
}
}

Das Problem gibt es bei den deutlich eingerückten Zeilen, also
keyl kl = this.new keyl();
// frame.addKeyListener(kl);
input.addKeyListener(kl);
Wenn ich es so mache wie in diesem Beispiel, d.h. dem Textfeld input einen Keylistener hinzufüge (innere Klasse keyl), wird über System.out das KeyEvent ausgegeben, z.b. so etwas für die Taste F1:
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=112,keyText=F1,keyChar=Undefined key
Char,keyLocation=KEY_LOCATION_STANDARD] on javax.swing.JTextField[,0,0,192x173 [...]

Wenn ich nun aber den Listener statt dem Textfeld dem Frame zuweise, passiert gar nichts. Laut Javadoku erbt JFrame die Methode addKeyListener() von der Klasse Component, es gibt auch keinen Fehler beim Kompilieren. Wenn ich im init meiner inneren Klasse keyl irgendetwas ausgeben lasse, zeigt sich auch, dass sie normal initialisiert wird. Der Frame scheint einfach keine Ereignisse zu bemerken. Hat jemand eine Ahnung woran das liegen kann?
Im Endeffekt will ich nichts weiter, als dass man z.b. F1 drücken kann um die Hilfe aufzurufen, und das möglichst ohne dass ich es jeder einzelnen Komponente sagen muss. Geht das nicht?

HellHorse
2004-03-21, 15:46:37
Kannst du nicht einfach ein JMenuItem mit Accelerator F11 machen?

setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F11));

Ehrlich gesagt wundere ich mich, dass es kompiliert, da show() deprecated ist.

Talion
2004-03-21, 15:53:14
Stimmt, an Accelerator hatte ich nicht gedacht. Wobei es ja eigentlich auch anders gehen muss... Naja, egal. Danke jedenfalls.


Hab show() im richtigen Programm auch nicht verwendet; das Testprog was ich hier gepostet hatte stammt von irgendeiner Seite (sollte dort glaube ich EXIT_ON_CLOSE demonstrieren), ich hab nur den Listener ergänzt. Daher die veraltete Methode.

Gast
2004-03-21, 17:08:12
Der Frame bekommt seit 1.4 das KeyEvent nicht mehr mit. Sun nennt das ein Feature, andere ein Bug. Es gibt einen Workaround, mit dem man die KeyEvents nach "unten durchreichen" kann, aber ich habe den jetzt leider nicht im Kopf. Auf den Bug-Seiten von Sun findet sich aber entsprechendes.
Seit wann ist show() für ein Window deprecated? Zumindest in den API-Docs steht es dort nur für Components. Die überschriebene Methode show() in Window ist es aber doch eigentlich nicht!?

Talion
2004-03-21, 17:14:34
Danke für die Infos, sowas in der Richtung hatte ich vermutet. Hat sich aber jetzt erledigt.

Edit: Bei der Codezeile obenm fehlte übrigesn noch ein ,0 für den nicht vorhandenen modifier.

setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0));

Außerdem gab es beim compilieren erst noch n Fehler, der sich aber in Wohlgefalleb aufgelöst hat, als ich sämntliche Dateien neu compiliert habe (auch die nicht geänderten).

HellHorse
2004-03-21, 18:04:11
Original geschrieben von Gast
...
Seit wann ist show() für ein Window deprecated? Zumindest in den API-Docs steht es dort nur für Components. Die überschriebene Methode show() in Window ist es aber doch eigentlich nicht!?
1.5 :D
http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Window.html#show()