Search code examples
javarobotframeworkenter

Java Robot doesnt Press Enter Key how it should


Im trying to program a litte Robot, that should just write for some hours the same phrase with a delay.

But somehow, if i have mor than 1 Letter at the same time before the Enter Key, it rather types a Pyramide.

For Example, if i wanna print "ted", it prints the following:

ted

tedted

tedtedted

tedtedtedted

[...]

(There is no empty line between the Pyramide-Lines)

It gets really frustrating.

I Tried many solutions, but none worked. Making a Delay for the robot, an extra Robot for the Enter Key, put it in an extra Thread or creating new Robots every time before a new Typing. It just doesnt work. What am i doing wrong? Here is a SSCCE with some trys i did:

@SuppressWarnings("CallToPrintStackTrace")
public class RobotTest {

private static Robot robo;
private static Robot okRobo;

static {
    createRobos();
}

private static void createRobos(){
    try {
        robo = new Robot();
        okRobo = new Robot();
    } catch (AWTException ex) {
        ex.printStackTrace();
    }
}

@SuppressWarnings({"CallToPrintStackTrace", "SleepWhileInLoop"})
public static void main(String[] args) throws InterruptedException {
    Thread.sleep(5000);
    for (int i = 0; i < 16; i++) {
        createRobos();
        perform();
//            Thread.sleep(500);
        performOk();
    }
}

private static void perform() {
    robo.keyPress(KeyEvent.VK_SHIFT);
    robo.keyPress(KeyEvent.VK_1);
    robo.keyRelease(KeyEvent.VK_SHIFT);
    robo.keyRelease(KeyEvent.VK_1);
    robo.keyPress(KeyEvent.VK_B);
    robo.keyRelease(KeyEvent.VK_B);
    robo.keyPress(KeyEvent.VK_O);
    robo.keyRelease(KeyEvent.VK_O);
    robo.keyPress(KeyEvent.VK_O);
    robo.keyRelease(KeyEvent.VK_O);
    robo.keyPress(KeyEvent.VK_S);
    robo.keyRelease(KeyEvent.VK_S);
    robo.keyPress(KeyEvent.VK_T);
    robo.keyRelease(KeyEvent.VK_T);
    robo.keyPress(KeyEvent.VK_E);
    robo.keyRelease(KeyEvent.VK_E);
    robo.keyPress(KeyEvent.VK_D);
    robo.keyRelease(KeyEvent.VK_D);
//        robo.waitForIdle();
}

private static void performOk() {
    okRobo.keyPress(KeyEvent.VK_ENTER);
    okRobo.keyRelease(KeyEvent.VK_ENTER);
//        okRobo.waitForIdle();
}

}

And here is my first try, that should work in my opinion too, but it doesnt:

public class RobotTest {

private static Robot robo;

@SuppressWarnings("CallToPrintStackTrace")
static {
    try {
        robo = new Robot();
    } catch (AWTException ex) {
        ex.printStackTrace();
    }
}

public static void main(String[] args) throws InterruptedException {
    Thread.sleep(5000);
    for (int i = 0; i < 16; i++) {
        perform();
    }
}

private static void perform() {
    robo.keyPress(KeyEvent.VK_SHIFT);
    robo.keyPress(KeyEvent.VK_1);
    robo.keyRelease(KeyEvent.VK_SHIFT);
    robo.keyRelease(KeyEvent.VK_1);
    robo.keyPress(KeyEvent.VK_B);
    robo.keyRelease(KeyEvent.VK_B);
    robo.keyPress(KeyEvent.VK_O);
    robo.keyRelease(KeyEvent.VK_O);
    robo.keyPress(KeyEvent.VK_O);
    robo.keyRelease(KeyEvent.VK_O);
    robo.keyPress(KeyEvent.VK_S);
    robo.keyRelease(KeyEvent.VK_S);
    robo.keyPress(KeyEvent.VK_T);
    robo.keyRelease(KeyEvent.VK_T);
    robo.keyPress(KeyEvent.VK_E);
    robo.keyRelease(KeyEvent.VK_E);
    robo.keyPress(KeyEvent.VK_D);
    robo.keyRelease(KeyEvent.VK_D);
    robo.keyPress(KeyEvent.VK_ENTER);
    robo.keyRelease(KeyEvent.VK_ENTER);
    robo.delay(500);
}

Solution

    1. Try not to initialize your Robot at each iteration of the loop. Call createRobos() outside of the loop. That is unless you have a specific reason that you're doing it that way.
    2. I don't think you need two separate instances of Robot to get this to work.
    3. Instead of using Thread.sleep(), you can use the delay() method within the Robot class. This is if you want to add a delay between Robot method calls.

    You may want to try to add a delay between when you're typing out the letter keys and when you're pressing the enter key and after you press the enter key. A 50 - 100 ms delay will usually do the trick. Sometimes, things get a little messed up, especially when you throw Thread.sleep() into the mix.

    I ran your code with these small changes and it seemed to work fine.