"Location is required" exception when loading FXML file

I already posted this today, so here's again, hope it helps you.

Here's a solution that works in the development environment, in Scene Builder and in a packaged JAR.

The folder structure:

enter image description here

Main.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:

<?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:

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:

.sun-button {
  -fx-graphic: url('./icons/sun.png');
}

application.css:

.root {
    -fx-background-color:lightgray;
}

sun.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).

Screenshot (just a button with an icon loaded via css)

enter image description here


Try this example from oracle:

 @Override
public void start(Stage stage) throws Exception {
   Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml"));

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

    stage.setTitle("FXML Welcome");
    stage.setScene(scene);
    stage.show();
}

The short answer is getClass().getResource("sample.fxml") returns null silently if the resource cannot be found on the runtime classpath, not the current directory etc.

So this depends on your IDE project setup, if you're using eclipse try adding the folder that sample.fxml resides in the run configuration.

Some ideas...

  • try getClass().getResource("/sample.fxml") instead...
  • try moving sample.fxml into the resources folder. I don't know much about your IDE, but I suspect that folder is only used for .java files... this is certainly true for gradle projects in eclipse - resources have to be in the src/main/resources tree as only that is added to the runtime classpath...

Tags:

Java

Javafx