在JavaFX应用程序中添加外部CSS文件
你是否在为JavaFX应用程序添加外部CSS文件或将外部设计的样式表链接到你的程序中时遇到困难?在这篇文章中,我们将探讨如何解决这些问题。
当人们决定对JavaFX应用程序进行样式设计时,挑战就来了。这是一个繁琐的程序,因为每个元素都需要它的样式。设计师要记住以前在不同元素上使用的样式,这个问题一再出现。
在FXML文件中,也很难跟上代码中的样式,因为它不是连续的。你可能也注意到,在造型过程中使用的关键词与HTML文件的关键词不同。
主要收获
在文章的最后,读者应该知道。
- 使用变量保存一个重复的样式以方便在其他元素上使用。
- 在应用程序中添加一个外部样式表。
- 通过添加JavaFX类来引用样式表中的元素。
- 将样式表链接到许多场景中。
前提条件
要学习这篇文章,你将需要。
- 在你的机器上安装Java开发工具包。建议使用市场上最新的JDK。本文使用的是JDK 17。
- 一个好的Java IDE。建议使用最新版本的IntelliJ终极版。因为它有对JavaFX的支持。本文使用了IntelliJ版本
2021.2.2。 - 一个良好的互联网连接。这是用来获取快速开发的索引的。它也将在项目的生成中使用。
先决条件可以随着时间的变化而改变,从文章发表的那一天开始。请确保跟进所述技术的最新版本。所用的应用程序的外观也可能根据发布日期的不同而变化。
塑造JavaFX应用程序风格的方法
一个JavaFX应用程序可以使用不同的风格进行定制。这些风格包括以下几种。
- 使用内部样式。这是由SceneBuilder默认提供的。
- 使用预先保存的变量。这些变量可以被重复使用,从而减少FXML文件中的代码重复。
- 使用外部CSS文件。这个文件可以根据项目的要求进行定制。它减少了代码的重复和错误。
在这篇文章中,上述所有内容将在一个JavaFX应用程序中演示。要做到这一点,我们将遵循以下步骤。
- 设计一个JavaFX登录应用程序的样本。
- 使用正常的内部样式为JavaFX应用程序设计样式。
- 使用预先保存的样式变量为应用程序添加样式。
- 使用一个外部CSS文件来应用样式。
创建一个新的JavaFX文件
- 到IDE去。打开它,点击创建新项目按钮。在下面的图片中查看一下。

- 选择BootstrapFX、ControlsFX和FormsFX作为项目的依赖项。这些都显示在下面的图片中。

文件夹结构
应用程序的文件夹结构如下图所示。
.
├── src
│ └── main
│ ├── java
│ └── com.login
│ ├── javafxstyle
│ ├── HelloApplication.java
│ └── HelloController.java
| └── module-info.java
│ └── resources
│ └── com.login.javafxstyle
│ └── hello-view.fxml
├── target
├── javafx-style.iml
└── pom.xml
在FXML应用程序内添加代码
在上述文件夹结构中显示的HelloController.java 文件内删除以下代码。
@FXML
private Label welcomeText;
@FXML
protected void onHelloButtonClick() {
welcomeText.setText("Welcome to JavaFX Application!");
}
这将删除应用程序中 "Hello按钮 "的功能。
使用SceneBuilder删除包含Hello button 和hello-view.fxml 文件中的Label的V-Box ,如下图所示。

如果没有安装SceneBuilder,请在这里查看如何在IntelliJ中安装和配置它。
这篇文章还展示了如何在IntelliJ终极版上设置JavaFX。如果出现任何错误,请确保重新启动IDE。
上面的步骤删除了文件中的这段代码。
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
fx:controller="com.example.demo.HelloController">
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
</padding>
<Label fx:id="welcomeText"/>
<Button text="Hello!" onAction="#onHelloButtonClick"/>
</VBox>
下载login.png 图像。将图像复制粘贴到hello-view.fxml 文件所在的位置。复制下面的代码,并将其粘贴到被删除的代码所在的hello-view.fxml 文件中。
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.2"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.login.javafxstyle.HelloController">
<children>
<Label fx:id="loginTitleLabel" layoutX="430.0" layoutY="35.0" text="Login"/>
<ImageView fitHeight="400.0" fitWidth="325.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@login.png"/>
</image>
</ImageView>
<Label fx:id="enterDetailsLabel" layoutX="330.0" layoutY="120.0" text="Enter the login details below:"/>
<Label fx:id="usernameLabel" layoutX="333.0" layoutY="160.0" text="Username:"/>
<TextField fx:id="usernameTextField" layoutX="415.0" layoutY="157.0" promptText="john.doe@email.com"/>
<Label fx:id="passwordLabel" layoutX="333.0" layoutY="198.0" text="Password:"/>
<PasswordField fx:id="passwordPasswordField" layoutX="415.0" layoutY="195.0" promptText="********"/>
<CheckBox fx:id="rememberMeCheckBox" layoutX="375.0" layoutY="245.0" mnemonicParsing="false"
text="Remember me?"/>
<Label fx:id="errorLabel" layoutX="387.0" layoutY="280.0" prefHeight="16.0" prefWidth="171.0"
text="Sign in error!"/>
<Button fx:id="cancelButton" layoutX="370.0" layoutY="310.0" mnemonicParsing="false" text="Cancel"/>
<Button fx:id="signInButton" layoutX="490.0" layoutY="310.0" mnemonicParsing="false" text="Sign in"/>
<Button fx:id="forgotPasswordButton" layoutX="400.0" layoutY="350.0" mnemonicParsing="false"
text="Forgot password?"/>
</children>
</AnchorPane>
当使用SceneBuilder查看时,该步骤产生以下输出。

前往HelloApplication.java 文件,并确保将场景尺寸设置为600 x 400。
Scene scene=new Scene(fxmlLoader.load(),600,400);
给应用程序添加样式
如前所述,有三种方法可以定制应用程序的外观。
1.添加内部造型
它可以通过两种方式实现。
- 通过把它硬编码到应用程序中。
- 通过使用SceneBuilder。
硬编码
打开FXML文件。点击左下角靠近状态栏的Text 选项,以文本格式查看窗口。在文件中,在fx:id为loginTitleLabel的标签下,添加以下样式。
<Label fx:id="loginTitleLabel" layoutX="430.0" layoutY="35.0"
style="-fx-font-size: 40; -fx-text-fill: linear-gradient(from 0% 0% to 100% 200%, repeat, aqua 0%, red 50%); -fx-font-weight: BOLD;"
text="Login" textFill="#31ebfc"/>
这个样式使它变得巨大和粗体,并在其中填充一些线性梯度。
在fx:id为enterDetailsLabel 的标签中,添加以下样式。
<Label fx:id="enterDetailsLabel" layoutX="330.0" layoutY="120.0"
style="-fx-text-fill: #727272; -fx-font-size: 15; -fx-font-weight: BOLD;"
text="Enter the login details below:"/>
在fx:id为usernameLabel 和passwordLabel 的标签中,分别添加以下内容。
<Label fx:id="usernameLabel" layoutX="333.0" layoutY="160.0"
style="-fx-text-fill: #727272; -fx-font-size: 15;"
text="Username:"/>
和
<Label fx:id="passwordLabel" layoutX="333.0" layoutY="198.0"
style="-fx-text-fill: #727272; -fx-font-size: 15;"
text="Password:"/>
- 给复选框添加以下样式。
<CheckBox fx:id="rememberMeCheckBox" layoutX="375.0" layoutY="245.0" mnemonicParsing="false"
style="-fx-text-fill: #727272;" text="Remember me?"/>
在fx:id为errorLabel 的标签上添加以下样式。
<Label fx:id="errorLabel" layoutX="387.0" layoutY="280.0" prefHeight="16.0" prefWidth="171.0"
style="-fx-text-fill: red;" text="Sign in error!"/>
至于其余的按钮,下面将是它们的样式。
<Button fx:id="cancelButton" layoutX="370.0" layoutY="310.0" mnemonicParsing="false"
onAction="#onCancelButtonClick"
style="-fx-background-color: #4385F4; -fx-text-fill: white; -fx-font-size: 13;" text="Cancel"/>
<Button fx:id="signInButton" layoutX="490.0" layoutY="310.0" mnemonicParsing="false"
onAction="#onSignInButtonClick"
style="-fx-background-color: #4385F4; -fx-text-fill: white; -fx-font-size: 13;" text="Sign in"/>
<Button fx:id="forgotPasswordButton" layoutX="400.0" layoutY="350.0" mnemonicParsing="false"
style="-fx-background-color: transparent; -fx-text-fill: #727272;" text="Forgot password?"
underline="true"/>
onAction属性将按钮链接到控制器中的一个函数。在一个触发事件中,比如点击按钮,该函数会被执行。
打开HelloController 类,粘贴下面的代码。请确保添加所需的导入。
/*Import JavaFX controls*/
@FXML
Button cancelButton, signInButton;
@FXML
Label errorLabel, loginTitleLabel;
@FXML
TextField usernameTextField;
@FXML
PasswordField passwordPasswordField;
/*Close the scene once the cancel button is clicked*/
@FXML
protected void onCancelButtonClick() {
Stage stage = (Stage) cancelButton.getScene().getWindow();
stage.close();
}
/* Make the label with the fx:id of 'errorLabel' change its text and color on Sign in Button click */
@FXML
protected void onSignInButtonClick() {
errorLabel.setText("Sign In Success!");
errorLabel.setStyle("-fx-text-fill: GREEN;");
}
通过HelloApplication.java 文件运行该应用程序,如下图所示。

输出看起来如下图所示。

正如我们所看到的,该应用程序如期运行。
使用SceneBuilder
使用SceneBuilder选项打开FXML文件,该选项位于窗口左下方靠近状态栏的位置。
要为应用程序中使用的控件添加样式,请点击所需的控件。在本例中,从fx:id 的标签开始,loginTitleLabel 。
在右侧的标签上,在属性部分下,注意SceneBuilder会自动识别设置在该元素上的可用格式。
勾选下划线的复选框。在样式部分,通过点击+ 符号添加以下属性。
-fx-background-color:#f3f3f3-fx-border-radius:5-fx-border-color:linear-gradient(from 0% 0% to 100% 200%, repeat, aqua 0%, red 50%)
属性选项卡中的SceneBuilder造型部分将看起来如下。

点击Remember me 复选框,选择Selected 选项。运行该应用程序。
它产生的输出如下。

正如所见,SceneBuilder在属性、布局和代码标签中提供了更多的选项。使用这种方法添加造型非常简单,因为有GUI的支持。
2.使用预先保存的变量
要做到这一点,造型将被存储在变量中。这些变量将是可重复使用的代码片段。它们可以减少代码错误,特别是当造型较长且难以记忆的时候。
打开应用程序中的控制器。在控件的导入上面,添加变量,为应用程序保存样式。
String successStyle = String.format("-fx-border-color: #4fd800; -fx-border-width: 2; -fx-border-radius: 5;");
String successStyleGradient = String.format("-fx-text-fill: #4fd800;");
现在,使用这些变量为页面的不同组件设置样式。一个例子是TextField和PasswordField。
将下面的代码粘贴在其他函数下面的onSignInButtonClick 。
usernameTextField.setStyle(successStyle);
passwordPasswordField.setStyle(successStyle);
signInButton.setStyle(successStyleGradient);
运行该应用程序。当点击Sign-In button ,输出结果如下所示。

从上面的步骤可以看出,造型可以在项目中快速重复使用,以获得高效的代码。它使开发人员的开发变得容易,特别是在有许多不同元素的预设样式的大型项目中。
3.使用外部CSS文件
当涉及到高级造型时,最好使用这种造型。它不仅易于管理,而且还支持代码的可读性。
有两种方法可以将外部样式表添加到程序中。这两种方法是:
- 通过
HelloApplication.java文件来添加它。 - 通过SceneBuilder或硬编码来添加它。
让我们快速看一下这两种方法。
1.通过主类文件添加
要添加它,在FXML文件的位置创建一个新的CSS文件。在HelloApplication.java 文件中,添加下面这行代码。
scene.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());
这将把styles.css 文件中的样式应用到创建的场景中。
2.通过SceneBuilder或硬编码来添加它
SceneBuilder将一个特定的样式表样式添加到应用程序中的一个特定控件上。这种添加方式与上面提到的使用场景风格化的方式不同,后者是将风格化添加到整个场景中。
因此,人们需要反复地重复这些步骤。
- 在SceneBuilder视图中,点击首先添加的AnchorPane。
- 在属性标签中,在 "JavaFX CSS "部分,点击 "Stylesheets "选项。
- 选择CSS文件,就可以了。
人们也可以通过链接它们来应用某个特定类的样式来控制应用程序。
这种链接可以通过在SceneBuilder中 "JavaFX CSS "部分的 "Styles Class "选项中向控件添加CSS类来实现。该类可以与应用程序已知的类不同。它可以被定义在添加到控件或场景的样式表中。这将在本文后面的代码中显示。
当AnchorPane的CSS类被设置为 "唯一 "时,它产生的代码如下所示,在文本视图中可以看到。
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0"
styleClass="unique" xmlns="http://javafx.com/javafx/11.0.2" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.login.javafxstyle.HelloController">
在添加任何样式之前,首先让我们看看样式格式是什么样子的。
外部样式设置格式
对于外部CSS样式,如果想引用组件的名称(fx:id),他们会在样式前使用一个# 符号。该格式如下所示。
#titleLabel {
/* Styling for the Control with the fx:id of titleLabel */
}
提供的控件,被CSS文件以类的形式引用。因此,要引用一个完整的类的集合,请以. (句号)符号开始。随后在样式前用小字写上控件的名称。
这类控件及其类名的例子有。
- Button: 按钮
- CheckBox:复选框
- Label: 标签
- RadioButton:放射状按钮
- TextField: 文本字段
- TextArea: 文本区(textarea
CSS格式的样本如下所示。
.root {
/*This applies styling for the root node*/
}
.label {
/* Styling for all Control with the class of 'label' */
}
对于JavaFX应用程序的任何样式,从-fx- 文本开始,然后是控件或JavaFX项目所支持的样式。
并非所有控件都支持所有的样式。在应用之前,一定要找出可以应用于每个控件的样式,以及它的作用。
现在,在创建的StyleSheet中,将下面的代码粘贴到其中。
.root {
/*This applies styling for the root node*/
-fx-background-color: linear-gradient(
from 0% 0% to 100% 200%,
repeat,
#fbeee6 0%,
#cde0c9 50%
);
-fx-font-family: "Lucida Console";
}
.label {
/* Styling for all Control with the class of 'label' */
-fx-padding: -2px;
-fx-start-margin: 2px;
-fx-end-margin: 2px;
}
.guide-link {
/*Unique class customized by user*/
}
#loginTitleLabel,
#errorLabel {
-fx-font-family: "Chilanka";
}
它为所有的根内容、标签控件以及loginTitleLabel和errorLabel控件都应用了样式设计。
此外,还可以应用更多的样式。这些包括复选框检查的后效。要实现下面的效果,请复制并粘贴下面的代码到其中。
/* Checkbox formatting */
.check-box .mark {
-fx-shape: "M2,0L5,4L8,0L10,0L10,2L6,5L10,8L10,10L8,10L5,6L2,10L0,10L0,8L4,5L0,2L0,0Z";
}
.check-box:selected .mark {
-fx-background-color: #0181e2ff;
}
/*Once the button is clicked, it will display the following effect when one hovers over it*/
.button:hover {
-fx-background-color: linear-gradient(#2a5058, #61a2b1);
}
这就产生了下面的输出。

多个场景实例的外部CSS
添加一行代码,首先指向样式表的位置,然后根据创建的许多场景来引用它。
打开HelloApplication.java 文件,粘贴下面的代码。
/*Multiple scenes created*/
Scene scene = new Scene(fxmlLoader.load(), 600, 400);
Scene scene1 = new Scene(fxmlLoader.load(), 800, 400);
Scene scene2 = new Scene(fxmlLoader.load(), 1000, 400);
Scene scene3 = new Scene(fxmlLoader.load(), 1200, 400);
Scene scene4 = new Scene(fxmlLoader.load(), 1200, 600);
Scene scene5 = new Scene(fxmlLoader.load(), 1200, 1000);
/*Show the location of the CSS resource file*/
String css = this.getClass().getResource("styles.css").toExternalForm();
/*Add the stylesheet quickly to the many scenes*/
scene.getStylesheets().add(css);
scene1.getStylesheets().add(css);
scene2.getStylesheets().add(css);
scene3.getStylesheets().add(css);
scene4.getStylesheets().add(css);
scene5.getStylesheets().add(css);
结论
总之,对最终用户来说,应用程序的外观和功能一样重要。它越有吸引力,用户就越能接受它。先进的造型设计有助于创造现代的UI设计。随着世界的发展,设计师必须不断关注市场上的改进和新的UI设计。
JavaFX是一个对任何Java程序都非常兼容的UI框架。它既可以用于简单的项目,也可以用于涉及复杂设计的高级项目。了解JavaFX程序中的设计和造型是非常重要的。它允许人们在为桌面应用程序构建现代设计时超越想象。
我们已经经历了在你的JavaFX程序中添加样式。来吧,在你的应用程序中尝试不同的风格。