JavaFX "Location is required." even though it is in the same package

Viewed 135101

I am trying to get my JavaFX program to run but am having some difficulty. I keep getting an error of 'java.lang.NullPointerException: Location is required.' The fxml file is in the same package as Application class. Here is my very simple code:

package com.kromalights.designer.entry;

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("main.fxml"));
        primaryStage.setTitle("Kromalights Designer");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }


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

And here is a copy of my main.fxml file:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<?scenebuilder-stylesheet mailStyles.css?>
<?import java.net.*?>

<BorderPane prefHeight="300.0" prefWidth="300.0" xmlns:fx="http://javafx.com/fxml/1"
        xmlns="http://javafx.com/javafx/2.2"
        fx:controller="com.kromalights.designer.entry.Controller">
    <bottom>
        <Pane prefHeight="200.0" prefWidth="200.0"/>
    </bottom>
    <center>
        <Pane prefHeight="200.0" prefWidth="200.0"/>
    </center>
    <left>
        <VBox prefHeight="200.0" prefWidth="100.0"/>
    </left>
    <top>
        <HBox prefHeight="100.0" prefWidth="200.0"/>
    </top>
    <stylesheets>
        <URL value="@mainStyles.css" />
    </stylesheets>
</BorderPane>

The controller class does exist and is in the package specified in the fxml file. All of my names are correct and are where I think they should be. What am I missing? I did try renaming my fxml file in case it was a name issue. Please help. FYI, I am using Intellij IDEA on OSX.

UPDATE: This is a Maven issue. I setup Maven for this project and that caused the issue. I removed Maven temporarily so I can continue working without it. Does anyone have any insight as to how I would best handle this when using Maven?

18 Answers

I couldn't use

getClass().getResource("views/view.fxml")

because I put my controller class into "controllers" package, so here is my solution:

getClass().getResource("../views/view.fxml")

If you look at the docs [1], you see that the load() method can take a URL:

load(URL location)

So if you're running Java 7 or newer, you can load the FXML file like this:

URL url = Paths.get("./src/main/resources/fxml/Fxml.fxml").toUri().toURL();
Parent root = FXMLLoder.load(url);

This example is from a Maven project, which is why the FXML file is in the resources folder.

[1] https://docs.oracle.com/javase/8/javafx/api/javafx/fxml/FXMLLoader.html

I have found all of the above solutions work just fine because they trigger your IDE to rebuild the project. No magic involved.

The "real" solution for this issue is that you should just ditch your previous build directory.

  • If you are using Maven, just delete the target folder (or do a mvn clean)!
  • If you're using ANT, delete that respective folder (I think it's called out)!
  • If you're using Gradle, delete the build folder!

I tried above answers and it didn't work in my project. My project was with maven and openjfx in Windows.

This solved the problem :

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

June/2021:

After Converting the Project To Maven You Should move fxml and css file to resource folder. Just Drag and Drop (in IntelliJ Community). Then :

Parent root = FXMLLoader.load(Objects.requireNonNull(getClass().getClassLoader().getResource("FXMLDocument.fxml")));

and :

 root.getStylesheets().add(getClass().getResource("/newCascadeStyleSheet.css").toString());
    

A Slash is require for the styleSheet.

Thats All.

I had structure like this:

src
  main
    java
      dogapp
        DogApp.java (the class that contains the main method and overloaded start method)
    resources
      DogApp.fxml

but it needed to be like this (needed to have the dogapp folder inside resources folder):

src
  main
    java
      dogapp
        DogApp.java (the class that contains the main method and overloaded start method)
    resources
      dogapp
        DogApp.fxml

DogApp.java:

public class DogApp extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) throws IOException  {
        primaryStage.setTitle("Dog App");
        primaryStage.setScene(new Scene(FXMLLoader
                .load(getClass().getResource("DogApp.fxml"))));
        primaryStage.show();
    }
}

You should use getClassLoader() method in your root

Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("main.fxml"));
Related