如何在 FXML 中添加 CSS 样式表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23975897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add a CSS stylesheet in FXML
提问by cody
I'd like to link a css file to my application. In my fxml file I use this:
我想将 css 文件链接到我的应用程序。在我的 fxml 文件中,我使用了这个:
<stylesheets>
<URL value="@../stylesheet1.css" />
</stylesheets>
...and I can see a styled preview when I open the fxml file in scenebuilder. But when I try to run the application I get an error:
...当我在场景构建器中打开 fxml 文件时,我可以看到样式预览。但是当我尝试运行该应用程序时,出现错误:
java.net.MalformedURLException: no protocol: ../stylesheet1.css
java.net.MalformedURLException:无协议:../stylesheet1.css
So I tested it this way:
所以我是这样测试的:
<stylesheets>
<String fx:value="stylesheet1.css" />
</stylesheets>
and now it's other way round - the application starts and applies the css, but I don't see the preview in scenebuilder. The error message:
现在情况正好相反 - 应用程序启动并应用 css,但我在 Scenebuilder 中看不到预览。错误信息:
"The file stylesheet1.css doesn't exist. Resource stylesheet1.css not found."
“文件 stylesheet1.css 不存在。找不到资源 stylesheet1.css。”
So how do I attach the css file properly?
那么如何正确附加css文件呢?
Well, although my question wasn't answered why exactly it doesn't work the above way, I found a solution that works for me. In my FXML I have just the line
好吧,虽然我的问题没有得到解答,为什么它不能按上述方式工作,但我找到了一个适合我的解决方案。在我的 FXML 中,我只有一行
<?scenebuilder-stylesheet ../stylesheet1.css?>
so Scenebuilder works with that css. And in my main class I set the stylesheet programmatically:
所以 Scenebuilder 与该 css 一起工作。在我的主类中,我以编程方式设置了样式表:
Scene scene = new Scene(root);
String css = this.getClass().getResource("../stylesheet1.css").toExternalForm();
scene.getStylesheets().add(css);
回答by Mr.AshishGK
What I found usable and working solution to include css
file in fxml
is add stylesheets="@app/cssfilename.css"
to the parent node of the fxml
file just as for stack pane
我发现包含css
文件的可用且有效的解决方案fxml
是添加 stylesheets="@app/cssfilename.css"
到文件的父节点,fxml
就像堆栈窗格一样
<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.fxml.SettingsController" stylesheets="@app/cssfilepath.css">
......
.....
.....
</StackPane>
回答by Roland
Here's a solution that works in the development environment, in Scene Builder and in a packaged JAR.
这是一个适用于开发环境、Scene Builder 和打包 JAR 的解决方案。
The folder structure:
文件夹结构:
Main.java:
主.java:
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("view/RootLayout.fxml"));
AnchorPane rootLayout = (AnchorPane) loader.load();
Scene scene = new Scene(rootLayout, 400, 400);
scene.getStylesheets().add(getClass().getResource("css/application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
RootLayout.fxml:
RootLayout.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.view.RootLayoutController">
<children>
<Pane layoutX="0.0" layoutY="0.0" prefHeight="200.0" prefWidth="200.0">
<children>
<Button fx:id="sunButton" layoutX="74.0" layoutY="88.0" mnemonicParsing="false" onAction="#handleSunButtonClick" styleClass="sun-button" stylesheets="@../css/toolbar.css" text="Button" />
</children>
</Pane>
</children>
</AnchorPane>
RootLayoutController.java:
RootLayoutController.java:
package application.view;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
public class RootLayoutController {
@FXML
Button sunButton;
@FXML
public void handleSunButtonClick() {
System.out.println( "Button clicked");
}
}
toolbar.css:
工具栏.css:
.sun-button {
-fx-graphic: url('./icons/sun.png');
}
application.css:
应用程序.css:
.root {
-fx-background-color:lightgray;
}
sun.png:
太阳.png:
This works in both the development environment and when you package the JAR (choose "Extract required libraries into generated JAR" in Eclipse).
这既适用于开发环境,也适用于打包 JAR(在 Eclipse 中选择“Extract required libraries into generated JAR”)。
Screenshot (just a button with an icon loaded via css)
屏幕截图(只是一个带有通过 css 加载的图标的按钮)
回答by DaRich
If you don't want to do it programmatically, you can do it by separating code and resources. I have a Maven project structure like this, but this is not a requirement.
如果不想以编程方式进行,可以通过分离代码和资源来实现。我有一个像这样的 Maven 项目结构,但这不是必需的。
src/main/java/${packageName}
MainWindow.fxml
src/main/resources/${packageName}
stylesheet1.css
Now you can use the stylesheet in the .fxml
现在您可以使用样式表 .fxml
stylesheets="@stylesheet1.css"
or by using the stylesheets tag as you did.
或者像您一样使用样式表标签。
There may be a warning in SceneBuilder
but it works.
可能有警告,SceneBuilder
但它有效。
回答by Hal
If you re using SceneBuilder as the original questioner is, just add the css style sheet to SceneBuilder. Under Preview, select the item relating to style sheets and a submenu will provide an item to add a css style sheet. Beware though, as the style will show up on the controls in the work area and the SceneBuilder preview but will not show when the application is run. You still have to select each control and select the style sheet under that control's ;properties before the control will show the style when the application is run.
如果您像原始提问者一样使用 SceneBuilder,只需将 css 样式表添加到 SceneBuilder。在预览下,选择与样式表相关的项目,子菜单将提供用于添加 css 样式表的项目。但请注意,因为样式将显示在工作区和 SceneBuilder 预览中的控件上,但不会在应用程序运行时显示。您仍然必须选择每个控件并选择该控件的 ; 属性下的样式表,然后该控件将在应用程序运行时显示样式。
I would further suggest that if Nathan Tuggy has nothing more intelligent to add than his rather childish comment that he should return to his customary regimen of autoeroticism and video games.
我会进一步建议,如果 Nathan Tuggy 没有比他幼稚的评论更明智的补充,那就是他应该回到他习惯的自体和电子游戏。