HOWTO · Java

JavaFX 主題

本教程演示如何使用 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);
  }
}

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

輸出:

選單

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