I work on a small tool for a game something like hotkey which handle a combination of user key press event and simulate with Awt Robot a couple of key press. The problem is that called method ghostWalk() work as expected only first time when registered combination is pressed, second time when I press the same combination and the same method are called only the last key is simulated which is after "robot.delay". pls read more from code comment.
import com.melloware.jintellitype.HotkeyListener;
import com.melloware.jintellitype.JIntellitype;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
public class L {
int i = 160;
public static void main(String args[]){
L l = new L();
l.k();
}
public void k(){
// Register keys combination
JIntellitype.getInstance();
JIntellitype.getInstance().registerHotKey(1, JIntellitype.MOD_ALT, (int)'D');
JIntellitype.getInstance().registerHotKey(2, JIntellitype.MOD_ALT, (int)'J');
JIntellitype.getInstance().registerHotKey(3, JIntellitype.MOD_ALT, (int)'K');
JIntellitype.getInstance().addHotKeyListener(new HotkeyListener() {
public void onHotKey(int aIdentifier) {
// First indentifier Alt + D
if (aIdentifier == 1) {
System.out.println("Alt+D hotkey pressed");
// Start new thread
new Thread(new Runnable() {
@Override
public void run() {
L gh = new L();
gh.ghostWalk();
}
}).start();
}
// Second indetifier
else if(aIdentifier == 2){
i += 10;
System.out.println(i);
}
// Third
else if(aIdentifier == 3){
i -= 10;
System.out.println(i);
}
}
});
}
// Method called to simulate key press
/* So, first time when i press Alt + D in game after program runs
all work good, the keys are simulated as expected but if I press again and again
the combination only key "d" are simulated which is after "delay(i), i = 160"
If program is restarted all again is the same, only first time when i press registered
combinations the program work as expected.
Second and others times program work only if there is delay "robot = new Robot();
robot.delay(100);"
on 100 delay program work well on 40ms need to press very fast the combination
so the program work as expected. How to fix it ? to simulate key press without
delay like first time when program is run.
P.s no matter in which window(game, notepad) you press combination to simulate key press
still work good only first time.
Example of output when i press two times combinations in game
first time: qqwewwd
second time: d
*/
public void ghostWalk(){
Robot robot = null;
try {
robot = new Robot();
//robot.delay(100);
robot.keyPress(KeyEvent.VK_Q);
robot.keyRelease(KeyEvent.VK_Q);
robot.keyPress(KeyEvent.VK_Q);
robot.keyRelease(KeyEvent.VK_Q);
robot.keyPress(KeyEvent.VK_W);
robot.keyRelease(KeyEvent.VK_W);
robot.keyPress(KeyEvent.VK_R);
robot.keyRelease(KeyEvent.VK_R);
robot.keyPress(KeyEvent.VK_W);
robot.keyRelease(KeyEvent.VK_W);
robot.keyPress(KeyEvent.VK_W);
robot.keyRelease(KeyEvent.VK_W);
robot.delay(i);
robot.keyPress(KeyEvent.VK_D);
robot.keyRelease(KeyEvent.VK_D);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Edit: I can't understand what changes are made after first calling ghostWalk method that I should to use delay so my program work as expected.
Edit2: In my case code start to work when setAutoWaitForIdle
was set to true and delay
= 5 (delay before start to simulate keypress) also if between
keypress is a delay like in my case delay(i), i = 160 then start delay should be 60~. (if start delay is 40~ then not always work good, need very fast to press registered keys combination idk why, also if start delay is less than 40-60 in my case is simulated only last keypress "D" which is after delay(i).)
If to delete robot.setAutoWaitForIdle(true)
and robot.delay(60)
on first registered hotkey event the tool will work as expected, on second, third etc times - not. After first JIntellitype event work only this code.
public void ghostWalk(){
Robot robot = null;
try {
robot = new Robot();
robot.setAutoWaitForIdle(true);
robot.delay(60);
robot.keyPress(KeyEvent.VK_Q);
robot.keyRelease(KeyEvent.VK_Q);
robot.keyPress(KeyEvent.VK_Q);
robot.keyRelease(KeyEvent.VK_Q);
robot.keyPress(KeyEvent.VK_W);
robot.keyRelease(KeyEvent.VK_W);
robot.keyPress(KeyEvent.VK_R);
robot.keyRelease(KeyEvent.VK_R);;
robot.delay(i);
robot.keyPress(KeyEvent.VK_D);
robot.keyRelease(KeyEvent.VK_D);
} catch (Exception e) {
e.printStackTrace();
}
}
You should consider setting an auto-delay using setAutoDelay.
It's quite possible your OS has problems handling input events if they're posted without delay. Try with 50 ms or 25ms delay, see what happens.
Another thing you can try is add
waitForIdle()
before each key press.EDIT: For sports I tried the JIntelliType library out, and the following snippet works relatively well. I tested pressing the hotkey out in Notepad++ (
ctrl-Q
) and it consistently prints outtt rocks
. However I had to release the hotkey fast, otherwise Notepad++ started interpreting the hotkey as something else (ctrl-Q
is already a shortcut for something else in Notepad++).Using a robot is not exact science. I had to delay the robot for 150 ms and then
waitForIdle
before letting the robot press keys. Otherwise things got screwed up. Setting auto delay was not necessary.