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