JavaFX - an overview
What is it?
JavaFX is the most recent desktop application development framework in the Java world, superseding AWT and Swing. Yes, there is also SWT; happy, Eclipse fans? Yes, there are others but I doubt they are nearly as popular, sorry.
It is a pretty modern UI framework and the way various artifacts are meant to interact makes it possible / easier for the developer to apply such useful concepts as separation of concerns, code reuse and more.
On top of the classic event-driven programming JavaFX introduced the concepts of observable values, properties and bindings. Various UI widgets expose relevant properties that can be bound to other properties, either in other widgets or in code. This binding mechanism allows for automatic updates of the UI without the developer having to listen to events and manually update UI properties.
The above-mentioned features combined with platform-specific ones such as modularization, internationalization, packaging and deployment methods allow for some pretty advanced applications to be developed.
The following general description does not cover all the subtleties, but tries to describe the most likely approach when working with JavaFX. For example, event handling methods can be written directly into the FXML file, not only in the controller. Or there's that not-so-needed-anymore Initializable
interface. We won't bother with all the gems, you'll have to discover them yourself while using the framework.
Software artifacts
The UI can be constructed programmatically by the developer but generally UI element definitions are stored into an FXML file; that file specifies what controller should be used (an almost ordinary java class) and what CSS style sheet. The IDE allows for the controller and CSS files to be edited while visual design tools such as Scene Builder take care of constructing the FXML file and pairing the controls in there with the controller and CSS stylesheet. Note that Gluon also offers Scene Builder as a library making it possible to be included within an IDE but as of this writing I'm not aware of any such implementation.
FXML files
FXML files are XML files holding special tags that define the UI elements. As in most other frameworks, the elements are hierarchical in structure, with a container element being the root that includes all the other containers and controls. Generally these files are made by a visual design tool such as Gluon's Scene Builder. In fact this is the only fxml designer that I know of. Once a controller source file has been configured, that visual design tool allows us to pair UI controls in the FXML file with JavaFX fields inside the controller; for example you can set a certain ComboBox to correspond to the
@FXML ComboBox cbxDepartment
defined in the controller - note the @FXML
annotation.Scene Builder and the FXML syntax allow other FXML files to be included or imported into the current file in a specific container, and so code reuse is possible.
At runtime there is a component in the JavaFX framework - the FXML Loader - that reads the FXML file, constructs the appropriate UI elements based on that, instantiates the controller and assigns the UI elements to the controller's fields as specified in the FXML file. The FXML's root element can be loaded into it's own window or within another container in a pre-existing window.
FXML Controllers - Java source code files
The controller is responsible with - you guessed it - controlling the UI. Which means it decides stuff like what goes into a TextField's text, a ComboBox's value, what needs to happen when a Button is clicked and so on.
As mentioned above, the controller is instantiated by the FXML Loader when loading an FXML file. A reference to the loaded FXML's controller can be obtained by the calling code so as to be able to interact with it by - for example - calling various methods. Actually there's another way to create a controller but for the time being we'll limit ourselves to "instantiated by the FXML Loader".
The developer writes the controller as an ordinary Java class having fields - either public or private annotated with
@FXML
- that correspond to tags in the FXML file, into which the FXML Loader "injects" the UI objects constructed when reading the FXML file, as instructed in the FXML tags. Also event-handling methods are defined here and they can be selected by the designer using SceneBuilder for handling various events on the UI elements. Those methods will then be linked to the proper events by the FXML Loader.So for example the FXML tag
<Label fx:id="lblName" />
will prompt the FXML Loader to construct a JavaFX Label
which will then be assigned to either a public field inside the controller instance declared as public Label lblName;
or to a private field annotated like this: @FXML private Label lblName;
After all the UI objects have been constructed and "injected" the FXML Loader will search for and call a
initialize()
method - either parameterless or as defined in the Initializable
interface. That method can be used by the developer to work on the objects created by the FXML Loader and injected into the controller instance, since those are created after the constructor is called.EDIT: The FXML Loader uses the reflection mechanisms to access and set various fields and methods within the controller. The developer needs to keep this in mind along with specifics related to the Java Platform Module System. More details will follow in subsequent posts.
CSS Files
JavaFX allows styling with Cascading Style Sheets.
The CSS reference for JavaFX 14 can be found here.
Scene Builder allows for .css files to be selected for container elements and the same can be done programmatically.
Apart from css files, various properties can be set on elements either programmatically (for example from within the controller) or in the FXML file, manually or by using the SceneBuilder.
CSS selectors can be used for searching nodes by using the
lookup
and lookupAll
methods.
That would be all for now. If you liked it then please upvote and stay tuned, more will follow!