gpt4 book ai didi

java - 避免不在 FX 应用程序线程上导致 UI 崩溃

转载 作者:行者123 更新时间:2023-12-02 10:41:57 25 4
gpt4 key购买 nike

我正在使用 JavaFX 制作一个基于分步的游戏,并使用 do while 循环来等待用户输入。问题是,它是从 fxml Controller 初始化方法调用的,这意味着该界面永远不会加载。解决方案是使用另一个线程等待,但 JavaFX 不允许从辅助线程修改任何节点。

我通过使用以下代码避免了“不在 FX 应用程序线程上”:

public void initialize(URL arg0, ResourceBundle arg1) {
// I call the game engine to start the game sequence and I pass root into it for further use
engine = new GameEngine(root);

Platform.runLater(new Runnable() {
@Override
public void run() {
engine.start();
}
});
}

engine.start() 方法内部:

public void start() {
System.out.println("Game started");
text("Hello, stranger"); // a new Label inside VBox
do {
try {
Thread.sleep((long) 1000);
System.out.println("Sleeping...");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Error... waiting?");
}
} while(this.listener == false); // Listener triggers when user inputs.

System.out.println("ENTER PRESSED, May proceed");
text("It worked!");
}

此外,GameEngine 扩展了 Thread,我不知道它如何影响多线程之外的其他内容。

当代码启动时,UI 崩溃并且输出每秒都在 Sleeping...,就像它应该的那样。

最佳答案

您不能在 JavaFX 应用程序线程上调用 Thread.sleep() 和/或 while 循环,因为这将导致 GUI 停止并等待循环结束。

The solution is to wait using another thread, but JavaFX doesn't allow to modify any nodes from secondary threads.

是的,您不应该从非 JavaFX 应用程序线程修改场景图,但这并不能阻止您为代码行调用 Platform.runLater()进行实际的修改。您还可以使用Task来实现这一目标。

很难提供任何具体的解决方案,因为我不知道 listener 标志是如何更新的。

编辑

我没有注意到 start() 方法属于 Thread 子类,直到 fabian 指出。你永远不应该重写Thread.start(),更糟糕的是,当你重写它时不要调用super.start()

所以这里发生的事情是您的 GameEngine 类不再像 Thread 一样工作。调用 engine.start() 只需执行您在调用 engine.start() 的线程(恰好是 JavaFX 应用程序线程,因为您已将其包装在 Platform.runLater() 中。

如果您仍然希望扩展Thread,那么您应该移动代码以覆盖Thread.run()。另请注意,您应该删除 initialize() 中的 Platform.runLater(),并将其放置在任何会影响 GUI 的代码中。

例如:

Platform.runLater(() -> {
myLabel.setText("User typed" + input);
});

关于java - 避免不在 FX 应用程序线程上导致 UI 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52864637/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com