如何在资源文件夹中引用javafx fxml文件?

2022-08-31 22:41:38

我正在创建一个javafx GUI应用程序,我的项目是一个maven配置的项目。我希望能够在我的控制器中像这样引用我的fxml文件:

FXMLLoader.load(getClass().getResource("main.fxml"); 

我的 main.fxml 文件位于 src/main/resources 文件夹中,我的控制器位于 src/main/java 文件夹中。我该怎么做?我的src / main / resources文件夹位于构建路径中,并且我能够从src / main / java文件夹中的类调用src / main / resources文件夹中的.properties文件。

编辑

我试图将fxml文件放在主资源文件夹的相应目录中:

enter image description here

但我仍然得到一个错误。


答案 1

通用资源查找信息

这个答案讨论了FXML位置查找,它实际上只是Java中通用资源查找任务的一个子集。资源位置由调用程序作为输入传递给 FXMLLoader,因此资源查找本身是调用应用程序代码的一部分,而不是 FXMLLoader 的一部分。

有关 Java/JavaFX 应用程序的通用资源信息(包括建议的故障诊断步骤)的全面介绍,请参阅:

同样有用的是伊甸园编码资源指南:


用法示例

FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/main.fxml"));
Parent content = loader.load(); 

位置解析选项

  1. 将所有 fxml 放在 src/main/resources 目录中。

    loader.setLocation(getClass().getResource("/main.fxml"));
    
  2. 将所有 fxml 放在 src/main/resources/fxml 目录中。

    loader.setLocation(getClass().getResource("/fxml/main.fxml"));
    
  3. 将 fxml 放在相应的资源目录中;例如 src/main/resources/com/mycompany/myapp。

    loader.setLocation(getClass().getResource("main.fxml")); 
    

最后一个选项假定从中加载 fxml 的类位于相应 Java 源层次结构中的同一相对位置。例如,您可以从源 调用上一个加载命令。com/mycompany/myapp/Main.java

FXMLLoader 使用建议

  1. 通过实例化 FXMLLoader 而不是使用 FXMLLoader 上的静态方法new FXMLLoader()

    • 当您想要从加载程序中获取值(如实例化控制器)时,静态方法会变得混乱。
  2. 在实例化的 FXMLLoader 上设置位置并调用 load() 而不是使用 load(stream) 从流加载

    • 在加载程序上设置基于 URL 的位置可以解析 fxml 和 css 文件中加载的相对资源。相对资源无法解析基于流的构造函数。
  3. 要基于类派生位置,请使用 getClass().getResource(),因为它是基于 URL 的,而不是基于流的 getClass().getResourceAsStream()。

IDE 和生成设置

确保 IDE 或生成工具正在将 fxml 文件从资源目录复制到生成输出目录。要了解 Intellij 为此的设置,请参阅:如何将 intellij 中的普通 Java 项目转换为 JavaFx 项目

关于Java Jigsaw模块化应用程序的说明

看:

具体来说,不要写:

ComboBoxStyling.class.getClassLoader()
    .getResource("/css/styleclass.css");

改为写:

ComboBoxStyling.class
    .getResource("/css/styleclass.css"); 

也就是说,直接从类中获取资源,而不是从类装入器中获取资源。如果从类装入器而不是类获取资源,那么基于模块配置的查找还有其他限制。这些限制可能难以理解,如果需要,请参阅类加载器方法的文档以获取信息。getResource


答案 2

您正在用于加载 main.fxml。这需要 main.fxml 和 java 类在同一目录/路径中加载它。如果要从与加载它的 java 类不同的路径/位置加载 fxml 文件,则需要使用相对路径。如上所述@jewelsea,您可以在 main.fxml 之前使用 / 字符的相对路径。因此,在您的案例中,使它为您工作的代码是FXMLLoader fxmlLoader = new FXMLLoader( getClass().getResource("main.fxml") );

FXMLLoader fxmlLoader = new FXMLLoader( getClass().getResource("/main.fxml") );

推荐