【问题标题】:How to reference javafx fxml files in resource folder?如何引用资源文件夹中的 javafx fxml 文件?
【发布时间】:2013-11-05 07:58:36
【问题描述】:

我正在创建一个 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文件放在主资源文件夹的对应目录中:

但我仍然遇到错误。

【问题讨论】:

    标签: java resources javafx fxml buildpath


    【解决方案1】:

    通用资源查找信息

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

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

    Eden 编码资源指南也很有用:


    示例用法

    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. 通过new FXMLLoader() 实例化一个 FXMLLoader 而不是使用 static methods on the FXMLLoader

      • 静态方法 当你想get values 时变得混乱(比如实例化 控制器)从加载器中取出。
    2. Set the location 在实例化的 FXMLLoader 上并调用 load() 而不是使用从流中加载 load(stream).

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

    IDE 和构建设置

    确保您的 IDE 或构建工具正在将 fxml 文件从资源目录复制到构建输出目录。要了解 Intellij 设置,请参阅:How to convert a normal java project in intellij into a JavaFx project

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

    见:

    具体不要写:

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

    改为写:

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

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

    【讨论】:

    • 您仍在使用示例中的静态方法。您需要调用 getResourceAsStream 而不是 getResource
    • 感谢 Felix,修复并澄清了答案。 3 年和 28 次投票,之前没有人在原始答案中指出这个异常;-)
    • 一直以来,它都失败了,因为我没有将/ 放在开始文件夹之前。 IE。 getClass().getResource("fxml/main.fxml").
    • NetBeans 用户快速注意事项,您可以通过右键单击项目目录 > 属性 > 选择“源” > 选择要添加到源的文件夹 > 添加文件夹来将现有文件夹添加到 src。因此,如果您已经有一个包含您要引用的 fxml 的文件夹,您只需添加该文件夹并使用它们的相对路径调用 fxml 文件。
    【解决方案2】:

    在您操作系统的文件资源管理器中打开您的资源文件夹。在这里,您将看到您创建了一个“dominion.application”文件夹,而不是“dominion”文件夹内的“application”文件夹。因此,“MainController”类与 fxml 文件放在不同的包中。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 其实这是对问题的简单回答,仔细想想也是有道理的。该路径相对于调用 FXMLLoader() 的源文件。
      猜你喜欢
      • 1970-01-01
      • 2018-08-15
      • 2010-10-09
      • 1970-01-01
      • 2016-08-14
      • 2012-12-07
      • 2017-05-18
      相关资源
      最近更新 更多