Your First JavaFX Window
Your First JavaFX Window
The previous lessons introduced the Application class, the lifecycle, and the tree of nodes that makes up a scene. Now you put it all together into a real, working window that a user can interact with. By the end of this lesson you will have a JavaFX application that displays a button and responds when the user clicks it — the smallest meaningful GUI program you can write.
What the Runtime Needs from You
JavaFX requires exactly one class to extend javafx.application.Application and override start(Stage primaryStage). That method is your entry point into the GUI world. Everything that touches the scene graph must happen here, or on the JavaFX Application Thread (covered fully in the next lesson). The main method simply calls launch(args) to hand control to the toolkit.
main entirely when the module system is configured — but keeping it is safer and more portable across build tools.
Building the Scene Step by Step
A JavaFX window is constructed bottom-up: you create the controls first, assemble them into a layout container, wrap that in a Scene, and place the scene onto the Stage. Here is the full program:
Let's walk through every decision in that 30-line program.
Step 1 — Controls Are Just Objects
Label and Button are both subclasses of Node. You construct them with new, set properties with setters, and add them to a parent container. There is no XML, no descriptor file, and no IDE wizard required — it is plain Java object construction.
Step 2 — Responding to an Event with a Lambda
The line button.setOnAction(event -> label.setText("Hello, JavaFX!")) is the core of GUI programming: connect a user action to a piece of code. setOnAction accepts any EventHandler<ActionEvent>. Because that interface is functional (single abstract method), a lambda works perfectly. When the button is clicked, the toolkit calls this lambda on the JavaFX Application Thread, which is also the thread that owns the scene graph — so updating label directly is safe here.
Step 3 — Layout Containers Position Children
VBox stacks its children vertically with a configurable spacing. The first argument to its constructor is the gap in pixels between children. You can also set padding and alignment via inline CSS (the -fx-* property names) or via the Java API. Other common containers you will meet soon are HBox (horizontal), BorderPane (north/south/east/west/center), and GridPane (rows and columns).
You add children with getChildren().addAll(...). The getChildren() method returns an ObservableList<Node> — adding or removing items from it automatically triggers a layout pass and a re-render.
Step 4 — The Scene Owns a Root Node and a Size
new Scene(root, 320, 200) creates a scene whose root is your VBox and whose initial size is 320×200 pixels. Every control inside root is now part of this scene's node tree. The Scene object is also where you later attach stylesheets:
Step 5 — The Stage Is the OS Window
primaryStage is provided by the toolkit when it calls start. You set a title, attach the scene, and call show(). That is all it takes to push a window onto the screen. The stage is also where you control resizability, full-screen mode, icons, and minimum/maximum dimensions:
The Complete Object Graph
After show() the live object graph looks like this:
This is the scene graph in action. When you click the button, the label's text property changes; the JavaFX rendering engine notices the change (because Text is observable) and repaints just the affected region on the next pulse — no manual repaint calls needed.
Closing Behaviour
By default, closing the primary stage exits the application via Platform.exit(). If you have multiple stages or need to run cleanup code, you can override stop() in your Application subclass:
System.exit() to close a JavaFX app. It bypasses stop() and skips any cleanup you registered. Use Platform.exit() instead, or simply close the window and let the default behaviour run.
Running the Application
With the JavaFX SDK on the module path (e.g. via the org.openjfx:javafx-controls Maven/Gradle dependency), compile and run as a normal Java class. IntelliJ IDEA and VS Code both support JavaFX projects through their Maven/Gradle integration — you do not need a separate plugin for this basic setup.
Summary
A working JavaFX window needs five things: controls created as objects, an event handler wiring user actions to code, a layout container assembling the controls, a Scene giving the tree a size, and a Stage presenting it on screen. The runtime calls start() for you — your job is to build the tree and call show(). That pattern scales unchanged from this 30-line program to a multi-screen enterprise application.