我的视图中有一个ImageView,并尝试用它显示一个WritableImage实例。我在另一个线程中绘制它,并通过侦听ObjectProperty的change事件将其传递给视图。
public void changed(ObservableValue<? extends Image> observable,
Image oldValue, Image newValue) {
this.imageView.setImage(newValue);
}imageView应该已经准备好接收图像了,它是由我的mainView显示的。但是它是通过IllegalStateException从
线程" Thread-4“java.lang.IllegalStateException中的异常:不在FX应用程序线程上;currentThread =Thread-4
有人能解释这件事吗?
发布于 2014-11-28 15:28:06
例外情况基本上告诉您问题是什么:您正在从以外的线程中更改部分场景图的状态。原因是侦听器方法是在更改属性的同一个线程上调用的。
您有几个解决这个问题的选项:一个是只使用Platform.runLater(...)。您可以在侦听器中这样做:
public void changed(ObservableValue<? extends Image> observable,
Image oldValue, Image newValue) {
Platform.runLater(new Runnable() {
@Override
public void run() {
this.imageView.setImage(newValue);
}
});
}或者您也可以做同样的事情来在FX应用程序线程上设置属性的值。
您还没有显示太多的代码,但是您也可以使用Task来计算图像。所以,而不是像这样:
new Thread(new Runnable() {
@Override
public void run() {
WritableImage image = new WritableImage(...);
/// draw on image....
myImageProperty.set(image);
}
});你可以做这样的事
Task<Image> imageTask = new Task<Image>() {
@Override
public Image call() {
WritableImage image = new WritableImage(...);
// draw on image....
return image ;
}
});
imageTask.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent event) {
myImageProperty.set(imageTask.getValue());
}
});
new Thread(imageTask).start();(这在Java 8中要简洁得多;我在问题中使用了Java 7兼容的代码)。
在这里,您可以避免使用低级API (Platform.runLater()),而是使用来自Task的回调方法(setOnSucceeded)之一,该方法保证在上调用。
https://stackoverflow.com/questions/27190774
复制相似问题