Исключение в основном говорит вам, в чем проблема: вы меняете состояние части графика сцены из потока, отличного от потока приложений FX. Причиной этого является то, что методы слушателя вызывают в том же потоке, который изменяет свойство.
У вас есть пара вариантов для этого: один должен просто использовать 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 Application Thread.
У вас нет большого кода, но для того, чтобы рассчитать изображение вы можете использовать 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()
), вместо того, чтобы с помощью одного из методов обратного вызова (setOnSucceeded
) от Task
, который гарантированно будет называться на FX Application Thread.
Отличный ответ Приветствия. Я очень новичок в java8, поэтому использовал стиль, который мне знаком;) на данный момент я не уверен, как заставить этот код работать в моей. Но я попробую как можно скорее и пометю вам ответ – Nemo
Версия Platform.runLater (...) работала для меня, приветствует приятеля – Nemo