【问题标题】:KeyEvents and Focus JavaFXKeyEvents 和焦点 JavaFX
【发布时间】:2017-04-08 13:39:20
【问题描述】:

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

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

这不起作用。 Pane 没有捕捉到任何 KeyEvent。从未打印过“我在这里”。 然后我想设置场景的onKeyPressed,它可以工作,但我必须在控制器中完成,因为我想要在按键期间处理的事情必须在控制器中完成。

然后我打电话给pane.getScene().setOnKeyPressed(),但结果却是nullPointerException,因为我发现我必须在initialize()之外打电话。

所以我创建了一个 Button 并为其附加了一个 onAction 事件,它会打印出我的窗格中的场景,以尝试它是否真的有效。

@FXML
public void printScene() {
    System.out.println( pane.getScene());
}

当我单击按钮时,它会打印出我的窗格中的场景,因为它应该有。但是后来,我意识到我的窗格现在可以捕获 KeyEvents。除了使用 Fxml 添加一个按钮之外,我什么都没改变,现在窗格捕获 KeyEvents?当我注释掉按钮的代码时,窗格不再捕获 KeyEvents

<Button onAction="#printScene"/>

这是我所有的按钮代码。

注意:我也尝试了pane.requestFocus()pane.SetFocusTraversable( true),但也没有用。但是突然添加一个按钮就可以了?我很困惑。

整个代码:

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>

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

【问题讨论】:

  • 不知道为什么添加按钮会给窗格带来焦点,或者为什么pane.requestFocus() 不起作用(您需要发布minimal reproducible example 才能得到答案)。最好的方法是在场景中注册一个侦听器,您可以在创建场景的地方执行此操作。此时应该也可以获取对控制器的引用,因此您可以从处理程序调用控制器上的方法。
  • 我会尽快发布所有代码,感谢您的帮助。我还在 initialize() 方法中调用了 requestFocus,也许这就是它不起作用的原因?
  • @James_D 我已经发布了整个代码。如果你能看一下我会很高兴^^
  • 是的,这很奇怪。我知道创建控件实例会强制加载 CSS。我想知道是否出于某种原因requestFocus() 不起作用,除非该节点是场景的一部分或已加载 CSS - 我将不得不深入研究源代码以确定这是否属实。无论如何,更安全的做法似乎是在现场注册处理程序。
  • 感谢您的回复!

标签: java javafx keyevent


【解决方案1】:

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

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

编辑:我看到你使用pane.getScene();你没有场景对象?

【讨论】:

  • 我知道窗格没有焦点,这就是我请求焦点的原因,但这没有用。将它应用到场景中会起作用,但我想知道为什么它开始使用添加按钮。
  • 尝试在按钮创建前后打印窗格内容。在您创建 Button 之前,场景可能并没有真正初始化。
  • 只评论 会使窗格失去焦点。
  • scene 直到 FXMLLoader.load() 完成执行后才被创建,因此在初始化方法中它将是 null。这里的基本思路是正确的:在场景中注册handler,但是需要在start方法中进行,而不是在控制器中。
猜你喜欢
  • 2015-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
  • 1970-01-01
相关资源
最近更新 更多