2
votes

I am trying to create a GUI environment using JavaFX (still at a very early stage), I've implemented the EventHandler, the MouseEvent works fine, but the KeyEvent does not seem to be working for some reasons. I already called setOnKeyPressed, setOnKeyTyped, etc. in the constructor, so theoretically it should work. But I couldn't see what is actually causing the problem.

GUI.java

import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import java.util.ArrayList;

/**
 * @author JAY
 */
public class GUI extends Pane implements EventHandler<Event>{

    private boolean up = false;
    private boolean down = false;
    private boolean left = false;
    private boolean right = false;
    private boolean spacebar = false;
    private boolean shift = false;
    private boolean ctrl = false;

    private double mouseX;
    private double mouseY;

    public GUI(int width, int height) {
        super();
        setStyle("-fx-background-color: black;");
        setPrefSize(width, height);

        ArrayList<Node> things = new ArrayList<>();
        getChildren().addAll(things);

        setOnKeyPressed(this);
        setOnKeyTyped(this);
        setOnKeyReleased(this);

        setOnMouseMoved(this);
        setOnMouseClicked(this);
        setOnMouseDragged(this);
    }

    @Override
    public void handle(Event event) {
        System.out.println(event.getEventType().toString());

        if(event instanceof KeyEvent) {
            if(event.getSource() == getOnKeyPressed()) {
                keyPressed((KeyEvent) event);
            }
            if(event.getSource() == getOnKeyReleased()) {
                keyReleased((KeyEvent) event);
            }

            System.out.println(((KeyEvent) event).getCode());
        }
        if(event instanceof MouseEvent) {
            if(event.getSource() == getOnMouseMoved()) {
                mouseMoved((MouseEvent) event);
            }

            System.out.println("mouse at x: " + mouseX + " y: " + mouseY);
        }
    }

    public void mouseMoved(MouseEvent e) {
        mouseX = e.getX();
        mouseY = e.getY();
    }

    public void keyPressed(KeyEvent e) {
        KeyCode code = e.getCode();

        if (code == KeyCode.UP)
            up = true;
        if (code == KeyCode.DOWN)
            down = true;
        if (code == KeyCode.LEFT)
            left = true;
        if (code == KeyCode.RIGHT)
            right = true;
        if (code == KeyCode.SPACE)
            spacebar = true;
        if (code == KeyCode.SHIFT)
            shift = true;
        if (code == KeyCode.CONTROL)
            ctrl = true;
    }

    public void keyReleased(KeyEvent e) {
        KeyCode code = e.getCode();

        if (code == KeyCode.UP)
            up = false;
        if (code == KeyCode.DOWN)
            down = false;
        if (code == KeyCode.LEFT)
            left = false;
        if (code == KeyCode.RIGHT)
            right = false;
        if (code == KeyCode.SPACE)
            spacebar = false;
        if (code == KeyCode.SHIFT)
            shift = false;
        if (code == KeyCode.CONTROL)
            ctrl = false;
    }

}

Main.java

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;

/**
 * @author JAY
 */
public class Main extends Application {

    private GUI arena = new GUI(600, 600);

    public void start(Stage primaryStage) {
        primaryStage.setTitle("My GUI");
        primaryStage.setScene(new Scene(arena));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}
2

2 Answers

1
votes

As @Francis Fredrick Valero said, is the scene the one that receives those key events.

In your main->start method you could do:

primaryStage.setTitle("My GUI");
Scene scene = new Scene(arena);
scene.setOnKeyPressed(arena);
primaryStage.setScene(scene);
primaryStage.show();
0
votes

The Scene receives the event. Can you try this instead?

getScene().setOnKeyPressed(this);