Application, Stage and Scene
Every JavaFX application is a subclass of Application. JavaFX creates its object itself, calls the right methods in the right order and passes a ready main window to start. You need this order to know where to build the interface and where to release resources.
The lifecycle
| Method | When it is called | What goes in it |
|---|---|---|
init() | Before the window is created | Reading settings; you cannot create the interface here |
start(Stage) | When everything is ready | Building the scene and showing the window |
stop() | After the last window closes | Saving data, closing connections |
Only start is required; the other methods are empty by default. The launch method in main starts the whole chain.
An example with three methods
Let's add all three methods to App and print which thread each one runs in:
// src/main/java/com/example/notes/App.java
package com.example.notes;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void init() {
System.out.println("init: " + Thread.currentThread().getName());
}
@Override
public void start(Stage stage) {
System.out.println("start: " + Thread.currentThread().getName());
Label label = new Label("Notes will appear here");
StackPane root = new StackPane(label);
Scene scene = new Scene(root, 640, 480);
stage.setTitle("Notes");
stage.setMinWidth(400);
stage.setMinHeight(300);
stage.setScene(scene);
stage.show();
}
@Override
public void stop() {
System.out.println("stop: the application is closing");
}
public static void main(String[] args) {
launch(args);
}
}After mvn javafx:run a window opens with "Notes will appear here" in the middle. You cannot shrink it below 400 × 300. When you close the window, the terminal shows:
init: JavaFX-Launcher
start: JavaFX Application Thread
stop: the application is closingThe JavaFX thread
start, stop and all click handlers run in one thread, the JavaFX Application Thread. Only this thread may create windows and change the interface. The init method runs in a different thread, so you do not create windows there. How to do long work without freezing the window is covered in the lesson on background tasks.
Stage, Scene and the root
A Stage window shows one scene. A scene gets a root node and a size when it is created:
// src/main/java/com/example/notes/App.java — part of start()
StackPane root = new StackPane(label);
Scene scene = new Scene(root, 640, 480);
stage.setScene(scene);StackPane is the simplest container: it stacks nodes on top of each other and centers them. You can replace the scene with another one at any moment; that is how you switch screens.
Useful window methods:
| Method | What it does |
|---|---|
setTitle(String) | Sets the window title |
setMinWidth(double), setMinHeight(double) | Limit the minimum size |
setResizable(boolean) | Forbids or allows resizing |
show() | Shows the window |
close() | Closes the window |
Common mistake
People try to create a window in main before calling launch, for example new Stage(). JavaFX is not running yet, and the program crashes with java.lang.IllegalStateException: Not on FX application thread; currentThread = main. Put all interface code in start or in methods called from it.