gpt4 book ai didi

multithreading - 如何从我自己的线程安全地修改 JavaFX GUI 节点?

转载 作者:行者123 更新时间:2023-12-03 00:58:42 33 4
gpt4 key购买 nike

我尝试更改线程中的 JavaFX GUI 节点,但看到以下错误:

Exception in thread "Thread-8" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-8

生成错误的示例代码:

public class Controller { 
public Label label = new Label();

public void load() {
MyThread myThread = new MyThread();
myThread.start();
}

public class MyThread extends Thread {
public void run() {
......
label.setText(""); // IllegalStateException: Not on FX application thread
}
}
}

最佳答案

事件场景图中 JavaFX 节点的所有操作都必须在 JavaFX 应用程序线程上运行,否则您的程序可能无法正常工作。

当您尝试在 JavaFX 应用程序线程外修改场景图节点的属性时,JavaFX 将抛出异常 IllegalStateException:不在 FX 应用程序线程上。即使您没有收到 IllegalStateException,您也不应该在 JavaFX 应用程序线程之外修改场景图节点,因为如果您这样做,您的代码可能会意外失败。

使用Platform.runLater()

将操作场景图节点的代码包装在 Platform.runLater 中调用以允许 JavaFX 系统在 JavaFX 应用程序线程上运行代码。

例如,您可以使用以下代码修复示例程序:

Platform.runLater(() -> label.setText(""));

使用带有 message 属性的 Task 的替代方案

如果您使用的是 JavaFX Task ,它对使用 JavaFX 进行并发编程有一些内置支持,那么您可以利用它的 message属性,可以从任何线程安全地更新,但只会在 JavaFX 线程上中继属性更改。

这是一个示例(来自任务 javadoc):

Task<Integer> task = new Task<Integer>() {
@Override protected Integer call() throws Exception {
int iterations;
for (iterations = 0; iterations < 10000000; iterations++) {
if (isCancelled()) {
updateMessage("Cancelled");
break;
}
updateMessage("Iteration " + iterations);
updateProgress(iterations, 10000000);
}
return iterations;
}
};

然后,您可以安全地绑定(bind)到消息属性,以使更改的消息值反射(reflect)在 UI 中:

Label iterationLabel = new Label();
iterationLabel.textProperty().bind(
task.messageProperty()
);

updateMessage javadoc:

Updates the message property. Calls to updateMessage are coalesced andrun later on the FX application thread, so calls to updateMessage,even from the FX Application thread, may not necessarily result inimmediate updates to this property, and intermediate message valuesmay be coalesced to save on event notifications.

This method is safeto be called from any thread.

Task javadoc 中有许多使用 updateMessage() 的示例。

关于multithreading - 如何从我自己的线程安全地修改 JavaFX GUI 节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19945422/

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