KeyEvents和Focus JavaFX

KeyEvents和Focus JavaFX,java,javafx,keyevent,Java,Javafx,Keyevent,我现在非常困惑。 我在fxml代码中创建了一个窗格,并设置了一个onKeyPressed事件 pane.setOnKeyPressed(new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent event) { System.out.println( "I'm here"); jump( event); } }); 当我点击按钮时,它打印出了我的窗格中应有的

我现在非常困惑。 我在fxml代码中创建了一个窗格,并设置了一个onKeyPressed事件

pane.setOnKeyPressed(new EventHandler<KeyEvent>() {
   @Override
   public void handle(KeyEvent event) {
       System.out.println( "I'm here");
       jump( event);
   }
});
当我点击按钮时,它打印出了我的窗格中应有的场景。但后来,我意识到我的窗格现在捕捉到了关键事件。除了使用Fxml添加一个按钮外,我没有做任何更改,现在窗格捕捉到KeyEvents?当我注释掉按钮的代码时,窗格不再捕捉KeyEvents

<Button onAction="#printScene"/>

取消注释按钮使窗格获得焦点,反之亦然。

这是我在这个网站上的第一个答案,所以我可能不会很好地回答你

无论如何,我认为错误是在应用窗格上的事件,请尝试在场景上应用它


编辑:我看到您使用了
窗格。getScene()
;你没有场景对象吗?

这是我在这个网站上的第一个答案,所以我可能不会很好地回答你

无论如何,我认为错误是在应用窗格上的事件,请尝试在场景上应用它



编辑:我看到您使用了
窗格。getScene()
;您没有场景对象?

不确定为什么添加按钮会使窗格获得焦点,或者为什么
pane.requestFocus()
不起作用(您需要发布一条消息才能得到答案)。最好的方法是在场景中注册一个监听器,您可以在创建场景的地方注册监听器。在这一点上,也应该可以获得对控制器的引用,因此您可以从处理程序调用控制器上的方法。我将尽快发布所有代码,谢谢您的帮助。我还在initialize()方法中调用了requestFocus,也许这就是它不起作用的原因?@James\u D我已经发布了全部代码。如果你能看一看我会很高兴的是的,这很奇怪。我知道创建控件实例将强制加载CSS。我想知道是否出于某种原因,
requestFocus()
不起作用,除非节点是场景的一部分或者CSS已加载-我必须仔细阅读源代码以确定这是不是真的。更安全的做法似乎是在现场注册处理程序。感谢您的回复!不确定为什么添加按钮会使窗格获得焦点,或者为什么
pane.requestFocus()
不起作用(您需要发布一个帖子才能得到答案)。最好的方法是在场景中注册一个监听器,您可以在创建场景的地方注册监听器。在这一点上,也应该可以获得对控制器的引用,因此您可以从处理程序调用控制器上的方法。我将尽快发布所有代码,谢谢您的帮助。我还在initialize()方法中调用了requestFocus,也许这就是它不起作用的原因?@James\u D我已经发布了全部代码。如果你能看一看我会很高兴的是的,这很奇怪。我知道创建控件实例将强制加载CSS。我想知道是否出于某种原因,
requestFocus()
不起作用,除非节点是场景的一部分或者CSS已加载-我必须仔细阅读源代码以确定这是不是真的。更安全的做法似乎是在现场注册处理程序。感谢您的回复!我知道窗格没有焦点,这就是我请求焦点的原因,但这不起作用。在场景中应用它会起作用,但我想知道的是,为什么它会从添加按钮开始工作。尝试在创建按钮之前和之后打印窗格内容。在创建按钮之前,可能场景没有真正初始化。除了使窗格失去焦点之外,没有任何注释。直到
fxmloader.load()
完成执行之后,
场景
才创建,因此在initialize方法中它将为
null
。这里的基本思想是正确的:在场景中注册处理程序,但您需要在
start
方法中注册,而不是在控制器中注册。我知道窗格没有焦点,这就是我请求焦点的原因,这不起作用。在场景中应用它会起作用,但我想知道的是,为什么它会从添加按钮开始工作。尝试在创建按钮之前和之后打印窗格内容。在创建按钮之前,可能场景没有真正初始化。除了使窗格失去焦点之外,没有任何注释。直到
fxmloader.load()
完成执行之后,
场景
才创建,因此在initialize方法中它将为
null
。这里的基本思想是正确的:在场景中注册处理程序,但需要在
start
方法中注册,而不是在控制器中注册。
<Button onAction="#printScene"/>
public class Main extends Application {

@Override
public void start(Stage primaryStage) throws Exception{
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("sample.fxml"));
    Parent root = fxmlLoader.load();
    Scene scene = new Scene( root, 800, 600);
    primaryStage.setTitle("Game");
    primaryStage.setScene( scene);
    primaryStage.show();


}

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

public class Controller {

@FXML private Pane pane;
@FXML private Rectangle cube;

public void initialize() {
    pane.requestFocus();
    pane.setFocusTraversable( true);
    pane.setOnKeyPressed(new EventHandler<KeyEvent>() {
        @Override
        public void handle(KeyEvent event) {
            System.out.println( "I'm here");
            jump( event);
        }
    });
    System.out.println( pane.getScene());
}
}

//FXML Code
<Pane fx:controller="sample.Controller" fx:id="pane"
  xmlns:fx="http://javafx.com/fxml">

<Rectangle width="800" height="20" layoutY="580" fill="green"/>
<Rectangle fx:id="cube" width="40" height="40" layoutX="5" layoutY="540"/>
<!--<Button />-->
</Pane>