AWT.Robot & pressedKey

Status
Nicht offen für weitere Antworten.

Pharias

Mitglied
Hallo liebe Community,


Ich mache ein Projekt mit meinen freunden und wir benutzen den Robot. Er funktioniert generell bestens ,aber leider arbeitet er nicht so wie wir ihn brauchen.

Dabei nutzen wir hauptsächlich die Methoden
[HIGHLIGHT="Java"]
KeyPressed(int Keycode)
KeyReleased(int Keycode)
[/HIGHLIGHT]

Unser Problem haben wir mit der Methode:
[HIGHLIGHT="Java"]
KeyPressed(int Keycode)[/HIGHLIGHT]

Sie simuliert den Betriebsystem einen Tasdruck vor. Das funktioniert auch , nur wollen wir , wenn wir eine Taste drücken lassen wollen, nicht nur 1 mal drücken lassen, sondern die Tste soll gedrückt bleiben.

Alternative wäre natürlich , einfach die methode öfters ausführen um so den gedrückt halten effekt hervorzubringen. Aber klar ist , dass ein Spiel große unterschiede zwischen öfters drücken und gedrückt halten sieht.

Also dachte ich wird es wohl nötig sein , denn Roboter umzuschreiben
Ich habe die API nach dem Roboter gesucht. Dabei habe ich herausgefunden, dass der Robot ein Object von RobotPeer benutzt , welches er erzeugt mithilfe eines ComponentFactory , welches er sich holt von dem default Toolkits. ( also somit schon langsam betriebsystem orientiert).

Somit meine Frage
Gibt es eine andere Lösung als den Robot umzuschreiben? und wenn nicht , kann mir vielleicht jemand nähere hilfestellung geben?

Danke im Vorraus und auf gute Zusammenarbeitung.

mfg Pharias

ps: Nein , es muss in Java geschrieben werden.
 

Wildcard

Top Contributor
Alternative wäre natürlich , einfach die methode öfters ausführen um so den gedrückt halten effekt hervorzubringen. Aber klar ist , dass ein Spiel große unterschiede zwischen öfters drücken und gedrückt halten sieht.
Wenn die Methode eine Taste 'drücken' und 'loslassen' würde, wie du hier andeutest, würde sie keyType heißen. Tut sie aber nicht. Warum? Weil sie ein key pressed Event an das OS sendet, aber kein key released.
Dafür gibt es schließlich die keyRelease Methode.
Das war jetzt übrigens kein Geheimwissen, sondern steht ganz unversteckt in der API-Doc:
Presses a given key. The key should be released using the keyRelease method.
 

hdi

Top Contributor
Wildcard ich glaube nicht dass er das meint.

Er suchst eine Methode holdPressed().

Der Robot sendet zwar kein release, aber er sendet auch nur einmalig ein pressed.
Der TO will aber wohl, dass der Effekt ist als würde der Robot immer und immer wieder drücken.

@Topic:

Wenn der Robot dafür nix anbietet (kenne Robots nicht) musst du wohl die pressed-Methode
ändern.

Wie wärs mit:

[HIGHLIGHT="Java"]robotPressed(){
if (released){
released = false;
while( !released ){
doStuff();
// evtl. kurzes sleep
}
}
}[/HIGHLIGHT]

den boolean released machst du dir halt global, und ein gewisses Event setzt
den Wert, wenn du also möchtest dass der Robot aufhört "zu drücken".

Aber noch einfacher isses wohl, das von außen zu regeln. D.h. dort, wo
du die pressed-Methode aufrufst, kannst du dir zB schnell nen neuen Thread
machen der halt die Methode x mal bzw bis zu einer Abbruchbedingung erneut
aufruft.
Dann musst du am Robot selbst nicht rumfingern.

Meinst du sowas?
 

Wildcard

Top Contributor
Wildcard ich glaube nicht dass er das meint.
...
Der Robot sendet zwar kein release, aber er sendet auch nur einmalig ein pressed.
Der TO will aber wohl, dass der Effekt ist als würde der Robot immer und immer wieder drücken.
Ich wiederhole das Zitat noch mal:

Alternative wäre natürlich , einfach die methode öfters ausführen um so den gedrückt halten effekt hervorzubringen. Aber klar ist , dass ein Spiel große unterschiede zwischen öfters drücken und gedrückt halten sieht.
Die Behauptung war also, der Robot 'lässt die Taste los', was er aber nicht tut.
Also doch, genau das hat er gemeint, denn auf das 'immer und immer wieder drücken' kam der OP ja schon selbst.
 

Pharias

Mitglied
Danke für die Antwort ( ernstgemeint)
Du hast die theroie schön beantwortet, aber hast du auch schon mal praktisch die methode getestet?

Ich sage nich um sonst , dass sie zwar einwandfrei funktioniert aber nicht so wie erwartet.

Keypressed sollte ohne Released eine taste gedrückt halten. Das tut sie zwar, aber bei allen tasten auser den CTRL oder SHIFT oder ALT werden die tasten nicht gehalten.

Also für ein besseres verständnis ein Beispiel:

Ich drücke auf der Tastatur im Editor die taste A und halte sie ( also ohne loszulassen)
Ausgabe aaaaaaaaaaaa ( bis man wieder los lässt)

Ich lass vom robot die KeyEvent.VK_A drücken ohne Release ( also auch ohne loszulasen)
Ausgabe a ( nur eine ausgabe)

Lustigerweise funktionieren aber Kombinationen ohne probleme und halten auch an , wenn man sie nicht released.

Verstehst du?

mfg. Pharias


edit: boah bin ich langsam :D ...

Ich habe mir die robot klase genauer angeschaut und ich müsste alle Toolkits aufmachen und ihre keypressed umschreiben .. ( wenn ich das richtig verstehe) und das ist schwer weil , das benötigte ToolKit beim Konstruktor vom SunToolkits durch getproperty path geholt wird und per classloader geladen wird
 
Zuletzt bearbeitet:

hdi

Top Contributor
ja wie? Also wenn du die Methode nur 1x aufrufst ist das klar.
Siehe mein Posting weiter oben. Das musst du schon selber öfters machen.
Oder funktioniert auch das nicht?
 

Pharias

Mitglied
Wenn ich die methode neu aufrufe wäre das so als würde ich die taste A los lassen und neu aufrufen.

Bei spielen ist das nicht wirklich sehr brauchbar :(.


[HIGHLIGHT="Java"]public class JRobotTest {

public static void main(String[]args)
{
Robot rob;
try {

// test , das toolkit zu laden
// Toolkit asd2 = Toolkit.getDefaultToolkit();
// ((ComponentFactory)asd2).createRobot(new Robot(), GraphicsEnvironment.getLocalGraphicsEnvironment() .getDefaultScreenDevice())

rob = new Robot();
for(;;){
rob.keyPress(KeyEvent.VK_A);
}

} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}[/HIGHLIGHT]
 

Ebenius

Top Contributor
Ah... Der Themeneröffner möchte, dass sowas beim Opfer ankommt.
Code:
KEY_PRESSED
KEY_TYPED
KEY_TYPED
KEY_TYPED
KEY_TYPED
KEY_TYPED
KEY_TYPED
KEY_TYPED
...
KEY_RELEASED
Ich glaube, das wird mit nem Robot nix. :)

Ebenius
 

Wildcard

Top Contributor
Unterschiedliche Dinge. Modifier werden von Programmen in der Regel anders abgefragt als Zeichen mit sichtbarem Output. Wenn du keyPress aufrufst ist die Taste 'gedrückt' und bleibt auch 'gedrückt'.
Ich drücke auf der Tastatur im Editor die taste A und halte sie ( also ohne loszulassen)
Ausgabe aaaaaaaaaaaa ( bis man wieder los lässt)
Dein Betriebssystem (je nach Betriebssystem) emuliert Tastendrücke mit bestimmter Verzögerung für Tasten mit sichtbarem Output.
Da du mit 90%iger Wahrscheinlichkeit ein Windows Nutzer bist, dort findest du die Einstellung in der Systemsteuerung -> Tastatur -> Zeichenwiederholung.
Ich vermute die emuliert die Schnittstelle die mit der physikalischen Tastatur kommuniziert. Java hingegen postet ein Event in die Queue. Das Event ist das gleiche, aber hier fehlt der Controller der weitere Anschläge simuliert. Was würde der Controller tun? Genau das was du im Eingangsposting überlegt hast.
 

Pharias

Mitglied
Naja ich bin eher benutzer von allen drei betriebsystemen
Verstehe den letzten satz nicht

Genau das was du im Eingangsposting überlegt hast.

Andere frage kann man so einen Controller erstellen? :/

Danke für die ganzen Antworten und erst recht so schnell =) hoffe ich bekomme weiterhin Hilfe.

mfg Pharias
 
Zuletzt bearbeitet:

Wildcard

Top Contributor
Naja ich bin eher benutzer von allen drei betriebsystemen
Das freut zu hören :)
Was ich damit sagen will ist: Im Prinzip kannst du nur das tun was du schon angesprochen hast. In einer Schleife keyPress und keyRelease aufrufen, denn das würde auch das Betriebssystem tun. Allerdings solltest du sleep oder yield dazwischen einbauen
 

Pharias

Mitglied
^^, Das ist auch der Grund warum es in Java sein muss.

Wenn ich das richtig verstanden habe , heisst das, dass gedrückt halten, bei einem Betriebsystem nichts anderes heisst als erneutes keyPressed?... Aber ab welchen Delay?

Ich hatte ( so ähnlich wie der code hier) ein Prototypen geschrieben und an ein einfachen Spiel ausprobiert mit wasd steuerung. Dabei funktionierte nur das Springen , rechts links unten , funktionierte nicht. Heute wurde mir klar warum. Springen braucht nur ein Klick während links rechts ein gedrückt halten benötigt.

Wenn es stimmt , was du sagst brauch ich nur etwas herumexperiementen mit dem setAutoDelay();


Ich hatte auch eine andere idee, ich wollte mir die per classloader geladene Toolkit klasse in eine Datei speichern um so die "echte" implementierung ( für das jeweilige Betriebsystem) des pressedKey anschauen zu können. Dabei hatte ich die Hoffnung, dass ich dort dann pressedKey Alg. verstehe und selbst implementieren kann und so modifizieren kann wie ich es brauche. ( Aber vielleicht mehr aufwendig als notwendig)


Pharias


edit: Super ja es funktioniert =) also die alternative funktioniert doch
 
Zuletzt bearbeitet:

Wildcard

Top Contributor
Wenn ich das richtig verstanden habe , heisst das, dass gedrückt halten, bei einem Betriebsystem nichts anderes heisst als erneutes keyPressed?... Aber ab welchen Delay?
Das Delay wird im Betriebssystem festgelegt. Eine einfache Möglichkeit es auszulesen kenne ich allerdings nicht.
Aber schön das dein Problem gelöst ist.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben