Nodes & Scene Graph Structure
Nodes & Scene Graph Structure
The previous lesson introduced the scene graph as a tree of Node objects. This lesson dissects that tree in detail: what kinds of nodes exist, how parent and leaf nodes relate to each other, how the graph is assembled in code, and why that structure drives rendering, layout, and event delivery in JavaFX.
Two Fundamental Kinds of Node
Every element in a JavaFX scene inherits from the abstract class javafx.scene.Node. That class is then split into two branches:
- Parent nodes — subclasses of
javafx.scene.Parent. They have an observable list of children and are responsible for laying out those children. You never instantiateParentdirectly; you work with concrete subclasses likeGroup,Region,Pane,VBox, orHBox. - Leaf nodes — direct subclasses of
Nodethat cannot have children. Shapes (Rectangle,Circle,Line),ImageView,Canvas, andMediaVieware all leaf nodes.
Button, TextField, and ListView extend Control, which extends Region, which extends Parent. They are therefore parent nodes internally — they contain their own skin nodes — but you treat them as leaf nodes from the perspective of your scene graph because you do not add children to them directly.
The Node Ownership Rule
A node can belong to at most one parent at a time. If you add a node that already has a parent to a different container, JavaFX will throw an IllegalArgumentException at runtime. This single-parent invariant is what keeps the tree structure well-defined and allows the renderer to traverse it predictably.
Building the Graph in Code
The simplest container is Group. It applies no layout logic — children are positioned by their own layoutX/layoutY or transform properties. A StackPane stacks its children on top of each other, centred by default. An HBox arranges children in a horizontal row; a VBox arranges them vertically.
Here is a small scene graph built entirely in Java:
The resulting tree looks like this:
VBox(root / scene root)Label— "Scene Graph Demo"Circle— radius 20HBoxButton— "OK"Button— "Cancel"
The Children List
Every Parent exposes its children through getChildren(), which returns an ObservableList<Node>. You can manipulate this list at any time on the JavaFX Application Thread and the scene graph updates immediately:
Because the list is observable, the layout system listens for changes and schedules a layout pass automatically. You never call a manual "refresh" method.
How Structure Drives Rendering and Layout
The scene graph is not just a data structure — it is the engine that drives three JavaFX subsystems:
- Rendering (painting order): nodes are painted in depth-first, pre-order traversal — parent before children, siblings in list order. A node drawn later appears on top. Changing a node's position in the children list changes its visual stacking.
- Layout: each
Parentcomputes the size and position of its children during a layout pass. The pass starts at the root and recurses down. Leaf nodes report their preferred size; parents allocate space according to their own rules (HBoxstacks horizontally,GridPaneplaces on a grid, etc.). - Event propagation: mouse and keyboard events travel the tree in two phases — capture (root → target) and bubbling (target → root). Understanding the tree shape tells you exactly which nodes receive an event and in what order.
StackPane or Group containers. If a container serves no layout or visual purpose, remove it.
Group vs Region — Choosing the Right Parent
Group and Region are the two base parent classes you will choose between most often:
Group— no layout, no background, no padding. Its size equals the collective bounds of its children. Use it for drawing surfaces, animation targets, or when you want to apply a single transform to a set of shapes.Region(and its subclassesPane,VBox,HBox,BorderPane,GridPane, etc.) — has a background, padding, border, and CSS styling. Use it for all UI layout work.
Coordinate Systems and Transforms
Each node has its own local coordinate system. A parent's coordinate system is the parent space that its children are placed in. When you set node.setLayoutX(50), you are positioning the node 50 pixels from the left of its parent's origin, not from the scene's origin. Transforms (Translate, Rotate, Scale) applied to a parent cascade to all its children, which is why grouping shapes into a Group and then rotating the group rotates all of them together.
Summary
The JavaFX scene graph divides nodes into parents (which can contain children) and leaves (which cannot). The ObservableList returned by getChildren() is the live structure of the tree; changes to it immediately drive layout, rendering, and event routing. Choosing the right container — Group for raw drawing, a Region subclass for UI layout — determines how your application positions and sizes its content. With this model understood, you can build any UI by composing nodes into a tree rather than manually calculating pixel coordinates.