GoXR3Plus GoXR3Plus - 2 months ago 9
Java Question

JavaFX Detect mutliple keyboard keys pressed simultaneously

As the title is saying I want to detect multiple keyboard keys pressed at the same time (simultaneously) and are being pressed (simultaneously) for a time period. I am trying to add multiple event handlers on the

Scene
but it doesn't work:

EventHandler<KeyEvent> handler1 = key -> {
//logic1 here
}

EventHandler<KeyEvent> handler2 = key -> {
//logic1 here
}

getScene().addEventHandler(KeyEvent.KEY_PRESSED, handler1);
getScene().addEventHandler(KeyEvent.KEY_PRESSED, handler2);


Why I want to do this:

I have some code and I want to resize a rectangle based on the
keyboard keys
pressed by the user.For example if the user is pressing
RIGHT ARROW
the rectangle is increasing to from right side and if the user is pressing
UP ARROW
the rectangle is increasing from the top side.

The problem:

But when the user is pressing [
RIGHT ARROW
] and [
UP ARROW
] simultaneously and keeping them pressed,the two actions above must happen together,and not only one of them.

Answer

Just manipulate some boolean properties:

private BooleanProperty upPressed = new SimpleBooleanProperty();
private BooleanProperty rightPressed = new SimpleBooleanProperty();

private BooleanBinding anyPressed = upPressed.or(rightPressed);

// ...

getScene().setOnKeyPressed(e -> {
    if (e.getCode() == KeyCode.UP) {
        upPressed.set(true);
    }
    if (e.getCode() == KeyCode.RIGHT) {
        rightPressed.set(true);
    }
});

getScene().setOnKeyReleased(e -> {
    if (e.getCode() == KeyCode.UP) {
        upPressed.set(false);
    }
    if (e.getCode() == KeyCode.RIGHT) {
        rightPressed.set(false);
    }
});

If both keys are pressed simultaneously, both properties will be true, so you can register listeners with the boolean properties, or check them in an AnimationTimer as you need, e.g.:

double delta = .. ;

AnimationTimer timer = new AnimationTimer() {
    @Override
    public void handle(long timestamp) {
        if (upPressed.get()) {
            rect.setY(rect.getY()-delta);
            rect.setHeight(rect.getHeight() + delta);
        }
        if (rightPressed.get()) {
            rect.setWidth(rect.getWidth() + delta);
        }
    }
};

anyPressed.addListener((obs, wasPressed, isNowPressed) -> {
    if (isNowPressed) {
        timer.start();
    } else {
        timer.stop();
    }
});