JavaFX KeyEvent не срабатывает

Я пытаюсь создать среду с графическим интерфейсом с помощью JavaFX (все еще на очень ранней стадии), я реализовал EventHandler, MouseEvent работает нормально, но KeyEvent по некоторым причинам не работает. Я уже вызывал setOnKeyPressed, setOnKeyTyped и т.д. в конструкторе, так что теоретически должно работать. Но я не мог видеть, что на самом деле вызывает проблему.

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);
    }

}

person Jay Feng    schedule 15.08.2015    source источник


Ответы (2)


Как сказал @Francis Fredrick Valero, именно сцена получает эти ключевые события.

В вашем методе main- > start вы можете сделать:

primaryStage.setTitle("My GUI");
Scene scene = new Scene(arena);
scene.setOnKeyPressed(arena);
primaryStage.setScene(scene);
primaryStage.show();
person Suicide Platypus    schedule 15.08.2015
comment
Спасибо, это сработало для меня сейчас. Я должен был заметить раньше, потому что позже понял, что в Swing прослушиватель ключей реализуется в JFrame, а не в JPanel. Следовательно, должно быть то же самое в JavaFX. Спасибо за помощь! - person Jay Feng; 15.08.2015

Сцена получает событие. Можете ли вы попробовать это вместо этого?

getScene().setOnKeyPressed(this);
person Francis Fredrick Valero    schedule 15.08.2015
comment
Это не сработает, потому что когда вы создаете экземпляр GUI, сцена еще не создана. - person Suicide Platypus; 15.08.2015