One common frustration with the way JavaFX loads Views with the FXMLLoader is that it does not make debugging easy! “Location is not set” is a prime example of this. But, it actually surrounds how the getResource() method finds your FXML file – something that’s not specific to JavaFX.

The “Location is not set” error generated by the FXMLLoader is thrown when the getResource() method cannot locate that resource. Instead, getResource() returns a null reference, which is passed to the FXMLLoader. The FXMLLoader interprets this as a failure to set the location parameter for the FXML file.

What we’ll achieve in this tutorial

Firstly, we’ll look at how to debug the problem. Then, we’ll run through some rules and best practice to store resources sustainably in the future. Finally, well go through one example of how the IDE can create this error – even if your Java code is fine.

We’ll debug a simple application with a package structure that looks like this:

Key points are:

  • Controller and Main are both in the com.edencoding folder
  • Resources have been separated from the Java code by specifying a resources folder
  • The sample.fxml file is not in a package folder, but in the root of the resources directory.

If you hadn’t guessed, the reason you need to know the project structure is that it’s almost always the source of this problem.

Why “Location is not set” occurs

The parameter we pass to the FXMLLoader during construction is labelled ‘location’, so I usually see this error and think “but I did set it!”

But, if you look at the parameters we pass to the FXMLLoader, we don’t actually pass it a file name – or even a File object. In fact, what we pass it is a URL. And, if you’re following convention, you don’t construct the URL separately, you create it using getClass().getResource().

The first step to debugging this program is disentangling the URL that we create using getClass().getResource() from the instantiation of the FXMLLoader. Let’s split it into two lines:

URL fxmlLocation = getClass().getResource("sample.fxml");
FXMLLoader loader = new FXMLLoader(fxmlLocation);

There are two ways to look at the output of this – one is to set a breakpoint and look at the contents of fxmlLocation with debugging tools. The other is to print out the fxmlLocation variable. It doesn’t matter which one you do, it’ll have the same result (assuming the project structure above):

null

Well, drat