JavaFX Themes

Sheeraz Gul Feb 16, 2024
JavaFX Themes

JavaFX is used for the GUI design. Many themes are available out there on which we can design and build our application.

This tutorial will list some famous JavaFX themes and demonstrates how to use and manipulate them to design our application.

List of JavaFX Themes

  • AeroFX: A JavaFX theme from GUIGARAGE which copies the windows 7 applications look, check it here.
  • AquaFX: A JavaFX theme from GUIGARAGE which copies the Mac OS applications look, check it here.
  • Flatter: A flat-design GUI theme from GUIGARAGE, check it here.
  • JMetro: A JavaFX theme inspired by Microsoft’s fluent design system, check it here.
  • jbootfx: A JavaFX theme which uses bootstrap for responsive design, check it here.
  • MaterialFX: A JavaFX theme for Google Material Design appearance, check it here.
  • Flat Red: A simple flat and red JavaFX theme, check it here.

Most of the themes above require maven support to load them as a project. Let’s use the simple Flat Red theme and try to manipulate it.

Flat Red, a Simple Flat and Red JavaFX Theme

Flat Red is a simple JavaFX theme provided on GitHub, offering different designs which can be manipulated according to our needs. Let’s try some originals first.

StyleButtons from Chapter 15 of the Flat Red theme will generate a phone dial view.

Example:

package jfx9be;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;

public class StyleButtons extends Application {
  @Override
  public void start(Stage primaryStage) {
    BorderPane root = new BorderPane();
    Scene scene = new Scene(root, 180, 250);
    scene.getStylesheets().add(getClass().getResource("mobile_buttons.css").toExternalForm());
    String[] keys = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#"};
    GridPane numPad = new GridPane();
    numPad.getStyleClass().add("num-pad");

    for (int i = 0; i < 12; i++) {
      Button button = new Button(keys[i]);
      button.getStyleClass().add("num-button");
      numPad.add(button, i % 3, (int) Math.ceil(i / 3));
    }
    // Call button
    Button call = new Button("Call");
    call.setId("call-button");
    call.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
    numPad.add(call, 0, 4);
    GridPane.setColumnSpan(call, 3);

    GridPane.setHgrow(call, Priority.ALWAYS);
    root.setCenter(numPad);
    primaryStage.setScene(scene);
    primaryStage.show();
  }

  public static void main(String[] args) {
    launch(args);
  }
}

Output:

Phone

Another example from Chapter 15 of Flat Red theme generates an interactive true false switch.

Example:

package jfx9controls.csspseudoclass;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Demo extends Application {
  private MyCtrl myCtrl;
  private ToggleButton buttonInteractive;

  @Override
  public void init() {
    myCtrl = new MyCtrl();
    buttonInteractive = new ToggleButton("Interactive: false");
    registerListeners();
  }

  private void registerListeners() {
    buttonInteractive.setOnAction(actionEvent -> {
      myCtrl.setInteractive(!myCtrl.isInteractive());
      buttonInteractive.setText("Interactive: " + (myCtrl.isInteractive() ? "true" : "false"));
    });
  }

  @Override
  public void start(Stage stage) throws Exception {
    VBox pane = new VBox();
    pane.setPadding(new Insets(10, 10, 10, 10));
    pane.setAlignment(Pos.CENTER);
    pane.setSpacing(10);
    pane.getChildren().addAll(myCtrl, buttonInteractive);
    VBox.setMargin(myCtrl, new Insets(10, 10, 10, 10));

    Scene scene = new Scene(pane);

    stage.setTitle("CSS PseudoClass");
    stage.setScene(scene);
    stage.show();
  }

  @Override
  public void stop() {}

  public static void main(final String[] args) {
    Application.launch(args);
  }
}

This example includes one more class found in Chapter 15 of Flat Red.

Output:

Switch

Now, let’s try to manipulate one example from the Flat Red Theme; we select LookNFeelChooser from Chapter 15.

Example:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="427.0" prefWidth="596.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children> <Accordion layoutX="102.0" layoutY="129.5" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns:fx="http://javafx.com/fxml">
    <panes>
        <TitledPane animated="false" text="Theme Demo Buttons">
            <content>
                <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children> <GridPane layoutX="38.5" layoutY="82.5" prefHeight="259.0" prefWidth="421.0" xmlns:fx="http://javafx.com/fxml">
    <columnConstraints>
        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
    </columnConstraints>
    <rowConstraints>
        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
    </rowConstraints>
<children> <RadioButton mnemonicParsing="false" selected="true" text="Radio_Button" GridPane.columnIndex="0" GridPane.rowIndex="1" /><Button mnemonicParsing="false" text="Demo Button" GridPane.columnIndex="0" GridPane.rowIndex="0" /><ToggleButton mnemonicParsing="false" text="Toggle_Button" GridPane.columnIndex="1" /><CheckBox layoutX="147.7890625" layoutY="74.5" mnemonicParsing="false" selected="true" text="CheckBox" GridPane.columnIndex="1" GridPane.rowIndex="1" />
</children>
</GridPane>
</children> </AnchorPane>
            </content>
        </TitledPane>
        <TitledPane animated="false" text="Progress Controls">
            <content>
                <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children> <ProgressBar layoutX="88.0" layoutY="55.0" prefWidth="200.0" progress="0.98" /><ProgressIndicator layoutX="168.5" layoutY="99.0" progress="0.98" />
</children> </AnchorPane>
            </content>
        </TitledPane> <TitledPane animated="false" text="Scroll Bars &amp; Sliders" xmlns:fx="http://javafx.com/fxml">
    <content>
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children> <ScrollBar layoutX="94.0" layoutY="31.0" prefHeight="14.0" prefWidth="312.0" /><ScrollBar layoutX="33.0" layoutY="29.0" orientation="VERTICAL" prefHeight="210.0" prefWidth="14.0" /><Slider layoutX="94.0" layoutY="145.0" prefHeight="14.0" prefWidth="310.0" /><Slider layoutX="463.0" layoutY="36.0" orientation="VERTICAL" prefHeight="206.0" prefWidth="14.0" />
</children> </AnchorPane>
    </content>
</TitledPane>
    </panes>
</Accordion>
</children> </AnchorPane>

The code above is the fxml from Chapter 15, which we edited according to our needs.

The Java code for this fxml is:

package application;

import java.io.IOException;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.stage.Stage;

public class Java_FX_Example extends Application {
  @Override
  public void init() {
    Font.loadFont(LookNFeelChooser.class.getResourceAsStream("Roboto-Thin.ttf"), 10).getName();
    Font.loadFont(LookNFeelChooser.class.getResourceAsStream("Roboto-Light.ttf"), 10).getName();
  }

  @Override
  public void start(Stage primaryStage) throws IOException {
    BorderPane root_border_pane = new BorderPane();
    Parent Parent_content = FXMLLoader.load(getClass().getResource("lnf_demo.fxml"));
    Scene Demo_scene = new Scene(root_border_pane, 650, 550, Color.WHITE);
    root_border_pane.setCenter(Parent_content);

    // Theme Menu bar
    MenuBar Demo_menu_Bar = new MenuBar();

    // Theme  file menu
    Menu Demo_file_Menu = new Menu("_File");
    MenuItem Menu_exit_Item = new MenuItem("Close");
    Menu_exit_Item.setAccelerator(new KeyCodeCombination(KeyCode.X, KeyCombination.SHORTCUT_DOWN));
    Menu_exit_Item.setOnAction(ae -> Platform.exit());

    Demo_file_Menu.getItems().add(Menu_exit_Item);
    Demo_menu_Bar.getMenus().add(Demo_file_Menu);

    // Look and feel menu
    Menu JFXPBE_Menu = new Menu("_JFXBE_Example");
    JFXPBE_Menu.setMnemonicParsing(true);
    Demo_menu_Bar.getMenus().add(JFXPBE_Menu);
    root_border_pane.setTop(Demo_menu_Bar);

    // Look and feel selection
    MenuItem option1_Menu_Item = new MenuItem("Option 1");
    option1_Menu_Item.setOnAction(ae -> {
      Demo_scene.getStylesheets().clear();
      // setUserAgentStylesheet(null);
      setUserAgentStylesheet(STYLESHEET_CASPIAN);
    });
    MenuItem option2_Menu_Item = new MenuItem("Option 2");
    option2_Menu_Item.setOnAction(ae -> {
      Demo_scene.getStylesheets().clear();
      // setUserAgentStylesheet(null);
      setUserAgentStylesheet(STYLESHEET_MODENA);
    });
    MenuItem option3_Menu_Item = new MenuItem("Option 3");
    option3_Menu_Item.setOnAction(ae -> {
      Demo_scene.getStylesheets().clear();
      setUserAgentStylesheet(null);
      Demo_scene.getStylesheets().add(getClass().getResource("controlStyle1.css").toExternalForm());
    });
    MenuItem option4_Menu_Item = new MenuItem("Option 4");
    option4_Menu_Item.setOnAction(ae -> {
      Demo_scene.getStylesheets().clear();
      setUserAgentStylesheet(null);
      Demo_scene.getStylesheets().add(getClass().getResource("controlStyle2.css").toExternalForm());
    });

    MenuItem option5_Menu_Item = new MenuItem("Option 5");
    option5_Menu_Item.setOnAction(ae -> {
      Demo_scene.getStylesheets().clear();
      setUserAgentStylesheet(null);
      Demo_scene.getStylesheets().add(getClass().getResource("sky.css").toExternalForm());
    });

    MenuItem option6_Menu_Item = new MenuItem("Option 6");
    option6_Menu_Item.setOnAction(ae -> {
      Demo_scene.getStylesheets().clear();
      setUserAgentStylesheet(null);
      Demo_scene.getStylesheets().add(getClass().getResource("flatred.css").toExternalForm());
    });

    JFXPBE_Menu.getItems().addAll(option1_Menu_Item, option2_Menu_Item, option3_Menu_Item,
        option4_Menu_Item, option5_Menu_Item, option6_Menu_Item);

    primaryStage.setTitle("JAVA_FX Themes Example");
    primaryStage.setScene(Demo_scene);
    primaryStage.show();
  }

  public static void main(String[] args) {
    launch(args);
  }
}

The code above will generate a box that will contain different menus with buttons, progress reports, and other options.

Output:

Menu

We can use any theme based on our requirements; these themes are not limited to the above list. There are several other options, but these are the most commonly used ones.

Author: Sheeraz Gul
Sheeraz Gul avatar Sheeraz Gul avatar

Sheeraz is a Doctorate fellow in Computer Science at Northwestern Polytechnical University, Xian, China. He has 7 years of Software Development experience in AI, Web, Database, and Desktop technologies. He writes tutorials in Java, PHP, Python, GoLang, R, etc., to help beginners learn the field of Computer Science.

LinkedIn Facebook