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
orScene
) insideinit()
. It cannot be used to create a stage or build a sceneOverride: 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.
@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 theScene
to theStage
(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
.
@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.
@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
(theprimaryStage
) 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 oneScene
at a time.You can change the entire UI of a window by creating a new
Scene
and setting it on the existingStage
, 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 aLabel
and aButton
.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
.
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, anImageView
containing a large image.
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);
}
}
- Write a complete temperature conversion program that converts a temperature from Fahrenheit to Celsius. The Fahrenheit temperature should be entered from a
TextField
, and aLabel
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.
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);
}
}