-
Notifications
You must be signed in to change notification settings - Fork 0
Home
So you decided to take a further look into the standbein library. Before get started take a quick grasp at the basics of dependency injection and guice, as this is the foundation of the library.
This library consists of a set of general use libraries (which you are free to use on their own) and the main application library.
-
i18n: The internationalization module (basically handling property files)
-
Eventsystem: The lightweight event bus.
-
Launch and services: Predefined application startup with runlevels.
-
Validation: 8 class validation system.
-
Activity context: A CDI like proxied scope to control the lifecycle of dialogs/activities.
-
Loading/saving model binding: A predefined approach to have the general load, bind, edit, save cycle.
I don not provide any awesome utility classes (Serices, Tasks, whatever) to hide the most prominent detail about javafx:
JavaFX is a multithreaded framework involving all the pain related to syncing at least 2 or more threads together
There is one general rule:
Never use Platform.runLater(…) to invoke anything in the ui thread (unless you are sure)
If you have a large team of developers programming a lot of different dialogs you want to prevent that the backgrounded process of one part of the programm comes back after it was blocked for some time and executes code on the UI that makes no sense anymore because you are in a totally different activity.
The enhanced control we need is already present in the standard JDK in the form of the ExecutorService.
In standbein there are 3 kinds of ExecutorServices:
-
ActivityExecutor: Which is the background thread executor service bound to the lifecycle of the current activity.
-
This executor service is used to eg. load stuff/save stuff in the background.
-
-
ActivityJavaFXExecutor: Which is the executor service that will execute stuff in the JavaFX Thread and is bound to the lifecycle of the current activity.
-
This executor service is used for all actions that need to run in the JavaFX thread
-
-
JavaFXExecutorService: Same as the ActivityJavaFXExecutor but it is not bound to any activity.
Sample usage:
@Inject
ActivityJavaFXExecutor fxService;
...
public void update() {
fxService.submit(()->label.setText("Hello");
}
...
Since JDK8 (and before that with guava) we have the possibility to create execution chains. Eg. we can load some stuff in the background in the activity executor service and when we get a result we will show it in some javafx component.
So an example would be:
@Inject
ActivityExecutor executor;
@Inject
ActivityJavaFXExecutor fxExecutor;
public void doStuff() {
CompletableFuture.supplyAsync(() -> veryLongLoading(), executor)//
.thenAcceptAsync(value -> label.setText(value), fxExecutor);
}
With the first call we load a value using the veryLongLoading() method in the background executor. Once the value is present we will apply it to the label, in the JavaFX thread. Since we use the activity executors, when we stop the activity, those executors will be shut down, and not accept any further operations (Reject policy).
From my point of view this is all we need to handle the complexity of UI multithreading. Did I mention that you can cancel completablefutures?