- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在过去的几天里,我一直在尝试使用 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/
我是一名优秀的程序员,十分优秀!