这个答案使用与丹尼尔的答案相同的概念。
随附的是来自Task javadoc的 Partial Result 示例的副本(针对当前嵌入在 Java 8 javadoc 中的语法错误进行了修复,并添加了更具体的 Generic 类型)。您可以使用它的修改。
将您的异常放在 partialResults 集合中。对于您的情况,您不需要从任务返回异常列表,而是可以将它们放在一些显示异常的 UI 控件中(例如ListView
带有CellFactory
异常显示的 a)。请注意,partialResults 集合不需要同步,因为它总是在 JavaFX UI 线程上更新和访问(更新是通过Platform.runLater()
类似于 Daniel 解决方案的调用发生的)。
public class PartialResultsTask extends Task<ObservableList<Rectangle>> {
private ReadOnlyObjectWrapper<ObservableList<Rectangle>> partialResults =
new ReadOnlyObjectWrapper<>(
this,
"partialResults",
FXCollections.observableArrayList(
new ArrayList<>()
)
);
public final ObservableList<Rectangle> getPartialResults() {
return partialResults.get();
}
public final ReadOnlyObjectProperty<ObservableList<Rectangle>> partialResultsProperty() {
return partialResults.getReadOnlyProperty();
}
@Override
protected ObservableList<Rectangle> call() throws Exception {
updateMessage("Creating Rectangles...");
for (int i = 0; i < 100; i++) {
if (isCancelled()) break;
final Rectangle r = new Rectangle(10, 10);
r.setX(10 * i);
Platform.runLater(() -> partialResults.get().add(r));
updateProgress(i, 100);
}
return partialResults.get();
}
}
更新它的可观察属性时,任务首先检查更新是否发生在 FX 应用程序线程上。如果是,它会立即更新。如果不是,则它将更新包装在Platform.runLater()
调用中。请参阅任务源代码以了解这是如何完成的。
也许可以定义一组通用的并发感知属性,但 JavaFX 并没有在其核心提供这样的设施。确实,没必要。除了 javafx.concurrent 包之外,JavaFX 是一个单线程 UI 框架。