Creating a Basic JavaFX Application

This section shows you how to create the foundation of a JavaFX application using the Jukebox project as a reference. Every JavaFX application needs a main class that extends javafx.application.Application.

What You'll Learn:
  • How to extend the Application class
  • Understanding the start() method
  • Creating a Scene and Stage
  • Launching the JavaFX runtime
  • Configuring your module for JavaFX

The Main Application Class

In the Jukebox project, Jukebox.java is the main application class. Let's examine its key components:

Class Declaration

The main class extends Application from the JavaFX package:

package jukebox;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Jukebox extends Application {
    // Application code goes here
}
Why extend Application?

The Application class provides the lifecycle methods that JavaFX uses to start and manage your application. When you extend it, you're telling JavaFX that this is your main application class.

The start() Method

The start() method is called by the JavaFX runtime when the application launches. It receives a Stage parameter, which represents the primary window of your application.

@Override
public void start(Stage stage) {
    // 1. Create the main application window view
    Region applicationWindow = ApplicationWindowController.createViewInstance();
    
    // 2. Create a scene with the application window as the root
    Scene scene = new Scene(applicationWindow, 
                          applicationWindow.getPrefWidth(), 
                          applicationWindow.getPrefHeight());
    
    // 3. Set the scene on the primary stage
    stage.setScene(scene);
    
    // 4. Set the window title
    stage.setTitle("Jukebox");
    
    // 5. Display the window
    stage.show();
}
  • Create the root node: ApplicationWindowController.createViewInstance() returns a Region which is the root of our UI hierarchy. In JavaFX, every Scene needs a root node.
  • Create the Scene: A Scene is the container for all your UI content. It takes the root node and dimensions as parameters.
  • Set the Scene: The Stage (window) displays the Scene. You set the scene using stage.setScene().
  • Configure the Stage: Set properties like title, size, and whether it's resizable.
  • Show the Stage: Call stage.show() to make the window visible.
  • The main() Method

    Unlike Swing or AWT applications, JavaFX applications have a specific entry point pattern. The main() method initializes your application data, then calls launch() to start the JavaFX runtime.

    public static void main(String[] args) {
        // Initialize the database - this holds all our application data
        database = new Database();
        
        // Load data from the JSON file into our database object
        database.loadData();
        
        // Launch the JavaFX application
        launch(args);
    }
    About launch():
    • launch(args) is a static method inherited from Application
    • It creates an instance of your application class and calls start()
    • It starts the JavaFX runtime and event processing thread
    • It blocks until the application exits
    • For most applications, this is the only call you need in main()

    Static Fields in Jukebox.java

    Notice that Jukebox.java has several static fields at the top. These are used for communication between different parts of the application:

    // Static controller references
    public static ApplicationWindowController applicationWindowController;
    public static ChooseAlbumController chooseAlbumController;
    public static PlayAlbumController playAlbumController;
    public static HomeScreenController homeScreenController;
    public static AdminPanelController adminPanelController;
    
    // Static data model
    public static Database database;
    
    // Global state
    public static Album selectedAlbum;
    Why use static fields?

    In a learning project like Jukebox, static fields provide a simple way for different controllers to access shared resources and communicate with each other. Each controller stores its instance in a static field when it's created, and other parts of the application can then access it.

    Note: In larger, production applications, consider using dependency injection or other patterns instead of static fields.

    Module Configuration

    JavaFX applications need to be configured as modules. The module-info.java file defines what modules your application depends on.

    open module jukebox {
        requires javafx.graphics;
        requires javafx.controls;
        requires java.desktop;
        requires javafx.fxml;
        requires com.google.gson;
    }
    Important: The open keyword

    The open keyword in open module jukebox is crucial. It allows FXMLLoader to access private fields and methods in your controller classes through reflection. Without open, you would get errors when loading FXML files that reference controllers.

    Creating Your Own Basic JavaFX Application

    Now let's create a simple "Hello World" JavaFX application from scratch, similar to the Jukebox pattern:

  • Step 1: Create the module-info.java

    open module myapp {
        requires javafx.controls;
        requires javafx.graphics;
    }
  • Step 2: Create the main application class

    package myapp;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    public class HelloWorld extends Application {
        
        @Override
        public void start(Stage stage) {
            // Create a simple label
            Label label = new Label("Hello, JavaFX!");
            
            // Put it in a layout container
            StackPane root = new StackPane(label);
            root.setStyle("-fx-padding: 20;");
            
            // Create the scene
            Scene scene = new Scene(root, 300, 200);
            
            // Configure and show the stage
            stage.setTitle("Hello World");
            stage.setScene(scene);
            stage.show();
        }
        
        public static void main(String[] args) {
            launch(args);
        }
    }
  • Step 3: Compile and Run

    Compile with:

    javac --module-path /path/to/javafx-sdk/lib \
          --add-modules javafx.controls,javafx.graphics \
          -d out src/myapp/module-info.java src/myapp/HelloWorld.java

    Run with:

    java --module-path /path/to/javafx-sdk/lib:out \
          --add-modules javafx.controls,javafx.graphics \
          myapp.HelloWorld
  • Try This:

    1. Modify the start() method in Jukebox.java to change the window title to something else
    2. Change the default size by modifying the prefWidth and prefHeight values
    3. Run the application and see the changes take effect

    Common Pitfalls

    Pitfall 1: Forgetting to call launch()

    If you forget to call launch(args) in your main() method, your JavaFX application won't start. The start() method will never be called.

    Pitfall 2: Missing module dependencies

    If you get errors like "Class not found" for JavaFX classes, make sure your module-info.java has all the required modules and you're using the correct --module-path and --add-modules flags when compiling and running.

    Pitfall 3: Not using the open keyword

    If you're using FXML files and you get reflection errors, make sure your module is declared as open module in module-info.java.

    Pitfall 4: Modifying UI from non-FX thread

    All JavaFX UI operations must be performed on the JavaFX Application Thread. If you try to update UI from another thread, you'll get errors. Use Platform.runLater() for background operations that need to update the UI.

    Key Takeaways

    Related Cookbook Sections

    Now that you understand the basics of creating a JavaFX application, check out these related topics: