Learn Java

Lesson 76Elective: Desktop apps with JavaFX

JavaFX overview, features, and architecture

Why Java needed a new GUI toolkit, what JavaFX offers, the layers between your code and the screen, and the Stage, Scene, and node structure every application shares.

By Updated 65 min

  • GUI
  • event-driven
  • AWT
  • Swing
  • JavaFX
  • key features

Most programs in this course talk to their user through a terminal: print a line, read a line. A JavaFX program opens a window instead, fills it with text, buttons and fields, and then waits for the user to do something. Before any code, this lesson builds the picture you need to read JavaFX code: how a window program runs, where JavaFX came from, what each of its layers does, and the three objects every JavaFX application is made of.

By the end of this lesson
  • Explain how a window program differs from a console program, and what the event loop does with every click.
  • Compare AWT, Swing and JavaFX, and say what really happened to Swing.
  • Say what JavaFX is, and explain each of its main features in a sentence or two.
  • Draw the JavaFX architecture and say what every box does, from the JavaFX API down to the JVM.
  • Describe an application as a Stage, a Scene and a scene graph of nodes, including the five stage styles and the three types of node.
From before
This track adds no new language feature. A JavaFX program is a class that extends a class the library provides and overrides its start method. Clicks are answered by lambdas, and window styles come from an enum. All of it runs on one dedicated thread, which is why one slow method can freeze a whole window.
Why the programs in this track have no Run button
JavaFX draws real windows on your computer's screen, which the in-browser Java engine cannot do. So the JavaFX programs on these pages are for reading, each with a description of what it shows. The next lesson sets JavaFX up on your own machine, where you can run every one of them.

What changes when a program has a window#

Think back to the console programs you wrote with Scanner. Your code was in charge. It printed a prompt, called nextLine(), and stopped dead until the user pressed Enter. Then it decided what to do next. The program asked the questions, in the order it chose.

A window turns this around. Once the window is on screen, the user can click any of ten buttons, type in any field, drag the window, resize it or close it, in any order. A program that stopped to wait for one particular answer would stop everything else too, including redrawing its own window. So a window program never waits for one answer. It leaves instructions in advance, such as “when the Save button is clicked, run this method”, and lets the user act. Each thing the user does is an event (a click, a key press, a resize), and the method you attach to it is an event handler. Programs built this way are called event-driven.

Console program
Window program (JavaFX)
Your code decides what happens next.
The user decides what happens next.
You call scanner.nextLine() and wait for the answer.
You attach a handler to a button and return at once. JavaFX calls the handler later.
The code reads top to bottom, one straight path.
The code is a set of small handlers that run in whatever order the user picks.
The program ends when main reaches its last line.
The program ends when the user closes the last window.
Sequential flow.
Event-driven flow.
Key idea

In a window program the user acts first and the toolkit calls your code. Your job is to leave handlers in place and let each one finish quickly.

The event loop#

Something has to do the waiting. Inside JavaFX is a loop you never write, the event loop, running on a single thread called the JavaFX Application Thread for as long as the program runs. Each time round, it does this:

  1. 1The operating system notices something physical: the left mouse button went down at a point inside your window.
  2. 2It delivers that to your window as an event, which joins a queue of events waiting to be handled.
  3. 3The loop takes the next event off the queue.
  4. 4It works out which part of the window is under that point, say the Save button.
  5. 5It calls the handler you attached to the Save button, and waits for that handler to return.
  6. 6It redraws whatever the handler changed, then goes back to step 3.

This shape has a name, inversion of control. In a console program your code calls the library when it wants input. In a window program the library calls your code when input arrives.

A slow handler freezes the whole window
Step 5 waits. If a handler spends eight seconds copying a large file, then for eight seconds the loop takes no events and redraws nothing: clicks pile up unanswered, typing does not appear, and the window stops repainting. Windows adds “(Not Responding)” to the title bar; macOS shows its spinning wait cursor. Keep handlers short, and move slow work to a background thread. The last lesson of this module does exactly that with database queries.

AWT, Swing and JavaFX#

Java has had three toolkits for building windows. Each one answers a weakness of the one before.

AWT, the Abstract Window Toolkit (package java.awt), came with Java 1.0 in 1996. When you create an AWT button, AWT asks the operating system to create a real native button and keeps a hidden peerobject connected to it. The button looks like every other button on that system, but AWT can only offer widgets that every operating system has, and each system's widgets behave a little differently, so the same program could misbehave on one system and work on another. AWT is fine for a simple interface and weak for a large one.

Swing (package javax.swing, part of Java 1.2 in 1998) took the opposite route. It asks the operating system only for a plain top-level window, then paints every button, list and table itself with Java code. Components drawn this way are called lightweight. Because the drawing is Java's own, they behave the same on every platform and lean far less on native resources. Swing also added the components AWT lacked, such as tables, trees, tabbed panes and sliders.

JavaFXfirst appeared in December 2008, programmed through a separate scripting language called JavaFX Script. In 2011, JavaFX 2.0 rebuilt it as an ordinary Java library, the one you will use. It draws a scene graph through the graphics card and adds CSS styling, FXML, animation, media playback and an embedded web browser. JavaFX 8 shipped inside Oracle's JDK 8 in 2014. From Java 11 it is no longer bundled with the JDK: it is developed as a separate project, OpenJFX, and downloaded from openjfx.io, which is why the next lesson needs a section on compiling.

AWTSwingJavaFX
Arrived1996, in Java 1.01998, in Java 1.22008; a plain Java library since 2011
Packagejava.awtjavax.swingjavafx.* (javafx.scene, javafx.stage and more)
Who draws a buttonThe operating system, through a native peerSwing itself, painted in Java (lightweight)Prism, JavaFX's renderer, using the graphics card
Good atSimple interfaces with a native lookLarge interfaces that look the same everywhereModern interfaces: CSS, FXML, animation, media, web pages, 2D and 3D
Weak atFew components; platform-specific bugsStyling means Java painting code; no media or web viewNeeds a separate download since Java 11
TodayStill in every JDK (module java.desktop)Still in every JDK (module java.desktop)Outside the JDK as OpenJFX, with a new release every six months
Did JavaFX replace Swing?
Only as the recommended choice for new work. With Java 8, JavaFX became the recommended toolkit for new desktop applications, and Oracle's JavaFX FAQ of the time answered “Is JavaFX replacing Swing?” with yes, adding that Swing would remain part of Java SE for the foreseeable future. It has. Swing was never removed: it ships in every JDK today (module java.desktop), and large programs still run on it, IntelliJ IDEA's own interface among them. It was JavaFX that left the JDK, in Java 11.

What JavaFX is#

JavaFX started out as a Java library for building rich internet applications, the 2008 term for programs delivered through the web that felt like desktop software, the territory of Adobe Flash and Microsoft Silverlight. A JavaFX program could run inside a web page through Java's browser plug-in, and JavaFX was promoted for desktops, phones and TVs. Browser plug-ins have since disappeared. Today JavaFX is a library for desktop applications on Windows, macOS and Linux; phones and tablets are reachable only through third-party ports such as Gluon's.

Two of its early promises still hold. First, JavaFX is one library for things that used to need several: media, UI controls, web content, 2D and 3D graphics. Before it, a Java program that wanted a video, a web page and modern controls had to stitch separate libraries together. JavaFX can also use the existing Java libraries, Swing included. Second, JavaFX draws through the GPU (graphics processing unit), the chip in your computer built for drawing. These hardware-accelerated graphics keep animation smooth, and because animation and controls share one system, a button can fade in or slide across the window like any other shape.

What JavaFX offers#

Here is what JavaFX gives you, each with what it means when you sit down to write a program.

  • It is written in Java and runs on the JVM, so the same program runs on Windows, macOS and Linux: it is platform independent. One footnote: the lowest layers, the ones that talk to the operating system and the graphics card, are native code built separately for each system, which is why you download JavaFX for your own operating system. Your Java code stays the same.
  • FXML is a markup language for describing an interface instead of building it in Java. It is XML, with tags and attributes that look like HTML. A line such as <Button text="Save" onAction="#save"/> declares a button whose click runs a method called save in a Java controller class. The layout lives in the .fxml file and the logic in Java, so each can change without touching the other.
  • Scene Builder is a free drag-and-drop designer, now maintained by Gluon: you place controls on a canvas and it writes the FXML for you. It works alongside IntelliJ IDEA, Eclipse, NetBeans and VS Code.
  • It works with Swing. SwingNode puts Swing components inside a JavaFX window, and JFXPanel puts JavaFX content inside a Swing window, so an old Swing application can move to JavaFX one screen at a time.
  • It has ready-made controls, the parts of a window a user clicks or types into, in javafx.scene.control: Button, Label, TextField, CheckBox, RadioButton, TableView, ComboBox and many more. The controls and layouts lesson covers the ones this track uses.
  • You style it with CSS, the same idea as on the web: colours, fonts, borders and backgrounds are set with CSS rules, using JavaFX property names that start with -fx-. The rule .button { -fx-background-color: steelblue; -fx-text-fill: white; } in a stylesheet restyles every button in the program without touching the Java.
  • A Canvas is a blank surface you paint on yourself, with calls such as fillRect and strokeLine, for drawings no ready-made node expresses. The printing API (javafx.print) opens the print dialog and sends any node to a printer.
  • Its API goes beyond windows and controls, to 2D and 3D graphics, multimedia and web content. It is written in modern Java, so you meet generics (ObservableList<Node>), annotations (@Override), background threads and lambda expressions (button.setOnAction(e -> save())) throughout.
  • Shapes are built in: 2D shapes such as Rectangle, Circle and Polygon, and 3D shapes such as Box and Sphere with cameras and lights, all ordinary nodes that sit in a window beside buttons.
  • Everything is drawn by Prism, a hardware-accelerated rendering pipeline. It has its own section in the architecture below.

The JavaFX architecture#

JavaFX is built as a stack of layers. Read the diagram from the top, the side your code touches, down to the JVM at the bottom. Each layer uses the one beneath it and hides it from the ones above, so your program only ever talks to the top row.

JavaFX APIthe classes you importScene Graphthe live tree of nodesQuantum Toolkitjoins the layer above to the engines below, and runs the threadsJavaFX Graphics EnginePrismdraws the nodesOpenGL | D3Dgraphics APIsGlasswindows and inputWin32 | GTKOS window systemsWebViewweb pagesWebKitbrowser engineMediaaudio and videoGStreamermedia frameworkJDK API and Toolsjavac, the debugger, the standard libraryJava Virtual Machineruns the bytecode of everything above
The JavaFX architecture. Each part of the graphics engine stands on the native technology it uses.

From the top: the JavaFX API and the scene graph you build with it; the Quantum Toolkit, which connects them to the engine below; the JavaFX graphics engine, with Prism for drawing, Glass for windows and input, WebView for web pages and Media for sound and video, each standing on a native technology; then the JDK API and tools, and the Java Virtual Machine. The sections below take the boxes from the top down.

JavaFX API#

The JavaFX API is the set of classes and methods you write your program with: Stage, Scene, Button, Label, TextField and the rest. Like the Java library you already know, it is organised into packages. These seven are the ones you meet first.

PackageWhat it holdsClasses you will meet
javafx.animationTransition-based animations applied to nodes: fill, fade, rotate, scale and translateFadeTransition, RotateTransition, Timeline
javafx.applicationThe application life cycleApplication, Platform
javafx.cssThe machinery behind CSS-like stylingMostly used indirectly, through setStyle(...) and .css files
javafx.eventDelivering and handling eventsEvent, ActionEvent, EventHandler
javafx.geometry2D geometry (points, rectangles, bounds) and the spacing and alignment values layouts usePoint2D, Insets, Pos, HPos
javafx.stageThe top-level containers, that is, windowsStage, StageStyle, FileChooser
javafx.sceneThe scene graph itself, plus the sub-packages canvas, chart, control, effect, image, input, layout, media, paint, shape, text, transform and webScene, Node, Group; then Button (control), VBox (layout), Text (text), Color (paint), Rectangle (shape)

The packages ship in a handful of modules: javafx.base, javafx.graphics, javafx.controls, javafx.fxml, javafx.media, javafx.web and javafx.swing. You will name modules when you compile in the next lesson. For now, it is enough to know that javafx.controls brings in the two modules it is built on, javafx.graphics and javafx.base.

Scene graph#

The scene graph is where every JavaFX interface starts. It is a tree of objects called nodesthat describes everything in the window: what is there, where it sits and what it looks like. You build the tree; JavaFX keeps it in memory and redraws the window from it whenever something in it changes. Change a label's text with setText and the window updates on its own, with no painting code from you.

Key idea

You never paint a JavaFX window. You build a tree of nodes that describes it, and JavaFX turns that tree into pixels every time it changes.

A node is any visual object. Nodes come in four broad kinds:

  • shapes, 2D and 3D, such as Circle, Rectangle, Polygon, Box and Sphere;
  • controls, such as Button, CheckBox, ChoiceBox and TextArea;
  • containers, also called layout panes, which hold other nodes and arrange them, such as BorderPane, GridPane and FlowPane;
  • media elements: ImageView shows an image and MediaView shows a video.
Root NodeBranch NodeLeaf NodeLeaf NodeLeaf Node
A scene graph: one root, a branch node holding two leaves, and a leaf directly under the root.

The tree follows a few rules:

  • Every node has exactly one parent, except one: the root node, which has none.
  • A node with children is a branch node; a node with no children is a leaf node. So a node can have any number of children, including none.
  • A node instance can be added to a scene graph only once. Add a button that already sits in one container to a second container and JavaFX quietly takes it out of the first: the node moves, it is not copied. Two buttons on screen need two Buttonobjects, and adding the same node twice to one container's children throws an IllegalArgumentException about duplicate children.
  • Every node can carry effects (a drop shadow, a blur), an opacity from 0 (invisible) to 1 (solid), transforms (rotate, scale, move), event handlers, and application-specific state: your own data attached to the node, such as an id string or an object stored with setUserData. Effects, opacity and transforms set on a branch apply to its whole subtree: fade a container to half opacity and everything inside it fades with it.
Quick check
A window has two VBox columns. The code adds one Button object, save, to the left column's children and then to the right column's children. What does the user see?

Quantum Toolkit#

Quantum is the middle layer. It connects the higher-level parts of JavaFX, the API and the scene graph, with the graphics and windowing systems underneath, and it is the reason your code never talks to Prism or Glass directly. It coordinates four kinds of work:

  • Rendering: getting buttons, labels and shapes drawn on screen, by handing the scene graph's changes to Prism.
  • Input events: mouse clicks, key presses and touches arriving from Glass, delivered to the right scene.
  • Windowing: opening, closing, sizing and positioning windows, through Glass.
  • JavaFX application operations: the rest of the traffic between JavaFX and the system underneath, such as starting the toolkit and shutting it down.

Oracle's own description of the architecture adds one more job: Quantum manages the threading rules that keep rendering and event handling apart.

The JavaFX graphics engine#

The large box in the middle of the diagram holds eight names. Four are parts of JavaFX; the other four are the native technologies those parts stand on.

JavaFX partWhat it doesNative technology underneath
PrismRenders 2D and 3D graphics, using the GPU for hardware accelerationOpenGL or Direct3D (D3D), the graphics APIs; Apple's Metal on macOS since JavaFX 27
GlassConnects JavaFX to the operating system: windows, events, keyboard, mouseWin32 on Windows or GTK on Linux (Cocoa on macOS), the windowing systems
WebViewDisplays web content inside a JavaFX applicationWebKit, the web engine
MediaPlays audio and videoGStreamer, the media framework

Prism#

Prism is JavaFX's rendering engine, the part that actually draws. Everything visible goes through it: buttons, text, shapes, images, animations, 2D and 3D graphics. Prism uses the GPU when one is available, which is what keeps graphics and animation smooth. To reach the GPU it uses whichever graphics API the system offers: Direct3D on Windows, OpenGL on Linux, and Apple's Metal on macOS, the default there since JavaFX 27 (earlier releases used OpenGL on macOS too). Where no usable GPU exists, in some virtual machines for instance, Prism falls back to a slower software renderer and the program still runs. It draws on a thread of its own, so one frame can be drawn while the next is being prepared.

Quick check
A JavaFX program draws its window correctly on most computers, but on one old laptop the window opens with its title bar and an empty, blank inside. Which part of JavaFX is the first suspect?

Glass#

Glass is JavaFX's low-level windowing toolkit, the bridge between your JavaFX application and the operating system. Its jobs:

  • Creates and manages windows.
  • Handles keyboard and mouse input.
  • Manages screen and display information: how many screens there are, their sizes and resolutions (the class javafx.stage.Screen reports what Glass found).
  • Handles window events such as opening, closing, resizing and moving.
  • Communicates with the operating system on JavaFX's behalf for all of the above.

A detail from Oracle's architecture notes connects Glass to the event loop. Glass uses the operating system's own event queue and runs on the same thread as your JavaFX code. AWT kept separate native and Java threads; JavaFX does not, which is why every event handler you write runs on the one JavaFX Application Thread.

WebView#

WebView is a JavaFX component that displays web pages and web content inside your application. It is based on the WebKit browser engine, the engine behind Safari. With it you can:

  • display HTML web pages;
  • load a website from its URL;
  • display content written in HTML, CSS and JavaScript;
  • let the user interact with the page: follow its links, fill in its forms;
  • combine web content with ordinary JavaFX controls in the same window.

The work is split between two classes. WebView is the node that displays the page. WebEngine, which every WebView owns, loads the page and controls it: load takes a URL, and loadContent("<h1>Hello</h1>") shows a string of HTML. Together they make your application a small web browser. Both live in the module javafx.web, which you must name when you compile and run.

MiniBrowser.java
read along
1import javafx.application.Application;
2import javafx.scene.Scene;
3import javafx.scene.web.WebEngine;
4import javafx.scene.web.WebView;
5import javafx.stage.Stage;
6
7public class MiniBrowser extends Application {
8 @Override
9 public void start(Stage stage) {
10 WebView webView = new WebView(); // the node that displays the page
11 WebEngine engine = webView.getEngine(); // loads and controls the page
12 engine.load("https://openjfx.io");
13
14 stage.setTitle("Mini Browser");
15 stage.setScene(new Scene(webView, 900, 600));
16 stage.show();
17 }
18
19 public static void main(String[] args) {
20 launch(args);
21 }
22}
Output
A 900 by 600 window titled "Mini Browser" showing the openjfx.io home page
(the computer must be online). Links work: clicking one loads the next page
inside the same WebView. WebView is in the javafx.web module, so the module
list grows to --add-modules javafx.controls,javafx.web

Media engine#

The media engine plays audio and video. It is built on GStreamer, an open-source multimedia framework. Older tutorials list formats such as FLV that current JavaFX no longer plays. This is what it supports today:

What current JavaFX plays
AudioMP3; WAV and AIFF (uncompressed); AAC in an MP4 container (.m4a)
VideoMP4 with H.264 or H.265 (HEVC) video and AAC sound. FLV is no longer supported.
StreamingHTTP Live Streaming (HLS) playlists (.m3u8)

The media classes are in the package javafx.scene.media (module javafx.media), in three parts:

  • Media represents one media file, created from its location as a URI string.
  • MediaPlayer plays the media: play(), pause(), stop(), volume, position.
  • MediaView is a node that displays a player's video in the scene graph. Sound needs no view: a MediaPlayer on its own plays an MP3.
VideoDemo.java
read along
1import java.io.File;
2import javafx.application.Application;
3import javafx.scene.Group;
4import javafx.scene.Scene;
5import javafx.scene.media.Media;
6import javafx.scene.media.MediaPlayer;
7import javafx.scene.media.MediaView;
8import javafx.stage.Stage;
9
10public class VideoDemo extends Application {
11 @Override
12 public void start(Stage stage) {
13 // Media: the file itself, given as a URI string (file:/...)
14 Media media = new Media(new File("ooty.mp4").toURI().toString());
15
16 // MediaPlayer: plays, pauses and stops it
17 MediaPlayer player = new MediaPlayer(media);
18
19 // MediaView: the node that shows the video in the scene graph
20 MediaView view = new MediaView(player);
21 view.setFitWidth(640);
22
23 stage.setTitle("Video Demo");
24 stage.setScene(new Scene(new Group(view), 640, 360));
25 stage.show();
26 player.play();
27 }
28
29 public static void main(String[] args) {
30 launch(args);
31 }
32}
Output
A 640 by 360 window titled "Video Demo" playing ooty.mp4 from the folder
the program was started in. Needs the javafx.media module:
--add-modules javafx.controls,javafx.media
Give it an .flv file instead and new Media(...) throws a MediaException,
because the format is not supported.

JDK API and tools, and the JVM#

The bottom two boxes are the Java platform you already know. The JDK API and tools are the standard libraries (java.lang, java.util, threads, files) and the development tools: the compiler javac, the launcher java, the debugger. JavaFX is built on them like any other Java library. The JVM is the foundation: it executes the bytecode, and a JavaFX application runs on it exactly as a console program does. If the line between the JDK and the JVM is hazy, revisit setup and the JVM.

One click through the layers#

To see the layers work together, follow a single click on a Save button whose handler changes a label to “Saved”.

  1. 1Operating system. You press the mouse button. The operating system works out which window is under the pointer and sends that window a native message.
  2. 2Glass owns that window, so it receives the message, on the JavaFX Application Thread, and turns it into an event JavaFX understands.
  3. 3Quantum passes the event to the scene shown in that window, as a MouseEvent carrying the click's coordinates.
  4. 4Scene graph. JavaFX finds the topmost node under the point, the Save button, and routes the event down the tree to it and back up. The button recognises a press followed by a release as a click and fires an ActionEvent.
  5. 5Your handler, the lambda you gave setOnAction, runs on the same thread and calls label.setText("Saved").
  6. 6Back down. The label is marked as changed and a pulse is scheduled. On the pulse, JavaFX recomputes CSS and layout and hands the change to Prism.
  7. 7Prism draws the new frame with the GPU, through Direct3D on Windows, and the window shows “Saved”.

The structure of a JavaFX application#

Every JavaFX application is made of three parts: a Stage, a Scene and nodes. The names come from the theatre. The stage is where the play happens, the scene is what is set up on it at the moment, and the nodes are everything in that scene.

Stagethe window, from javafx.stageScenewhat the window shows, from javafx.sceneScene GraphRoot NodeBranch NodeLeaf NodeLeaf NodeLeaf Node
The Stage holds a Scene, and the Scene holds the scene graph of nodes.
Key idea

A Stage shows one Scene at a time, the Scene holds one root node, and every other node hangs somewhere below that root.

Stage#

A stage is a window, and it contains all the objects of a JavaFX application. It is an object of the class Stage in the package javafx.stage. You do not create the first one yourself: the primary stage is created by the platform, the JavaFX runtime, and passed as the argument to the start() method of your Application class. Extra windows, such as a dialog, are further Stage objects you create with new Stage().

Size and position
A stage's width and height give its size. Its position on the screen comes from two other properties, x and y, the distances from the left and top edges of the screen. All four have setters: stage.setX(100) and stage.setY(50) move the window, while stage.setWidth(600) and stage.setHeight(400) resize it.

A stage is divided into the content area, where your scene is drawn, and the decorations: the title bar and borders, drawn by the operating system. When you give a scene a size, say 600 by 300, that is the content area. The decorations go around it, so the window on screen is a little larger.

A stage has a style that decides its decorations. The styles are the values of the enum StageStyle (package javafx.stage), chosen with the stage's initStyle method. An enum is the natural type here: a fixed set of named choices. These five have been there from the start:

DECORATED
Title bar and border from the operating system. The default.
UNDECORATED
No title bar, no border. Only the white content area.
a node
TRANSPARENT
No decorations and no background. Only your nodes are visible.
UNIFIED
Decorated, but the title bar and content share one background.
x
UTILITY
A slim tool window with a minimal title bar.
The five classic StageStyle values. DECORATED is what you get when you choose nothing.
  • DECORATED: the default. A white background with the normal title bar and borders, including the minimise, maximise and close buttons.
  • UNDECORATED: a white background with no title bar or border at all, as on a splash screen. With no title bar to drag or close it by, your program has to provide a way out.
  • TRANSPARENT: no decorations and a transparent background, so only what your nodes draw is visible. Set the scene's fill to Color.TRANSPARENT as well, and a round clock can float on the desktop with no rectangle around it.
  • UNIFIED: normal decorations, but no border between the title bar and the content, so the content's background runs up into the title bar. Only some platforms support it; elsewhere it falls back to DECORATED.
  • UTILITY: a white background with minimal decorations, typically a slimmer title bar with only a close button, for small tool windows.
UtilityWindow.java
read along
1import javafx.application.Application;
2import javafx.scene.Group;
3import javafx.scene.Scene;
4import javafx.stage.Stage;
5import javafx.stage.StageStyle;
6
7public class UtilityWindow extends Application {
8 @Override
9 public void start(Stage primaryStage) {
10 primaryStage.initStyle(StageStyle.UTILITY); // must come before show()
11 primaryStage.setTitle("Tools");
12 primaryStage.setScene(new Scene(new Group(), 250, 150));
13 primaryStage.show();
14 }
15
16 public static void main(String[] args) {
17 launch(args);
18 }
19}
Output
A small window, 250 by 150, titled "Tools", with a slim title bar and,
on most systems, only a close button. Moving the initStyle line below
show() makes it throw IllegalStateException: the style can only be
chosen before the stage is first shown.

JavaFX 27 added a sixth value for good, EXTENDED, after trying it out as a preview in JavaFX 25 and 26. It stretches your content up into the title bar area, so your own nodes can sit there, together with a new HeaderBar control. This track sticks to the classic five.

One last point: nothing appears until you call the stage's show() method. Until then the stage is an object in memory and nothing more.

Scene#

A scene represents the physical contents of a JavaFX application: everything in the scene graph. It is an object of the class Scene in the package javafx.scene. At any instant a scene is added to only one stage, though a stage can swap in a different scene at any time with setScene, which is how a login screen gives way to a main screen in the same window.

You create a scene by instantiating Scene, passing it the root node and, if you like, its size: new Scene(root, 600, 300). The constructor takes the width first, so that scene is 600 pixels wide and 300 tall. A scene also has a fill, its background colour, white unless you change it. The next lesson builds scenes line by line.

Scene graph and nodes#

Two words to keep apart: the scene graph is a tree-like, hierarchical data structure representing the contents of a scene. A node is one visual object in it, of the four kinds you met above: geometrical objects, UI controls, containers and media elements. Each of them is a subclass of Node in javafx.scene, the superclass of all nodes. That shared superclass is what lets one container hold a Button, a Rectangle and an ImageView in a single list, the same polymorphism you used with your own class hierarchies.

By their place in the tree, nodes are of three types:

  • A root node is the first node of the scene graph, the one at the top with no parent. It is the node you pass to the Scene constructor.
  • A branch node, also called a parent node, is a node with child nodes. Their base class is Parent in javafx.scene, an abstract class, so you never write new Parent(); you use one of its kinds, described below.
  • A leaf node is a node without child nodes, such as a Rectangle or an Ellipse (2D shapes), a Box (a 3D shape), an ImageView (shows an image) or a MediaView (shows a video).

The parent nodes come in three kinds:

  • Group: a collective node that holds a list of children. When the group is rendered, its children are rendered in order, each drawn over the ones before it, and any transform or effect applied to the group applies to all of them. A group does not arrange its children: each one stays at the coordinates you gave it.
  • Region: the base class of all the node-based UI controls and layout containers: Chart, Pane (and through it VBox, GridPane and the other panes) and Control (and through it Button, TextField and the other controls). A region has a size of its own, can be resized, and can be styled with CSS.
  • WebView: manages a web engine and displays its contents. It extends Parent, but you never add children to it yourself; what it shows comes from the web page.

Notice where the controls sit. Button descends from Region, and so from Parent, because a control draws itself with a few internal nodes. In the tree you build, though, a button has no children you add, so you treat it as a leaf. The controls and layouts lesson draws the whole class hierarchy.

Two more points about the root. First, it is mandatory. The Scene constructor will not work without one, and its parameter type is Parent, so a leaf such as a Rectangle cannot be a root: that call does not compile. Second, the kind of root changes what happens when the window is resized:

A Group as the root
A layout pane as the root (StackPane, VBox, ...)
Is as big as its children, whatever the window size.
Is always exactly the size of the scene.
Leaves each child at the coordinates you gave it.
Decides where its children go; a StackPane centres them.
Window made bigger: the content stays where it was and empty space appears around it.
Window made bigger: the pane grows and lays its children out again, so centred content stays centred.
Window made smaller: whatever falls outside the window is cut off at the edge (clipped).
Window made smaller: the pane shrinks and lays its children out again in the space left.
Quick check
Which of these lines fails to compile?

Here is the scene graph of a small but real window, with each node's type marked.

Stagethe window, titled Ooty Tours (not a node)
Scene400 by 250 (not a node either)
VBoxroot node: a Region that stacks its children
Textleaf: "Welcome to Ooty"
ImageViewleaf: a photo of the lake
HBoxbranch node: a row for the buttons
Buttonleaf: "Book"
Buttonleaf: "Close"
Stage and Scene sit above the tree but are not nodes. The VBox is the root; it and the HBox are parents; the rest are leaves.
Ooty Tours
Welcome to Ooty
ImageView: lake.jpg
BookClose
The same window from the user's side. The leaves are what you see; the VBox and the HBox are invisible and only arrange them.
Where this track goes

Try it

Answer each one in your head or on paper first, then open the answer.

1
A console program and a JavaFX program both need the user's name. Describe how each one gets it, and say who decides what happens next in each.
2
A button's handler copies a 2 GB file, which takes ten seconds. What does the user see during those ten seconds, and why?
3
Someone writes in a forum: “Since Java 8, Swing has been removed and replaced by JavaFX.” Which part is right, which part is wrong, and what happened to JavaFX itself in Java 11?
4
Name the part of the JavaFX architecture that does each job: (a) asks the operating system for a window and receives key presses; (b) draws a button using the graphics card; (c) connects the scene graph to the engine below and coordinates rendering with input; (d) plays an MP4 file; (e) shows a web page inside the window. Then name the native technology under (a), (b), (d) and (e).
5
Look at the Ooty Tours scene graph above. Which node is the root, which are branch nodes, and which are leaves? Then: what happens if the code also adds the Book button to the VBox?
6
Which StageStyle fits each window: (a) an ordinary main window; (b) a splash screen with no title bar, shown while the program loads; (c) a small floating palette of drawing tools; (d) a round clock with no rectangle around it? When must initStyle be called? Finally, what do a stage's width and height set, and what sets its position?

Practice

Work through these on your own. Each one builds on this page.

1
Without looking back, draw the JavaFX architecture diagram and write a sentence or two on what each box does. Pair every part of the graphics engine with the native technology under it. Then compare your work with the figure and the tables on this page, and mark every difference.
2
Draw the scene graph of a calculator window: a TextField display at the top and a 4 by 4 grid of buttons below it, inside a VBox root, with a GridPane holding the buttons. Mark each node as root, branch or leaf. How many nodes does the tree have? Why can one Button object not serve as all sixteen keys?
3
For each of the seven packages in the JavaFX API table, find one more class in the JavaFX API documentation on openjfx.io and write one line on what it is for. Then find which module each package belongs to. Use what you find to explain why a program that plays a video needs javafx.media in its module list, while a program that only shows a Rectangle does not.
4
A friend's JavaFX player plays song.mp3 but fails on clip.flv and holiday.mkv. Using the media formats table, explain both failures, and say what the friend could do to play the two videos.

Short guides on this topic

Quick answers to what people search for about it, with code to run.

Spotted a mistake, or a part that did not make sense? Report it by email