A lightweight JavaFX component library focused on flat visual style, theme switching, custom desktop window helpers, and reusable UI utilities.
It currently provides:
- Light and dark theme stylesheets
- Semantic CSS style classes and helper utilities
- Custom controls such as
Switch,Card,SVGButton, andPopupTextField - Desktop window helpers such as
AppStage,TransparentPane, andToastQueue - Common utility classes for config, async tasks, and resource lifecycle management
- Features
- Requirements
- Installation
- Quick Start
- Core Components
- Theme and Styling
- Desktop Window Helpers
- Utilities
- Project Structure
- Contributing
- License
- Flat UI styling for JavaFX controls and custom components
- Built-in
LightThemeandDarkTheme - Semantic style tokens via
Styles, such asaccent,success,danger,rounded, andelevated-* - Custom switch control with animated thumb and CSS-configurable label position
- Card-style control for quick dashboard and settings layouts
- SVG-based button and icon support
- Custom borderless desktop window wrapper with drag, resize, maximize, and system buttons
- Toast notification queue for lightweight feedback
- Helper classes for async background tasks, config storage, and automatic resource cleanup
- JDK
11+ - JavaFX
17.0.0.1 - Maven or Gradle
Notes:
- The library is compiled with Java 11 target compatibility.
- Your application should still configure JavaFX runtime dependencies for its own target platform.
<dependency>
<groupId>io.github.nonoas</groupId>
<artifactId>jfx-flat-ui</artifactId>
<version>1.0.3</version>
</dependency>implementation("io.github.nonoas:jfx-flat-ui:1.0.3")The repository does not currently ship with a standalone demo app, so the snippet below is a minimal integration example.
import github.nonoas.jfx.flat.ui.control.Card;
import github.nonoas.jfx.flat.ui.control.SVGPath;
import github.nonoas.jfx.flat.ui.control.Switch;
import github.nonoas.jfx.flat.ui.pane.SVGImage;
import github.nonoas.jfx.flat.ui.stage.ToastQueue;
import github.nonoas.jfx.flat.ui.theme.DarkTheme;
import github.nonoas.jfx.flat.ui.theme.LightTheme;
import github.nonoas.jfx.flat.ui.theme.Styles;
import github.nonoas.jfx.flat.ui.theme.Theme;
import java.util.Objects;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class DemoApp extends Application {
@Override
public void start(Stage primaryStage) {
applyTheme(new LightTheme());
var icon = new SVGImage(SVGPath.SETTING_BUTTON.value(), Color.web("#0969da"));
icon.setSize(18);
var card = new Card(
"JFX Flat UI",
"Flat-styled JavaFX controls and window helpers.",
icon
);
var themeSwitch = new Switch("Dark mode");
var toastButton = new Button("Show toast");
toastButton.getStyleClass().addAll(Styles.ACCENT, Styles.ROUNDED);
toastButton.setOnAction(e -> ToastQueue.show(primaryStage, "Saved successfully", 2000));
themeSwitch.selectedProperty().addListener((obs, oldValue, dark) -> {
applyTheme(dark ? new DarkTheme() : new LightTheme());
});
var root = new VBox(16, card, themeSwitch, toastButton);
root.setPadding(new Insets(24));
primaryStage.setScene(new Scene(root, 640, 360));
primaryStage.setTitle("jfx-flat-ui Demo");
primaryStage.show();
}
private void applyTheme(Theme theme) {
String stylesheet = Objects.requireNonNull(
getClass().getResource(theme.getUserAgentStylesheet())
).toExternalForm();
Application.setUserAgentStylesheet(stylesheet);
}
}| Component | Package | Description |
|---|---|---|
Switch |
...control |
Animated two-state toggle control with CSS support and ToggleGroup integration |
Card |
...control |
Lightweight card component with title, description, and graphic |
SVGButton |
...control |
Button with SVG graphic and hover color/background builder |
PopupTextField |
...control |
Text field with popup suggestion/content area |
AlignedTableColumn |
...control |
Table column with configurable header and cell alignment |
SVGImage |
...pane |
SVG-based icon/image node with size and fill control |
JustifiedFlowPane |
...pane |
Responsive pane that lays out items in evenly distributed rows |
Two built-in themes are included:
LightThemeDarkTheme
The CSS layer also exposes semantic style classes through github.nonoas.jfx.flat.ui.theme.Styles.
Common examples:
button.getStyleClass().addAll(Styles.ACCENT, Styles.ROUNDED);
deleteButton.getStyleClass().addAll(Styles.DANGER, Styles.BUTTON_OUTLINED);
textField.getStyleClass().add(Styles.LARGE);
container.getStyleClass().addAll(Styles.BG_SUBTLE, Styles.ELEVATED_1);Useful style categories include:
- State and intent:
ACCENT,SUCCESS,WARNING,DANGER - Shape and density:
ROUNDED,SMALL,MEDIUM,LARGE,DENSE - Surfaces:
BG_DEFAULT,BG_SUBTLE,BORDER_DEFAULT - Elevation:
ELEVATED_1toELEVATED_4 - Button variants:
BUTTON_ICON,BUTTON_CIRCLE,BUTTON_OUTLINED - Text helpers:
TITLE_1toTITLE_4,TEXT_MUTED,TEXT_SMALL
For advanced styling, Styles also includes helpers such as:
toggleStyleClass(...)addStyleClass(...)activatePseudoClass(...)appendStyle(...)removeStyle(...)toDataURI(...)
AppStage wraps a transparent JavaFX Stage and adds a desktop-app oriented shell:
- Transparent window root with rounded corners
- Built-in minimize, maximize, and close buttons
- Window drag support via
registryDragger(...) - Manual resize handling for borderless windows
- Optional custom content via
setContentView(...)
Minimal usage:
import github.nonoas.jfx.flat.ui.stage.AppStage;
import javafx.scene.Parent;
Parent root = createRootView();
Parent titleBar = createTitleBar();
AppStage appStage = new AppStage();
appStage.setTitle("My Desktop App");
appStage.setSize(960, 640);
appStage.setMinWidth(720);
appStage.setMinHeight(480);
appStage.setContentView(root);
appStage.registryDragger(titleBar);
appStage.show();For lightweight notifications, use:
ToastQueue.show(stage, "Operation completed", 2000);new TaskHandler<String>()
.whenCall(() -> loadDataFromService())
.andThen(result -> resultLabel.setText(result))
.handle();ConfigManager config = new ConfigManager("settings", "MyDesktopApp");
config.set("theme", "dark");
config.saveConfig();This stores data under a hidden app-specific directory in the user home by default.
If you want resources to be released automatically when the JavaFX application stops, extend AutoReleaseApplication and register resources through ResourceManager.
ResourceManager.getInstance().register(() -> socket.close());src/main/java/github/nonoas/jfx/flat/ui
├─ control # custom controls such as Switch, Card, SVGButton
├─ pane # layout and SVG-based visual nodes
├─ stage # window shell and toast helpers
├─ theme # theme contracts, themes, and style constants
├─ config # config persistence helper
├─ concurrent # async task helper
└─ utils # shared UI and color utilities
Issues and pull requests are welcome.
Recommended contribution flow:
- Fork the repository.
- Create a feature branch.
- Keep changes focused and documented.
- Add or update examples when API behavior changes.
- Open a pull request with a clear summary of motivation and impact.
This project is licensed under the Apache License 2.0.