Skip to content
trashgod edited this page Apr 12, 2024 · 6 revisions

Goal

One goal of this project was to examine the consequences of hosting multiple, stand-alone applications within a single, dashboard-style JavaFX application. An experienced designer would reasonably observe that careless use of such an approach could undermine separation of concerns, as a JavaFX Application should follow strict lifecycle rules. For convenience while integrating, a class that implements the Modular interface may extend Application, but it is not required to do so.

Design

The host Application, defined in pom.xml, is org.example.ModularApp. It loads ModularView.fxml, initializing the resulting ModularHome controller and displaying its content. Because it implements the Modular interface, the ModularHome method createContent() simply returns the view's root component: a TabPane with one Tab for each client application.

A client application may be either a conventional JavaFX application or a JavaFX FXML application. For a conventional JavaFX application, ModularHome invokes setContent with the client's createContent() result. For a conventional JavaFX FXML application, ModularHome loads the relevant FXML and continues, again using the client controller's createContent() result.

To inject controller parameters as needed, see org.example.ModularController for example controller factory implementations.

Running

The project requires Java 17 or later and uses Maven to load a compatible version of JavaFX locally. As it uses the javafx-maven-plugin, it can be run from the command line like this:

mvn javafx:run

Alternatively, using a local JavaFX SDK, create a JAR with mvn package and run with either of these:

java -p /path/to/javafx-sdk/lib:target/modular-5.0.jar -m modular/org.example.ModularApp
java -p /path/to/javafx-sdk/lib --add-modules ALL-MODULE-PATH -jar target/modular-5.0.jar

The first runs both JavaFX and the JAR on the module path; the second runs JavaFX on the module path and the JAR on the class path according to its manifest. Client applications that began as stand-alone applications can be launched independently:

java -p /path/to/javafx-sdk/lib:target/modular-5.0.jar -m modular/org.example.AboutApp
java -p /path/to/javafx-sdk/lib:target/modular-5.0.jar -m modular/org.example.status.StatusApp

Use jlink to create a custom runtime image that can be run from the command line:

mvn javafx:jlink
./target/modular/bin/modular
./target/modular/bin/java -m modular/org.example.ModularApp
./target/modular/bin/java -m modular/org.example.AboutApp
./target/modular/bin/java -m modular/org.example.status.StatusApp
./target/modular/bin/java -m modular/org.example.math.ModularApp
…

Use jpackage to package a Java application containing the custom runtime image:

jpackage --type app-image -n Modular --runtime-image target/modular -m modular/org.example.ModularApp
Clone this wiki locally