# KeyListener-Alternative ohne anfängliches Delay ?



## kopfsalat (17. Dez 2004)

Hallo!
Ich suche eine Möglichkeit, die (Pfeil)tasten abzufragen, und bin dabei auf das Interface KeyListener mit der Methode KeyPressed als wohl einzige Lösung (mit Alternative abstract class KeyAdapter, welche im Grunde aber dasselbe ist) gestoßen.

Das funktioniert auch alles soweit, aber es gibt ein Problem: 
Wenn man die Taste gedrückt hält, dann wird das KeyEvent für KeyPressed  zunächst nur einmal erzeugt, gefolgt von einer kurzen Pause, danach geht es dann zügig ohne Unterbrechung. Also dasselbe Verhalten, wie es bei normalen Texttastatureingaben gewünscht ist.

Kann man dieses Verhalten ändern ? Z.B. für Rotationen von Objekten, etc. ist das absolut lästig.
Ich hätte gerne, dass sobald die Taste gedrückt ist, die Ereignisse ununterbrochen losgefeuert werden.
Gibt es dafür eine andere Methode - die ggf. näher mit dem Tastaturpuffer zusammenarbeitet ?

Eine umständliche Alternative wäre wohl, mit KeyPressed und KeyReleased lediglich ein 'globales Flag' auf An/Aus zu setzen, und in einer Art Hauptschleife in Abhängigkeit davon die gewünscht Aktion ausführen. Dann aber wäre das gesamte Programm nicht mehr rein Event-orientiert (so, wie ich es mir wünsche), sondern bräuchte eine Hauptschleife.


----------



## Wildcard (17. Dez 2004)

Du könntest auch einen eigenen Thread erzeugen, der gestartet wird wenn eine Taste gedrückt wird,
und beendet wird wenn sie wieder losgelassen wird.
(Hab ich immer so gemacht)
Die Anschlagverögerung auszuschalten ist glaub ich nicht so ohne weiteres möglich.
Bin mir da aber nicht ganz sicher, also wenn es jemand besser weiß...


----------



## 0xdeadbeef (17. Dez 2004)

Ist ein Problem der JVM-Implementierung unter Linux:

Unter Win32 erzeugt eine gedrückte Taste "key pressed"-Nachrichten, solange die Taste gedrückt wird und eine (!)  "key released"-Nachricht, wenn die Taste schließlich losgelassen wird. Unter Linux werden die ganze Zeit "key pressed/key released"-Paare erzeugt.

Dadurch ist es nicht möglich, einen für Spiele geeigneten Tastaturhandler zu schreiben, bei dem ja der Zustand der Taste interessiert.

Einzige Möglichkeit: ausschalten der Tastenwiederholung auf (JVM-)globaler Ebene. Das wird z.B. in der LWJGL so gehandhabt, ist vermutlich aber nativ implementiert.


----------



## kopfsalat (17. Dez 2004)

@3735928559


> Unter Win32 erzeugt eine gedrückte Taste "key pressed"-Nachrichten, solange die Taste gedrückt wird


Das wäre ja schon die Lösung, wenn es da nicht eine kurze Pause nach dem ersten erzeugten Event zu Beginn gäbe. Habe mir gerade mal LWJGL angesehen, sieht gut aus! Gibt es allerdings derzeit 'nur' für Win/Linux/Mac. Ist aber halt nicht mehr ganz so plattformunabhängig.
Wundert mich generell, dass das so ein Problem zu sein scheint, allerdings meine ich mich auch zu entsinnen, dass z.B. der direkte Tastaturzugriff bei Windows sogar DirectX benutzt.

@Wildcard
Ach jau! Threads sollten ja unter Java keine großen Sorgen bereiten. Werde ich wohl erstmal damit ausprobieren. Klingt immerhin 'more OOP', als eine Hauptschleife.


----------



## 0xdeadbeef (20. Dez 2004)

kopfsalat hat gesagt.:
			
		

> @3735928559
> 
> 
> > Unter Win32 erzeugt eine gedrückte Taste "key pressed"-Nachrichten, solange die Taste gedrückt wird
> ...


Das *ist* die Lösung, weil Du die Tastaturwiederholung ja gar nicht brauchts in einem Spiel. Bei ersten KeyPressed kannst Du Dir Deinen Handler einhängen, mit dem Du die Taste als gedrückt merkst, erst beim KeyReleased-Event gibst Du sie wieder frei: solange die Taste als gedrückt markiert iwst, machst Du Deine Aktion 
Nur wie gesagt: unter Linux mußt Du dazu die Tastaturwiederholung ausschalten, denn sonst bekommst Du die ganze Zeit wieder Presser/Released-Paare und damit Änderungen des Tasten-Status, was insbesondere wieder die Verzögerung am Anfang verursacht. Unter Win32 dagegen nicht!


----------



## kopfsalat (20. Dez 2004)

:idea: 
Jetzt klingelt's. Ich hatte die Problematik bei Linux gar nicht erkannt. 

Tsja, dann werde ich mich wohl verabschieden von der Programmierung, wo man für jede Aktion ein eigenes KeyEvent nahm dahingehend, dass man nur noch einmal _an_ und nachher wieder _ab_schalten muss.
Hoffentlich wird dabei kein KeyReleased-Event verschluckt...


----------

