How to reference javafx fxml files in resource folder?

Generic Resource Lookup Information

This answer discusses FXML location lookup, which is really just a subset of the generic resource lookup task in Java. The resource location is passed by the calling program as input to the FXMLLoader, so the resource lookup itself is part of your calling application code and not the FXMLLoader.

For thorough coverage of generic resource information (including recommended troubleshooting steps) for Java/JavaFX applications, please refer to:

Also useful, is the Eden coding resource guide:


Example usage

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

Location resolution options

  1. Put all of your fxml in the src/main/resources directory.

    loader.setLocation(getClass().getResource("/main.fxml"));
    
  2. Put all of your fxml in a src/main/resources/fxml directory.

    loader.setLocation(getClass().getResource("/fxml/main.fxml"));
    
  3. Place fxml in a corresponding resource directory; e.g. src/main/resources/com/mycompany/myapp.

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

The last option assumes that the class from which you are loading the fxml is in the same relative location in the corresponding Java source hierarchy. For example, you might invoke the last load command from source com/mycompany/myapp/Main.java.

FXMLLoader usage recommendations

  1. Instantiate an FXMLLoader via new FXMLLoader() rather than using
    the static methods on the FXMLLoader.

    • The static methods
      become confusing when you want to get values (like instantiated
      controllers) out of a loader.
  2. Set the location on the instantiated FXMLLoader and call
    load() rather than loading from a stream using
    load(stream).

    • Setting a URL based location on the loader allows for resolution of
      relative resources loaded in fxml and css files. Relative
      resources do not resolve for a stream based constructor.
  3. To derive a location based upon a class, use
    getClass().getResource(), as it is URL based, rather than
    getClass().getResourceAsStream() which is stream based.

IDE and Build Settings

Ensure that your IDE or build tool is copying the fxml files from the resource directory to the build output directory. For understanding Intellij settings for this, see: How to convert a normal java project in intellij into a JavaFx project.

A note on Java Jigsaw modular applications

See:

Specifically, don’t write:

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

Instead write:

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

That is, get the resource from the class directly rather, NOT from the class loader. If you get resources from a class loader rather than the class, then there are additional restrictions on lookup based upon the module configuration. These restrictions can be hard to understand, see the documentation for the Class and ClassLoader getResource methods for information if needed.

Leave a Comment