简体   繁体   English

JavaFX-无法加载外部CSS主题

[英]JavaFX - Unable to load external CSS themes

My application contains several different packages that I want to be able to access CSS theme files, stored in the application's themes folder. 我的应用程序包含几个我希望能够访问CSS主题文件的程序包,这些程序包存储在应用程序的themes文件夹中。

After following several tutorials and other StackExchange questions and answers, I haven't found anything that works for my situation. 在遵循了几个教程以及其他StackExchange的问题和答案之后,我还没有找到适合我的情况的任何东西。 In fact, many of the "answers" just say to move the .CSS files into the same folder as the class calling for it; 实际上,许多“答案”都只是说将.CSS文件移动到与调用它的类相同的文件夹中。 that is not an acceptable solution for my situation. 对于我的情况,这不是可接受的解决方案。

My directory structure is similar to this: 我的目录结构与此类似:

- Root Project Folder
    - /data
    - /themes
        - /Theme.css
    - /src
        - sample
            - /Main.java
            - /Controller.java
            - /sample.fxml

How would I apply the Theme.css to my sample.fxml file? 如何将Theme.css应用于我的sample.fxml文件?

I threw together a sample project that works to illustrate my issue. 我整理了一个示例项目,以说明我的问题。

Main.java: Main.java:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");

        Scene scene = new Scene(root, 300, 275);

        scene.getStylesheets().add(
            getClass().getResource("/themes/Theme.css").toExternalForm());

        primaryStage.setScene(scene);
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}

sample.fxml: sample.fxml:

<GridPane fx:controller="sample.Controller"
          xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
</GridPane>

The Error: 错误:

Caused by: java.lang.NullPointerException
    at sample.Main.start(Main.java:18)

Also Tried: 也尝试过:

scene.getStylesheets().add("file:///themes/Theme.css");
scene.getStylesheets().add("file:///../themes/Theme.css");

Those both present the same "resource not found" error. 两者都出现相同的“找不到资源”错误。

This code works in the Sample above: 该代码在上面的示例中起作用:

File css = new File("themes/Theme.css");
scene.getStylesheets().add("file:///" + css.getAbsolutePath());

However, I cannot get the exact same code to work within my larger project with the same structure. 但是,我无法获得完全相同的代码以在具有相同结构的较大项目中工作。

I get this error: 我收到此错误:

WARNING: Resource "file:////[PATH TO PROJECT]/themes/Theme.css" not found

The full path shown in the error is exactly correct and leads to the file that DOES exist. 错误中显示的完整路径是完全正确的,并导致该文件确实存在。

How would I go about troubleshooting this? 我将如何解决此问题? Since it works fine in the sample project but not my larger one, the problem obviously lies somewhere in my other project code. 由于它在示例项目中运行良好,但在我的较大项目中却不行,因此问题显然出在其他项目代码中。

But why would the compiler tell me a file doesn't exist when it clearly does? 但是,为什么编译器会在明显的时候告诉我文件不存在?


Incidentally, my goal here is to allow users to select a "Theme" to use to style the entire application. 顺便说一句,我的目标是允许用户选择一个“主题”来对整个应用程序进行样式设置。 The /themes folder contains several dozen themes to choose from. /themes文件夹包含几十个主题可供选择。

Thank you in advance for all your help! 预先感谢您的所有帮助!

Following @James_D's comment to the original question, I was able to get this working with the following code, converting the string to a URI to get the proper format. 在@James_D对原始问题的评论之后,我能够使用下面的代码来完成此工作,将字符串转换为URI以获取正确的格式。

I did not want to bundle the CSS files within the JAR because I want my users to be able to customize them and add their own. 我不想将CSS文件捆绑在JAR中,因为我希望用户能够自定义它们并添加自己的文件。

Solution: 解:

        scene.getStylesheets().clear();

        File css = new File("themes/" + Settings.getThemeName() + ".css");
        System.out.println(css.toString());
        File fontFile = new File("themes/Font.css");

        scene.getStylesheets().addAll(
                css.toURI().toString(),
                fontFile.toURI().toString());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM