JavaFX 主題

Sheeraz Gul 2024年2月16日
JavaFX 主題

JavaFX 用於 GUI 設計。那裡有許多可用的主題,我們可以在這些主題上設計和構建我們的應用程式。

本教程將列出一些著名的 JavaFX 主題,並演示如何使用和操作它們來設計我們的應用程式。

JavaFX 主題列表

  • AeroFX:來自 GUIGARAGE 的 JavaFX 主題,它複製了 Windows 7 應用程式的外觀,請在此處進行檢查。
  • AquaFX:來自 GUIGARAGE 的 JavaFX 主題,它複製 Mac OS 應用程式的外觀,請檢視此處
  • Flatter:來自 GUIGARAGE 的平面設計 GUI 主題,請在此處檢視。
  • JMetro:受 Microsoft fluent 設計系統啟發的 JavaFX 主題,請檢視此處
  • jbootfx:使用 Bootstrap 進行響應式設計的 JavaFX 主題,請在此處檢視。
  • MaterialFX:用於 Google Material Design 外觀的 JavaFX 主題,請檢視此處
  • Flat Red:一個簡單的平面和紅色 JavaFX 主題,請檢視這裡

上面的大多數主題都需要 maven 支援才能將它們作為專案載入。讓我們使用簡單的 Flat Red 主題並嘗試操作它。

Flat Red,一個簡單的 Flat 和 Red JavaFX 主題

Flat Red 是 GitHub 上提供的一個簡單的 JavaFX 主題,提供不同的設計,可以根據我們的需要進行操作。讓我們先嚐試一些原件。

Flat Red 主題第 15 章中的 StyleButtons 將生成電話撥號檢視。

例子:

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);
  }
}

輸出:

電話

另一個來自 Flat Red 主題第 15 章的示例生成了一個互動式真假開關。

例子:

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);
  }
}

此示例包括在 Flat Red 的第 15 章中找到的另一個類。

輸出:

轉變

現在,讓我們嘗試操作 Flat Red Theme 中的一個示例;我們從第 15 章中選擇 LookNFeelChooser。

例子:

<?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>

上面的程式碼是第 15 章的 fxml,我們根據需要進行了編輯。

這個 fxml 的 Java 程式碼是:

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);
  }
}

上面的程式碼將生成一個框,該框將包含帶有按鈕、進度報告和其他選項的不同選單。

輸出:

選單

我們可以根據我們的要求使用任何主題;這些主題不限於上述列表。還有其他幾個選項,但這些是最常用的選項。

作者: 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