JavaFX Fundamentals & the Scene Graph

Introduction to JavaFX

18 min Lesson 1 of 12

Introduction to JavaFX

JavaFX is the modern GUI toolkit for Java. It replaces Swing as the recommended way to build rich desktop applications, and it brings with it a scene-graph rendering model, CSS styling, hardware-accelerated graphics, and a clean property-and-binding system that makes reactive UIs straightforward to write. By the end of this tutorial you will have built a real, runnable JavaFX window — but first you need to understand what JavaFX is, why it exists, and how to wire it into a project.

A Brief History: From AWT to Swing to JavaFX

Java has had GUI support since its earliest days. The Abstract Window Toolkit (AWT) appeared in Java 1.0 and rendered components using native OS widgets. It worked, but the thin abstraction over platform-specific controls made consistent cross-platform behaviour difficult. Swing arrived in Java 1.2 and solved the consistency problem by painting every widget in Java itself — Swing owns every pixel. That made Swing highly portable, but its threading model is error-prone (all UI work must happen on the Event Dispatch Thread), and its API accumulated decades of cruft.

JavaFX was introduced as a separate download with Java 8 and bundled directly into the JDK. Oracle unbundled it again in Java 11, making it a standalone open-source project hosted at openjfx.io. The current stable release at time of writing is JavaFX 21 (LTS), which targets Java 21.

JavaFX is not part of the JDK since Java 11. You must add it as an explicit dependency via Maven or Gradle. This is covered below in the setup section.

What Makes JavaFX Different from Swing

The single biggest architectural difference is the scene graph. In Swing you build a tree of JComponent objects and Swing paints them in a flat, sequential pass. In JavaFX every visual element is a Node in a retained tree called the Scene Graph. The renderer traverses this tree efficiently, skipping unchanged subtrees, and delegates rasterisation to the GPU through the underlying Prism rendering pipeline.

Key differences at a glance:

  • Rendering: Swing — Java2D software rendering by default. JavaFX — hardware-accelerated Prism (OpenGL/Direct3D), software fallback on headless environments.
  • Styling: Swing uses pluggable Look-and-Feel classes. JavaFX uses CSS — the same syntax you use on the web, applied to Nodes.
  • Layout declarations: Swing layout managers are configured in Java code. JavaFX can also be configured in Java code, or in FXML, an XML markup language for describing the scene graph declaratively (analogous to XML layouts in Android).
  • Properties & Bindings: JavaFX introduces observable properties (StringProperty, IntegerProperty, etc.) that can be bound together so that changing one value automatically updates dependent UI elements.
  • Threading: JavaFX has the same rule as Swing — all UI mutations must happen on the JavaFX Application Thread — but it provides cleaner helpers (Platform.runLater) and a Task / Service API for background work.
  • Media & Web: JavaFX ships MediaPlayer for audio/video and WebView, a Chromium-based embedded browser (availability depends on platform).

The JavaFX Module System

JavaFX is split into modules, so you only pull in what you need:

  • javafx.base — observable collections, properties, bindings
  • javafx.graphics — scene graph, Stage, Scene, Nodes, shapes, transforms, CSS engine
  • javafx.controls — standard controls: Button, TextField, TableView, etc.
  • javafx.fxml — FXML loader and controller support
  • javafx.media — audio/video
  • javafx.webWebView component

For the first few lessons you only need javafx.controls (which transitively pulls in javafx.base and javafx.graphics).

Setting Up a JavaFX Project with Maven

The recommended way to start is the official Maven archetype maintained by the OpenJFX team. Run this command (substituting your own group/artifact IDs):

mvn archetype:generate \ -DarchetypeGroupId=org.openjfx \ -DarchetypeArtifactId=javafx-archetype-simple \ -DarchetypeVersion=0.0.6 \ -DgroupId=com.example \ -DartifactId=hellofx \ -Dversion=1.0-SNAPSHOT

This produces a working skeleton with a pom.xml that already contains the JavaFX dependency and the javafx-maven-plugin. The relevant excerpt:

<dependencies> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>21</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-fxml</artifactId> <version>21</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.8</version> <configuration> <mainClass>com.example.hellofx/com.example.hellofx.App</mainClass> </configuration> </plugin> </plugins> </build>

To run the application from the terminal:

mvn javafx:run
Use the JavaFX Maven Plugin, not the plain exec:java goal. JavaFX requires specific --module-path and --add-modules JVM arguments since Java 11. The javafx-maven-plugin adds these automatically. Trying to launch a JavaFX app with a plain java command or exec:java without these flags produces a cryptic "Error: JavaFX runtime components are missing" message.

Setting Up with Gradle

If you prefer Gradle, add the org.openjfx.javafxplugin plugin:

// build.gradle (Groovy DSL) plugins { id 'application' id 'org.openjfx.javafxplugin' version '0.1.0' } application { mainModule = 'com.example.hellofx' mainClass = 'com.example.hellofx.App' } javafx { version = '21' modules = [ 'javafx.controls', 'javafx.fxml' ] }

IDE Support

IntelliJ IDEA and Eclipse both support JavaFX projects. IntelliJ ships with a built-in JavaFX project wizard (File → New → Project → JavaFX) that generates the Maven/Gradle skeleton for you. The free Community Edition works, though the Ultimate Edition adds an FXML visual designer. Scene Builder — a standalone, free visual FXML editor from Gluon — integrates with both IDEs and lets you drag components onto a canvas and see the generated FXML in real time.

Do not add JavaFX JARs manually to the classpath. Manual JAR configuration worked before the module system but breaks in Java 11+. Always declare JavaFX as a Maven/Gradle dependency and let the build tool handle the module path. Manually adding JARs without the correct --module-path and --add-modules flags will give you a runtime error even though the classes are on the classpath.

JavaFX vs Swing — When to Choose Each

In a greenfield desktop project you should choose JavaFX. Swing is still maintained and still works, but it receives only critical bug fixes; all new GUI development from Oracle's side targets JavaFX. The main reasons to stay on Swing are: you are maintaining a large existing Swing codebase, or you need a third-party component library (e.g. JFreeChart) that does not yet have a JavaFX port. Both toolkits can coexist: SwingNode embeds Swing content inside a JavaFX scene, and JFXPanel embeds a JavaFX scene inside a Swing application.

Summary

JavaFX is the modern, hardware-accelerated, CSS-styleable, scene-graph-based GUI toolkit for Java. It supersedes Swing for new development and is available as a standalone Maven/Gradle dependency since Java 11. You set it up through the official OpenJFX dependency and the javafx-maven-plugin or Gradle plugin to get the required module-path arguments wired in automatically. In the next lesson you will write your first Application subclass and understand the JavaFX lifecycle that every desktop app follows.

ES
Edrees Salih
1 hour ago

We are still cooking the magic in the way!