dani.nykh
dani.nykh

Reputation: 37

Holding a physical key then using awt.Robot to auto press that same key in Java

I am using JNativeHook in my program to detect global key strokes that are outside my program. This is what I need to accomplish:

when I try to physically press and hold the space bar, and before I physically release the space bar: I want to use the awt.Robot class to auto press the space bar for me in a loop while the space bar is physically pressed.

My theory to the problem is that the JNativeHook NativeKeyListener understands the awt.Robot keyRelease() function as if it was a physical key release (in this case the space bar.)

Here is the relevant code:

// These are the global variables
// ...
Robot robot;  // Initialized in the constructor
// ...
boolean spaceDown = false;
boolean activeThread = false;

private void pressSpace(){

    robot.keyPress(KeyEvent.VK_SPACE);
    robot.delay(20);
    robot.keyRelease(KeyEvent.VK_SPACE);
    robot.delay(30);

    System.out.println("Robot - Press/Release");

}

private void executeThread(){

    new Thread(){
        public void run(){
            while(spaceDown){
                pressSpace();
            }
            activeThread = false;
        }
    }.start();

}

public void nativeKeyPressed(NativeKeyEvent e){

    if(e.getKeyCode() == NativeKeyEvent.VC_SPACE){

        System.out.println("Physical - Pressed");

        activeThread = true;
        spaceDown = true;
        if(activeThread){
            executeThread();
        }
    }

}
public void nativeKeyReleased(NativeKeyEvent e){

    if(e.getKeyCode() == NativeKeyEvent.VC_SPACE){
        System.out.println("Physical - Released");
        spaceDown = false;
    }

}

After running this program, when I press the space key and then release OR if I hold it. I get the same output each time in the console. It generally looks like this...

...
Physical - Pressed
Physical - Released
Robot - Press/Release
Physical - Pressed
Physical - Released
Robot - Press/Release
...

Any ideas?

Upvotes: 0

Views: 433

Answers (1)

Alex Barker
Alex Barker

Reputation: 4400

I am not sure why you are trying to do that... When you hold down a key, after the repeat delay has passed, you basically get a key down even at the repeat rate until you release. If you want to simulate a key bounce, where the key is pressed and then released, instead of a key down event being repeated:

// These are the global variables
public void nativeKeyPressed(NativeKeyEvent e){

    if(e.getKeyCode() == NativeKeyEvent.VC_SPACE){

        System.out.println("Physical - Pressed");

        // This should produce a key release event.
        GlobalScreen.postNativeEvent(new NativeKeyEvent(
            NativeKeyEvent.NATIVE_KEY_RELEASED, 
            e.getWhen(), 
            e.getModifiers(), 
            e.getRawCode(), 
            e.getKeyCode, 
            e.getKeyChar(), 
            e.getKeyLocation()));
    }

}

Your example above has a lot of thread safety issues which is probably why you have an issue.

Upvotes: 1

Related Questions