JavaFX 25 Highlights
Kevin Rushforth on September 23, 2025JavaFX 25 is here with several new features and improvements! JavaFX 25 is designed to work with JDK 25, and is known to work with JDK 23 and later versions. Here are the highlights of the JavaFX 25 release:
- JavaFX controls in the title bar (Preview)
- RichTextArea (Incubator) : CSS styling of highlights
- CSS media feature queries
- TabStopPolicy for TextFlow
- Additional geometry-based Text / TextFlow APIs
- Text Layout API
JavaFX Controls in the Title Bar (Preview)
This preview feature defines a Stage
style in which the client area is extended into the header bar area, removing the separation between the two regions and allowing applications to place scene graph nodes in the header bar area of the Stage
.
The new feature provides the default header buttons (iconify, maximize, close), but no system-provided draggable header bar. Applications provide their own header bar by placing a HeaderBar
control in the scene graph, positioned at the top of the window. HeaderBar
automatically adjusts for the placement of the default window buttons on the left or right side of the window.
Here is a simple example:
public class HeaderBarApp extends Application {
@Override
public void start(Stage stage) {
var button = new Button("My button");
HeaderBar.setAlignment(button, Pos.CENTER_LEFT);
HeaderBar.setMargin(button, new Insets(5));
var headerBar = new HeaderBar();
headerBar.setCenter(button);
var root = new BorderPane();
root.setStyle("-fx-background: #afafbf;");
root.setTop(headerBar);
var scene = new Scene(root, 200, 150);
scene.setFill(Color.web("afafbf"));
stage.setScene(scene);
stage.initStyle(StageStyle.EXTENDED);
stage.show();
}
}
This example produces the following results on Windows and macOS.
Figure 1: Extended Stage with HeaderBar on Windows
Figure 2: Extended Stage with HeaderBar on macOS
To try this preview feature you need to run the example with java -Djavafx.enablePreview=true ...
on the command line.
RichTextArea (Incubator) : CSS Styling of Highlights
Applications can now style RichTextArea
highlights using CSS. JavaFX 25 added new overloads for the following methods that take a list of CSS style names:
RichParagraph::addHighlight
RichParagraph::addWavyUnderline
SimpleViewOnlyStyledModel::highlight
SimpleViewOnlyStyledModel::addWavyUnderline
CSS Media Feature Queries
This feature adds media queries to JavaFX CSS, a powerful component that enables stylesheets to dynamically test specific aspects of the JavaFX scene. Media queries are independent of the contents of the scene graph, its styling, or any other internal aspect; they’re only dependent on the “external” configuration of the scene. The following example stylesheet uses a media query:
.button {
-fx-background-color: lightgray;
-fx-text-fill: black;
}
@media (prefers-color-scheme: dark) {
.button {
-fx-background-color: darkgray;
-fx-text-fill: white;
}
}
In the example above, the button’s background and foreground colors will change at runtime when the preferred color scheme is changed to dark. Since a media query can contain arbitrary CSS rules, all aspects of styling can be adjusted.
TabStopPolicy for TextFlow
TabStopPolicy
provides a way for applications to define tab stops based on a geometric position in the text line rather than a fixed number of characters. This makes it suitable for both proportional and monospaced fonts while offering better support for rich text.
Here is a code snippet showing how to add tab stops to your TextFlow
:
var str1 = "This is...\t";
var str2 = "a test\tof tabs";
TextFlow flow = createTextFlow(str1, str2);
// Create tab stops
var stops = List.of(
new TabStop(25),
new TabStop(90),
new TabStop(180)
);
// Create tab stop policy
var tsPolicy = new TabStopPolicy();
tsPolicy.tabStops().addAll(stops);
flow.setTabStopPolicy(tsPolicy);
And below you can observe the example output. The light green vertical lines were added to show where the tab stops are.
Additional Geometry-Based Text / TextFlow APIs
JavaFX 25 added new geometry-based methods to Text
and TextFlow
.
This was done to provide missing APIs as well as the ability to properly account for insets and padding in TextFlow
.
Class | Methods |
---|---|
Text | getRangeShape, getStrikeThroughShape |
TextFlow | getHitInfo, getCaretShape, getRangeShape, getUnderlineShape, getStrikeThroughShape |
Text Layout API
This feature provides a new LayoutInfo
object that holds a snapshot of the text layout geometry in a Text
or TextFlow
node. This includes a list of text lines, shapes derived from the layout (for example, selection, underline, strike-through), and caret information.
For example:
Text textNode = createTextNode();
// Get the layout info for this text node and print the text lines
var layoutInfo = textNode.getLayoutInfo();
layoutInfo.getTextLines(false)
.stream()
.forEach(System.out::println);
Other Changes
Checkout the JavaFX 25 Release Notes for a complete list of important changes, new features, enhancements, and bug fixes. See also the API docs for a list of new APIs and deprecated APIs in each release.
Call to Action
We invite you to download JavaFX 25 today from jdk.java.net/javafx25 and use it to build and run your applications.
Please send feedback to openjfx-dev@openjdk.org (registration required).
We especially welcome feedback on the JavaFX Preview API (controls in the title bar) and Incubating APIs (RichTextArea
and InputMap
), as we evolve those APIs towards finalization.