gpt4 book ai didi

JavaFX:仅在更新标签时不在应用程序线程中?

转载 作者:行者123 更新时间:2023-11-30 07:51:30 25 4
gpt4 key购买 nike

在过去的几天里,我一直在尝试使用 JavaFX、FXML、任务和属性。我偶然发现了一个奇怪的行为,希望你能帮助我更好地理解发生了什么。

我有一个简约的 GUI,如下所示:GUI

如果我单击按钮,则会创建并启动一个新任务。此任务递增 Double 属性,并将新值写入标签并设置在 ProgressBar 中。任务的代码可以在这里看到:

public class TestTask extends Task<Void>{

private final DoubleProperty doubleValue = new SimpleDoubleProperty();

@Override
protected Void call() throws Exception {
for(double i = 0.1; i <= 1; i = i+0.1 ) {
doubleValue.set(i);
Thread.sleep(1000);
}
return null;
}

public DoubleProperty test() {
return doubleValue;
}
}

FXML Controller 的代码如下:

public class FXMLDocumentController implements Initializable {

@FXML private Label label;
@FXML private Slider slider;

//Called when the Button is clicked
@FXML
private void handleButtonAction(ActionEvent event) {
TestTask task = new TestTask();
task.test().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
//Works without problems
slider.setValue(newValue.doubleValue());
//Throws an exception
label.setText("Value" + newValue.doubleValue());
});
new Thread(task).start();
}
}

如果我运行此代码尝试更新标签会导致以下异常:java.lang.IllegalStateException:不在 FX 应用程序线程上;当前线程 = 线程 4。 Slider 的更新工作正常并且不会引发任何问题。

阅读以下关于 SO 的问题后:

我知道标签更新失败是因为我试图在从 TestTask 线程而非 FXApplication 线程调用的监听器中执行 UI 更新。

我现在的问题是:为什么 Slider 的 Update 工作并且不抛出异常?更新是在 Listener 中执行的,因此是在 TestTask 线程中执行的。这种尝试不应该也抛出“不在 FX 应用程序线程上”异常吗?

提前感谢您花时间帮助我。

最佳答案

在一个线程上更新属性,同时监听另一个线程上的属性更改只是一个 race condition .不要这样做。

JavaFX 系统不仅假设 UI 的更新发生在单个线程上,它还假设属性也是如此,无论它们是否绑定(bind)到 UI 元素。不要依赖 JavaFX 系统来检查所有竞争条件并为您正确报告和处理它们,因为它不是为这样做而设计的。

您需要以防止此类情况发生的方式编写您的代码。

关于JavaFX:仅在更新标签时不在应用程序线程中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46993547/

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