The Application Class

So that is the front-end, the easy part (so to speak).  I put the code to implement the controls in a separate file, and reference it in the application main program (Listing 3).  Compare this code to Listing 1, which is what you get when you create the initial Project.

Let’s look at Listing 3 in detail.

package datecalculator;
 
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.AnchorPane;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
 
/**
 * The DateCalculator class is the main class for the
 * Date Difference Calculator application.  This class extends
 * javafx.application.Application.
 *
 * @author Philip Nau
 */
public class DateCalculator extends Application {
    /**
     * Loads the FXML file (DateCalculatorUI.fxml) used in
     * generating the UI, and initializes the overall application window. 
     * Establishes the FXML document controller DateCalculatorUI.
     * Sets the Application Stage (main window) and defines the Scene based on
     * the FXML hierarchy.
     * @param appStage the name of the main Application Stage.
     */
    @Override
    public void start(Stage appStage) throws Exception {
        FXMLLoader floader = new FXMLLoader();
        // Identify the URL of the FXML file used to lay out the UI.
        floader.setLocation(this.getClass().getResource(
                "DateCalculatorUI.fxml"));
        // Load the FXML Object hierarchy.
        floader.load(); 
        // Our top-level hierarchy element is an AnchorPane.
        AnchorPane root = floader.getRoot(); 
       
        DateCalculatorUI calculatorController =
                   (DateCalculatorUI)floader.getController();
        calculatorController.setApplicationStage(appStage);
        appStage.setScene(new Scene(root, Color.DARKGREY));
        appStage.setTitle("Event Date Difference Calculator");
        appStage.setResizable(false);
        appStage.show();
    }
 
    /**
     * The main class is required by Java but is not used to invoke FXML
     * applications.
     * @param args the command line arguments (None, in our case).
     */
    public static void main(String[] args) {
        launch(args);
    }
}
 

Listing 3 – Date Calculator Main Class


When you create your Project as a JavaFX Application you are extending the Application class, in this case by DateCalculator.  There are two methods in this class; main() provides the required Java static method to process any run-time arguments (none, in my case), and to create and launch the application thread.  The start() method is abstract in the base class and must be overridden to set the DateCalculator primary Stage and Scene.  It is the main entry point for the application. The first thing I do is identify the location and name of the SceneBuilder-created FXML file that defines the DateCalculator UI. The FXMLLoader load() method parses and loads the XML content, effectively defining the UI elements, along with their properties and relationships, including the root node of the UI hierarchy.  In my case, the root node is of type AnchorPane, since I use an AnchorPane in SceneBuilder as my top-level container.  Note my UI Controller class (DateCalculatorUI) is referenced in the FXML file, through the ‘fx:controller="datecalculator.DateCalculatorUI"’ construct. (You can establish the controller in SceneBuilder, see Section 5 of the Getting Started tutorial).  Next, the Scene is set, and the Stage’s show() method makes the UI visible.

A side note here – JavaFX is designed to operate in a multi-threaded environment.  At run-time, JavaFX initiates the main thread (called the Application thread, appropriately enough). All UI code is executed on this thread.  Additional threads may be initiated to run in parallel with the main thread to accomplish other tasks; for example, background processing, timed event handling, and so forth. There are JavaFX classes (Task, Service) and a Worker interface to accomplish this activity, but I don’t use these features in this application, so I’ll leave off with a pointer to the documentation and move on.

Note my reference to the DateCalculatorUI object in establishing the Calculator Controller.  The DateCalculatorUI class extends Stage and performs the bulk of my UI processing. I also set up a reference to the appStage object as an instance variable in DateCalculatorUI; I will use this reference to control dialog Stages that are needed to get and save Event information.  More on this below.