はじめに
最近のディスクトップアプリケーションは、ウインドウのタイトルバーにコントロールを配置するものが増えてきました。Electron 系だと一般的ですね。
例えば VS Code のタイトルバーは以下のようになっています。

JavaFX でこのようなタイトルバーを実現するには、StageStyle.UNDECORATED で装飾無しのウインドウを作成し、タイトルバーを自作するしかありませんでした。
JavaFX 25 では、プレビュー版ではありますが、タイトルバーにコントロールを配置する機能が追加されました。
タイトルバーのカスタマイズ
タイトルバーをカスタマイズするには JavaFX 25 で追加された javafx.scene.layout.HeaderBar にコントロールを追加し、
var headerBar = new HeaderBar(); headerBar.setLeading(node1); headerBar.setCenter(node2); headerBar.setTrailing(node3);
HeaderBar を BorderPane に追加し、stage.initStyle(StageStyle.EXTENDED) を指定するだけです。
var root = new BorderPane(); root.setTop(headerBar); Scene scene = new Scene(root); stage.setScene(scene); stage.initStyle(StageStyle.EXTENDED);
サンプルアプリケーション
build.gradle.kts を設定します。
org.openjfx.javafxplugin プラグインで JavaFX 25 を導入します。
plugins {
application
id("org.openjfx.javafxplugin") version "0.1.0"
}
repositories {
mavenCentral()
}
dependencies {
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(25)
}
}
application {
mainClass = "org.example.App"
applicationDefaultJvmArgs = listOf(
"-Djavafx.enablePreview=true",
"--enable-native-access=javafx.graphics",
)
}
javafx {
version = "25"
modules("javafx.controls")
}
プレビュー機能を有効にするため、アプリケーションプラグインの設定で -Djavafx.enablePreview=true を指定する必要があります。
org.openjfx.javafxplugin プラグインを使う場合、現時点では gradle.properties にて configuration-cache を無効にする必要があります。
org.gradle.configuration-cache=false
アプリケーションは以下のように実装します。
package org.example; import javafx.application.Application; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HeaderBar; import javafx.stage.Stage; import javafx.stage.StageStyle; public class App extends Application { @Override public void start(Stage stage) { var textField = new TextField(); textField.setPromptText("Search..."); textField.setMaxWidth(300); HeaderBar.setMargin(textField, new Insets(5, 10, 5, 10)); HeaderBar.setAlignment(textField, Pos.TOP_CENTER); var headerBar = new HeaderBar(); headerBar.setCenter(textField); var root = new BorderPane(); root.setTop(headerBar); var text = new Label("Hello, JavaFX"); text.setFocusTraversable(true); root.setCenter(text); Scene scene = new Scene(root, 700, 300); stage.setScene(scene); stage.initStyle(StageStyle.EXTENDED); stage.show(); text.requestFocus(); } public static void main(String[] args) { launch(); } }
サンプルアプリケーションの実行
サンプルアプリケーションを実行してみましょう。
./gradlew run
以下のようにタイトルバーにコントロールが表示されます。

Windows の場合は以下のようになります。

なお、タイトルバーは、 OS ではなくJavaFX側で描画しているため、例えばタイトルバーの色などの指定は、自身で行う必要があります(最大化・最小化・コンテキストメニューなどの挙動は JavaFX 側でよしなに処理してくれます)。