I’ve been working on a project this year whose aim was to research how well JavaFX can be used as a technology to develop In-Car-Infotainment systems. The project’s focus was on two areas:
- Using a framework to develop various different Human-Machine-Interfaces (HMIs) within a consistent theme
- Analyzing the potential of model-based “reactive” development using JavaFX APIs for properties and bindings.
The framework for the development of HMIs is a research project at Volkswagen called Tappas. The framework can be used to develop prototypes of Infotainment HMIs by linking graphical user interfaces (GUIs) to relevant services. Part of the project involved adapting and extending the framework to allow complex skin variants for a basis HMI. Alongside our extensions, we also researched how well we could reactively model the GUI using Tappas.
The reactive model
The basis of a reactive model is a decision tree – a non-cyclical graph with a root node. The amount of nodes in the decision tree is described using properties. When the decision tree is traversed, each path ends at one of the leaves, with each leaf representing a view in the modelled GUI. Properties can be influenced by the user or by other services. Changing a property results in the decision tree being traversed again – and can therefore produce a different view in the GUI depending on the changed property.
An advantage of this approach is the chronological decoupling of the system and its services from the user interaction. The decision tree is only reanalyzed when properties are changed. The state of the GUI itself is defined solely by the amount of properties, and the properties are not tied to any specified time.
The model also possesses an inherent memory. Changing a property on the route to the current view usually results in a different view being displayed. If the property is changed back to its original value, the previously shown view will once again be displayed. Modelling the system history is therefore unnecessary. Navigation using “Back” can simply be implemented by remembering which property values were changed in which order.
The Tappas framework uses JavaFX with OSGi. Framework elements are provided as OSGi bundles and can be loaded dynamically at runtime. The HMI consists of a central presentation element (the main application) that contains other apps that can be used in the Infotainment system. Apps can be registered via an OSGi interface so that they can be found by the main application and shown to the user. Because recurring elements are abstractly described in each app, the framework is able to display them in a consistent fashion in the GUI.
The JavaFX properties and binding API is used to implement the reactive model. The model relies on the concept of lazy evaluation using InvalidationListeners. JavaFX elements can set requestLayout flags in response to certain property changes, causing the graphical representation engine to reorganize the elements in the scene graph using Pulses. Once the reorganization is complete, rendering takes place. The frequency of the pulses is controlled by JavaFX, although it is possible to explicitly request a pulse.
The Tappas framework describes the decision tree using bindings as a viewExpression. An InvalidationListener on the viewExpression requests a pulse when an expression is invalidated – i.e. when a dependent property is changed. The pulse results in the decision tree being reanalyzed and thus to a new view being shown in the GUI.
To deal with multiple variants of a HMI basis, we also spent time researching CSS skinning and the skin-control-pattern. Controls have a separate skin implementation, allowing layouts to be completely changed. One example is changing the layout using different FXML files (FXML is a declarative language for JavaFX layout elements). The skin-control-pattern offers flexibility when it comes to implementing different skin variants, but is problematic at the moment because it means that the code basis must be accessed and changed which makes the separation of responsibilities in the code difficult.
We found that the Tappas framework and the standard JavaFX mechanisms are well-suited to reactive modelling. Being able to modify the behavior in a time-independent manner was a crucial factor. The skin-control-pattern allows variants to be realized but is still faced with the problem of easily separating responsibilities during development.
The aspects we looked at show that JavaFX is a good candidate for developing HMIs. We’re looking forward to moving away from prototypes and onto actual applications to put our knowledge to the test and gather more experience from real development situations.
Image sources: Ehrke, J.; Gerlach, S. (2014, December) JavaFX auf Rädern. Javamagazin, 1.2015, 96-101. With kind permission from Jens Ehrke.