Skip to content

bsommerfeld/jfx-frameless

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JFX Frameless

Modular window shell toolkit for JavaFX. Compose custom undecorated windows from building blocks: resize behavior, platform-native title bars, flexible layout slots.

Showcase
JFX-Frameless makes stunning UIs like this possible!

What it does

  • Transparent, undecorated windows with optional rounded corners
  • Platform-styled controls: macOS traffic lights, Windows 11 Fluent buttons
  • Edge-based resizing in all directions
  • Composable layout: title bar, sidebars, content, footer
  • JavaFX as provided - you bring your own runtime

Note on "Native" Controls: The window controls are styled to match platform conventions using JavaFX components (SVG + CSS). True OS-native controls with full hover behavior and system integration face JavaFX platform limitations. We're exploring solutions and welcome contributions! See Known Limitations below.

Requirements

  • Java 21+
  • JavaFX 21+

Installation

Maven:

<dependency>
    <groupId>de.bsommerfeld</groupId>
    <artifactId>jfx-frameless</artifactId>
    <version>0.1.1</version>
</dependency>

Gradle:

implementation 'de.bsommerfeld:jfx-frameless:0.1.1'

JavaFX is provided. Add javafx-controls (Maven: org.openjfx:javafx-controls:21, Gradle: same).

Usage

Minimal

new WindowShell(primaryStage)
    .withDefaultTitleBar()
    .withResizable()
    .withMinSize(400, 300)
    .withContent(new Label("Hello"))
    .show();

Builder

WindowShell window = WindowShellBuilder.create(stage)
    .defaultTitleBar()
    .resizable()
    .minSize(400, 300)
    .size(1200, 800)
    .cornerRadius(16)
    .content(myContent)
    .leftSidebar(navigation)
    .stylesheet(getClass().getResource("/css/app.css").toExternalForm())
    .build();

window.show();

Custom Title Bar

TitleBar titleBar = new TitleBar(stage)
    .withPlatformControls()
    .bindIcon()                     // binds to stage.getIcons()
    .bindTitle()                    // binds to stage.titleProperty()
    .withRightContent(settingsButton, themeToggle);

// Or with static values:
TitleBar titleBar = new TitleBar(stage)
    .withPlatformControls()
    .withIcon(myLogoNode)           // static node, null-safe
    .withTitle("My App");           // static string

new WindowShell(stage)
    .withTitleBar(titleBar)
    .withResizable()
    .withContent(myContent)
    .show();

Bare minimum

Skip features you don't need:

// No title bar, no resize, square corners
new WindowShell(stage)
    .withSquareCorners()
    .withContent(myContent)
    .show();

Layout Structure

StackPane (root, rounded clip)
  └─ BorderPane (layout)
       ├─ top: TitleBar
       ├─ left: sidebar
       ├─ center: StackPane (content)
       ├─ right: sidebar
       └─ bottom: footer

Components

Class Purpose
WindowShell Stage wrapper with fluent API
WindowShellBuilder Builder pattern alternative
TitleBar Draggable bar with left/center/right slots
MacOSControls Traffic light buttons
WindowsControls Fluent Design buttons
ResizeBehavior Edge detection + drag resize
OperatingSystem Runtime platform detection

Styling

Minimal default stylesheet at /css/frameless.css (optional):

shell.withStylesheet(getClass().getResource("/css/frameless.css").toExternalForm());

The default CSS provides only structural essentials (dimensions, layout). Colors and theming are left to your application's stylesheet.

CSS classes:

Class Element
.window-shell-root Root StackPane
.window-shell-layout BorderPane layout
.window-shell-content Content pane
.title-bar Title bar
.title-bar-title Title label
.title-bar-icon Icon node
.macos-controls macOS button group
.traffic-light-button macOS button
.windows-controls Windows button group
.window-control-button Windows button
.close-button Close button

JPMS

module your.app {
    requires de.bsommerfeld.jfx.frameless;
    requires javafx.controls;
}

Known Limitations

Window controls are platform-styled (JavaFX SVG/CSS), not OS-native. This means:

  • ✅ Look and feel matches platform conventions
  • ⚠️ Native hover behaviors (macOS traffic light symbols, Windows tooltips) are emulated
  • ⚠️ Some platform-specific interactions (e.g., macOS green button fullscreen popup) are not available

Why? JavaFX's StageStyle.TRANSPARENT removes native decorations, and accessing internal window handles requires non-public APIs. Apps like IntelliJ use JetBrains Runtime (patched JVM) for this.

Contributions welcome! If you have ideas or experience with native window integration, please open an issue or PR.

Contributing

Found a bug? Have an idea? Want to tackle the native controls challenge?

  1. Issues: Report bugs or suggest features at GitHub Issues
  2. Pull Requests: Contributions welcome! Please discuss major changes in an issue first
  3. Native Controls: This is our biggest challenge - any expertise appreciated!

License

MIT

About

Custom titlebars for JavaFX without sacrificing window resizing.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors