Recent Java releases now include a new user interface framework in the form of JavaFX. This is huge improvement over the ageing Swing/AWT framework and provides a much more suitable platform for implementing the GUI portion of Reaction based applications.
The JavaFX example presented here makes use of the same underlying application model as the previous Swing based example, replacing only the viewer and controller parts of the application. As for the Swing based example, the viewer and controller roles are combined into a single class called ViewerController and the full implementation is included in the javafx examples package as JavaFxExample.
As for the previous Swing based example, a number of buttons are added to the GUI window for starting, stopping and resetting the stopwatch. These correspond directly to the timerStart, timerStop and timerReset methods on the model's control interface. Since the control interface methods are thread safe, it is possible to call them directly from the context of the GUI thread using a standard action event handler object as shown in Listing 9.10.
In the example, the control buttons are all added to a horizontal box, which will place them in the TilePane widget container. The appearance of the enclosing box and the control buttons themselves is configured using the specified style classes from the JavaFxExample.css stylesheet
There is also the `close' button on the window frame which corresponds to the timerQuit method on the control interface. Again, this may be called directly from the GUI thread using a standard JavaFX window event handler object as shown in Listing 9.11.
The implementation of viewer functionality in JavaFX is made much easier by the support for value binding to user interface elements. This means that the application developer does not need to explicitly manage the process of redrawing the user interface view. However, JavaFX still imposes the restriction that updates to bound property values must take place in the context of the main Java FX thread.
In the example, the signalable interface to the application view and the observable timer property value used by the JavaFX framework are wrapped in a separate class called ObservableTimer. This allows the observable timer value to be bound to the JavaFX user interface element as shown in Listing 9.12. Once this binding has been established, any changes to the observable timer string value will automatically cause the displayed timer text to be redrawn.
The observable timer class manages the forwarding of updates from the model to the JavaFX observable property updates which will trigger the user interface to be updated. The first task is to convert the numeric timer value to a string which is suitable for display, followed by a request to the JavaFX framework to apply this change to the observable string property value from the context of the main JavaFX thread.
The process of converting the integer timer value to a displayable string is shown in Listing 9.13. After the display string has been formatted, the Platform.runLater call is made in order to schedule the Runnable.run method for subsequent execution in the context of the JavaFX main thread.
The procedure used to update the observable string value from within the context of the JavaFX main thread is shown in Listing 9.14. This takes the currently cached string representation of the stopwatch time and updates the observable string value which is bound to the user interface display.
The use of property binding in JavaFX provides for a much more elegant viewer implementation than the equivalent Swing based code. Furthermore, while all the styling associated with the Swing view has to be hardcoded into the painting callback, the JavaFX implementation does not need to contain any formatting information at all.
In the JavaFX implementation, all of the text styling associated with the viewer functionality is assigned using the styleClass method calls made when declaring the text elements in Listing 9.12. These identify the text styling to be used as defined in the associated stylesheet. For the purposes of the example, some simple effects can be applied to the displayed string as shown in Listing 9.15.
The combination of the buttons added to the GUI window in Section 9.4.1 and the rendered version of the current stopwatch time yields the window display shown in Figure 9.2. This has a much more polished look than the corresponding Swing application, despite the fact that much less code is required to produce the desired result. However, both applications still share the same core application code - further emphasising the independence of the underlying Reaction based model from the GUI toolkit being used.