JavaFX FXML控制器键处理程序代码无效

3

我在使用FXML和keyPress事件处理器时遇到了问题。

我尝试设置一个简单的按键事件处理器,但是该处理器并没有被调用。鼠标事件处理等都能够正确处理,但是按键事件处理却不能。

我曾经在Pane、Pane中的circle以及scene上设置过按键事件处理器。

public class Controller implements Initializable {
    public Pane canvas;
    public Label yDisplay;
    public Label xDisplay;
    public Circle circle;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        canvas.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent keyEvent) {
                System.out.println("Test");
            }
        });
    }
}

尊敬的Dil,谢谢您的回答,但我想做一些“游戏”,在屏幕上有一个简单的圆圈,通过按键盘上的按键移动。当然,要关注组件才能工作。但是没有焦点。也许键监听器必须设置在窗口或场景上?对于目的的模糊性,我深感歉意。

我尝试在按下时设置,但场景在初始化时为空。

public class Controller implements Initializable {
    @FXML private Pane canvas;
    @FXML private Label yDisplay;
    @FXML private Label xDisplay;
    @FXML private Circle circle;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        canvas.getScene().setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent keyEvent) {
                System.out.println("Work");
            }
        });
        canvas.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                canvas.getChildren().add(new Bullet(150.0, 150.0, mouseEvent.getX(), mouseEvent.getY()));
            }
        });
    }
}

这是一个逻辑问题,我尝试在Application类中设置键处理程序。将键处理程序设置在Application上可以实现,但如何获取场景中的Circle和其他组件,因为它们保存在controller.class中。

  @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root));
        primaryStage.getScene().setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent keyEvent) {
                System.out.println("HEY");
            }
        });
        primaryStage.show();
    }

现在我试图通过查找场景/父根来完成它。

是的!查找父级是有效的。我只需要通过# +“id”进行搜索即可。

 @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root));
        primaryStage.getScene().setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent keyEvent) {
                System.out.println("HEY");
                Circle myCirecle = (Circle) root.lookup("#circle");
                myCirecle.setTranslateY(10.0);
            }
        });
        primaryStage.show();
    }

1
你可以使用lookup方法来获取圆形,但是有一种标准的方法来实现。在控制器中编写getter方法以获取Circle(例如:getCircle())。使用getController API从fxmlLoader获取控制器。然后使用getCircle方法即可获取圆形。 - Dil
1个回答

5

您的代码没有问题。我已经测试了这段代码,并且在没有任何更改的情况下,它对我起作用了。问题可能出在您的使用上。为什么要将KeyPress监听器添加到整个面板而不是一些组件上?除非选择了容器/面板,否则无法识别按键。 在fxml中添加一个TextField以检查是否识别到按键,如下:

 @FXML
private TextField testTextField;

并在initialize()函数内添加以下代码

testTextField.setOnKeyPressed(new EventHandler<KeyEvent>() {

        @Override
        public void handle(KeyEvent arg0) {
            // TODO Auto-generated method stub
            System.out
                    .println("MyController.initialize().new EventHandler() {...}.handle()");

        }
    });

注意:您应该在fxml中添加文本字段,而不仅仅是在控制器中添加上述代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接