Skip to content

JavaFX

1. The Application Class and Lifecycle

The javafx.application.Application class is the entry point for any JavaFX application.

To create a JavaFX app, main class must extend the Application class. (must be a subclass)

The lifecycle of the application defines three life-cycle methods the application can override: init(), start(), and stop().

Think of the lifecycle like putting on a play:

  • init(): Setting up the props and stage backstage before the audience arrives.
  • start(): The curtain goes up, and the play begins.
  • stop(): The play is over, and the crew cleans up and tears down the set.

init()

The void init() method is called after the application is launched/ begins but before the UI is created and shown.

  • Purpose: It's used for initialization tasks that don't involve the UI, such as loading configuration files, establishing database connections, or preparing resources.

  • Execution: It runs on a non-JavaFX application thread. This means you cannot create or modify UI components (like a Stage or Scene) inside init(). It cannot be used to create a stage or build a scene

  • Override: This is an optional method. You only need to override it if you have pre-UI setup tasks to perform. If no initialization required, this method need not be overridden because an empty, default version is provided.

java
@Override
public void init() {
    // Example: Load properties from a config file.
    System.out.println("Inside init(): Setting up resources...");
}

start(Stage primaryStage)

This is the main entry point for all JavaFX applications and is where user interface is built.

  • Purpose: It's where Scene is created, add UI controls (nodes), and attach the Scene to the Stage (the main window).

  • Execution: It runs on the JavaFX Application Thread, which is the only thread allowed to modify the UI (the scene graph).

  • Override: This is an abstract method, so you must override it in your class. The JavaFX runtime provides you with the main window, called the primaryStage.

java
@Override
public void start(Stage primaryStage) {
    System.out.println("Inside start(): Building the UI...");
    // Create a button
    Button btn = new Button("Say 'Hello World'");
    
    // Create a layout pane (the root node)
    StackPane root = new StackPane();
    root.getChildren().add(btn);

    // Create a scene and set the root node
    Scene scene = new Scene(root, 300, 250);

    // Set the scene on the stage, set a title, and show it
    primaryStage.setTitle("Hello World!");
    primaryStage.setScene(scene);
    primaryStage.show();
}

stop()

The stop() method is called when the application is closing. This can happen when the user closes the last window or when Platform.exit() is called explicitly.

  • Purpose: It's the ideal place for cleanup operations, such as releasing resources, closing network connections, or saving the application's state before it terminates.

  • Execution: It runs on the JavaFX Application Thread.

  • Override: This is an optional method. You only override it if you have final cleanup tasks to perform.

java
@Override
public void stop() {
    // Example: Release resources or save data.
    System.out.println("Inside stop(): Cleaning up and exiting...");
}

2. Core Structural Components of JavaFX

The Stage and Scene Classes

These two classes form the basic container structure of a JavaFX application, best understood with a theater analogy.

Stage:

The Stage is the top-level container / window of application. All JavaFX applications automatically have access to one Stage, called the primary stage.

  • The main Stage (the primaryStage) is created for you by the JavaFX runtime.

  • It represents the entire window, including its border, title bar, and minimize/maximize/close buttons.

  • You can create new Stage objects to serve as pop-up dialogs or additional windows.

Scene:

The Scene is the container for all the content inside a Stage, for the items that comprise the scene.

These can consist of controls, such as push buttons and check boxes, text, and graphics. To create a scene, you will add those elements to an instance of Scene.

  • A Stage can only display one Scene at a time.

  • You can change the entire UI of a window by creating a new Scene and setting it on the existing Stage, much like changing the set on a theater stage.

  • A Scene must be constructed with a root node.

In summary: A Stage is the window, and a Scene is the content within that window.

Nodes and the Scene Graph

  • Node: A Node is any single item in the scene graph. This includes every visual element, such as:

    • UI controls like Button, Label, TextField.

    • Layout panes like VBox, GridPane.

    • Shapes like Rectangle, Circle.

    • Media views for images and videos.

  • Scene Graph: The scene graph is the hierarchical tree structure of all the nodes that make up a Scene.

    • It starts with a single root node. This is the only node that doesn't have a parent.

    • Every other node is a child of another node, forming a tree. For example, a VBox (a layout pane) might be the root node, and its children could be a Label and a Button.

    • JavaFX uses this tree structure to render the UI and process events. Events often "bubble up" from a child node to its parent.

Layouts (Layout Panes)

Layout panes are special types of nodes whose purpose is to automatically manage the size and position of their child nodes. They are essential for creating responsive UIs that look good on different screen sizes, as they save you from having to manually calculate the coordinates of every component.

Common layout panes include:

  • HBox: Arranges its child nodes in a single horizontal row.

  • VBox: Arranges its child nodes in a single vertical column.

  • BorderPane: Divides the layout into five regions: top, bottom, left, right, and center. This is very common for the overall structure of an application window.

  • GridPane: Arranges its child nodes in a flexible grid of rows and columns, similar to a spreadsheet.

  • StackPane: Stacks its child nodes on top of each other, like a deck of cards. The last node added is on top.

JavaFX Controls

3. Basic JavaFX Controls: Label, Button, RadioButton, TextField

JavaFX controls are ready-made user interface components (like buttons, text fields, sliders, etc.) that you can use to build interactive GUI applications.

Label Static text Button triggers action on click TextField allows single line text input CheckBox Select deselct multiple options RadioButton Select one option from a group ListView List of items ComboBox dropdown menu TreeView

This program creates a simple user information form. You can enter a name in a TextField, select a salutation using RadioButton, and click a Button to display a greeting in a Label.

java
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class BasicControlsDemo extends Application {

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Basic Controls Demo");

        // --- 1. Create the Controls ---

        // Label to display the final greeting.
        Label greetingLabel = new Label("Greeting will appear here.");

        // TextField for user to enter their name.
        TextField nameField = new TextField();
        nameField.setPromptText("Enter your name"); // Placeholder text

        // RadioButtons for selecting a title.
        ToggleGroup titleGroup = new ToggleGroup(); // Ensures only one can be selected
        RadioButton mrButton = new RadioButton("Mr.");
        mrButton.setToggleGroup(titleGroup);
        mrButton.setSelected(true); // Default selection

        RadioButton msButton = new RadioButton("Ms.");
        msButton.setToggleGroup(titleGroup);

        // Button to trigger the action.
        Button greetButton = new Button("Show Greeting");

        // --- 2. Set the Action for the Button ---
        greetButton.setOnAction(event -> {
            String name = nameField.getText();
            RadioButton selected = (RadioButton) titleGroup.getSelectedToggle();
            String title = selected.getText();

            if (name.isEmpty()) {
                greetingLabel.setText("Please enter a name.");
            } else {
                greetingLabel.setText("Hello, " 
	                + title + " " + name + "!");
            }
        });

        // --- 3. Arrange Controls in a Layout Pane ---
        VBox root = new VBox(10); // 10 is the spacing between elements
        root.setPadding(new Insets(15)); // Padding around the layout
        root.getChildren().addAll(
            new Label("Enter Name:"), 
            nameField, 
            new Label("Select Title:"), 
            mrButton, 
            msButton, 
            greetButton, 
            greetingLabel
        );

        // --- 4. Create Scene and Show Stage ---
        Scene scene = new Scene(root, 300, 280);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

4. Advanced JavaFX Controls: ListView, TreeView, ScrollPane

This program demonstrates three more advanced controls:

  • ListView: Shows a simple, selectable list of items.

  • TreeView: Shows a hierarchical list of items that can be expanded and collapsed.

  • ScrollPane: Provides scrolling capabilities to a large piece of content—in this case, an ImageView containing a large image.

java
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class AdvancedControlsDemo extends Application {

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Advanced Controls Demo");

        // --- 1. Create the ListView ---
        ListView<String> listView = new ListView<>();
        listView.getItems().addAll("Apples", "Oranges", "Bananas", "Pears");
        listView.setPrefHeight(100);

        // --- 2. Create the TreeView ---
        // Create tree items (nodes)
        TreeItem<String> rootItem = new TreeItem<>("Files");
        TreeItem<String> branch1 = new TreeItem<>("Pictures");
        branch1.getChildren().addAll(new TreeItem<>("photo1.jpg"), new TreeItem<>("photo2.png"));
        TreeItem<String> branch2 = new TreeItem<>("Documents");
        branch2.getChildren().addAll(new TreeItem<>("report.docx"), new TreeItem<>("notes.txt"));
        
        // Add branches to the root
        rootItem.getChildren().addAll(branch1, branch2);
        rootItem.setExpanded(true); // Show it expanded by default

        TreeView<String> treeView = new TreeView<>(rootItem);
        treeView.setPrefHeight(150);
        
        // VBox for the left side
        VBox leftPane = new VBox(10, new Label("ListView:"), listView, new Label("TreeView:"), treeView);

        // --- 3. Create the ScrollPane with a large image ---
        // Note: You need a large image file named "large-image.jpg" in your project folder.
        // A placeholder is used if the image is not found.
        ImageView largeImageView;
        try {
            Image image = new Image("https://i.imgur.com/uStyOo2.jpeg"); // A large sample image URL
            largeImageView = new ImageView(image);
        } catch (Exception e) {
            // Fallback if image fails to load
            largeImageView = new ImageView();
            System.err.println("Could not load image. Please check the path/URL.");
        }
        
        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setContent(largeImageView); // Put the image view inside the scroll pane
        scrollPane.setPrefSize(300, 260);

        // --- 4. Arrange Layouts ---
        HBox root = new HBox(15, leftPane, scrollPane);
        
        // --- 5. Create Scene and Show Stage ---
        Scene scene = new Scene(root, 550, 300);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
  1. Write a complete temperature conversion program that converts a temperature from Fahrenheit to Celsius. The Fahrenheit temperature should be entered from a TextField, and a Label should be used to display the converted temperature.

This program creates a simple window with a TextField for user input, a Button to initiate the conversion, and a Label to display the result. It also includes basic error handling for non-numeric input.

java
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class TempConverter extends Application {

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Fahrenheit to Celsius Converter 🌡️");

        // --- 1. Create UI Components ---

        // TextField for Fahrenheit input
        TextField fahrenheitField = new TextField();
        fahrenheitField.setPromptText("e.g., 32");
        fahrenheitField.setMaxWidth(150);

        // Button to trigger the conversion
        Button convertButton = new Button("Convert");

        // Label to display the result in Celsius
        Label resultLabel = new Label("Result will be shown here.");

        // --- 2. Set the Action for the Button ---
        convertButton.setOnAction(event -> {
            String inputText = fahrenheitField.getText();
            try {
                // Convert the input text to a number
                double fahrenheit = Double.parseDouble(inputText);
                
                // Apply the conversion formula: C = (F - 32) * 5/9
                double celsius = (fahrenheit - 32) * 5.0 / 9.0;
                
                // Display the result, formatted to two decimal places
                resultLabel.setText(String.format("%.2f °C", celsius));
                
            } catch (NumberFormatException e) {
                // Handle cases where the input is not a valid number
                resultLabel.setText("Invalid input. Please enter a number.");
            }
        });

        // --- 3. Arrange Components in a Layout ---
        VBox root = new VBox(15); // Use a VBox for vertical layout with 15px spacing
        root.setPadding(new Insets(20)); // Padding around the VBox
        root.setAlignment(Pos.CENTER); // Center all components
        root.getChildren().addAll(
            new Label("Enter Temperature in Fahrenheit:"), 
            fahrenheitField, 
            convertButton, 
            resultLabel
        );

        // --- 4. Create Scene and Show Stage ---
        Scene scene = new Scene(root, 300, 200);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Made with ❤️ for students, by a fellow learner.