如何在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 02:31:55  来源:igfitidea点击:

How to add a CSS stylesheet in FXML

cssjavafxstylesheetfxmlscenebuilder

提问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 cssfile in fxmlis add stylesheets="@app/cssfilename.css"to the parent node of the fxmlfile 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:

文件夹结构:

enter image description here

在此处输入图片说明

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:

enter image description here

在此处输入图片说明

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 加载的图标的按钮)

enter image description here

在此处输入图片说明

回答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 SceneBuilderbut 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 没有比他幼稚的评论更明智的补充,那就是他应该回到他习惯的自体和电子游戏。