Provide an Executor implementation that runs submitted tasks on the JavaFX thread as an easily accessible static somewhere (perhaps Platform.getUpdateExecutor()).
It would look like:
private final Executor updateExecutor = new Executor() {
@Override
public void execute(Runnable command) {
Platform.runLater(command);
}
};
This makes it easier to use the concurrency API to handle background tasks which eventually need to do a small UI update, especially with for example the new Java 8 CompletableFuture that allows for multiple tasks to be chained and combined after which a UI update takes place. Here's an example (with only limited Lambda's, although the whole thing could be written as a one-liner):
/*
* Based on Task duration, select an Executor, then load an Image, then update the property with the Image.
*/
CompletableFuture<Executor> futureExecutor = CompletableFuture.supplyAsync(() -> imageHandle.isFastSource() ? FAST_EXECUTOR : SLOW_EXECUTOR, FAST_EXECUTOR);
CompletableFuture<Image> futureImage = futureExecutor.thenCompose(new Function<Executor, CompletionStage<Image>>() {
@Override
public CompletionStage<Image> apply(Executor executor) {
return CompletableFuture.supplyAsync(() -> getImage(imageHandle), executor);
}
});
CompletableFuture<Void> future = futureImage.thenAcceptAsync(image -> {
property.set(image); // Must be on JavaFX UI thread
}, new Executor() {
@Override
public void execute(Runnable command) {
Platform.runLater(command);
}
});
The last part would be nice to write as:
CompletableFuture<Void> future = futureImage.thenAcceptAsync(image -> {
property.set(image); // Must be on JavaFX UI thread
}, Platform.UPDATE_EXECUTOR);
This is only a minor request, and any kind of utility class can easily provide this executor, but I thought it might be good to have it as part of the platform.
It would look like:
private final Executor updateExecutor = new Executor() {
@Override
public void execute(Runnable command) {
Platform.runLater(command);
}
};
This makes it easier to use the concurrency API to handle background tasks which eventually need to do a small UI update, especially with for example the new Java 8 CompletableFuture that allows for multiple tasks to be chained and combined after which a UI update takes place. Here's an example (with only limited Lambda's, although the whole thing could be written as a one-liner):
/*
* Based on Task duration, select an Executor, then load an Image, then update the property with the Image.
*/
CompletableFuture<Executor> futureExecutor = CompletableFuture.supplyAsync(() -> imageHandle.isFastSource() ? FAST_EXECUTOR : SLOW_EXECUTOR, FAST_EXECUTOR);
CompletableFuture<Image> futureImage = futureExecutor.thenCompose(new Function<Executor, CompletionStage<Image>>() {
@Override
public CompletionStage<Image> apply(Executor executor) {
return CompletableFuture.supplyAsync(() -> getImage(imageHandle), executor);
}
});
CompletableFuture<Void> future = futureImage.thenAcceptAsync(image -> {
property.set(image); // Must be on JavaFX UI thread
}, new Executor() {
@Override
public void execute(Runnable command) {
Platform.runLater(command);
}
});
The last part would be nice to write as:
CompletableFuture<Void> future = futureImage.thenAcceptAsync(image -> {
property.set(image); // Must be on JavaFX UI thread
}, Platform.UPDATE_EXECUTOR);
This is only a minor request, and any kind of utility class can easily provide this executor, but I thought it might be good to have it as part of the platform.