'Locating fxml file from a different package
I am having "tare your hair out" type difficulties while trying to open an fxml file from a controller which is in a different package. the package structure is as follows:
Controller name = LocationController
Controller package = src/com/yas/prayertimeconfig/location/java
FXML file name = AvailableAddresses.fxml
FXML file package = src/com/yas/prayertimeconfig/availableaddresses/java
The code I am using to open up the fxml file from with in LocationController
is as follows:
@FXML void btnFindAddress_Click(ActionEvent event) throws IOException {
try{
Parent root1 = FXMLLoader.load(getClass().getResource("/src/com/yas/prayertimeconfig/availableaddresses/java/AvailableAddresses.fxml"));
Stage stage = new Stage();
stage.setTitle("Available Addresses");
stage.setScene(new Scene(root1));
stage.show();
} catch (Exception e) {
System.out.println(e);
}
}
I keep getting:
java.lang.NullPointerException: Location is required.
I have tried every using:
getClass().getResource()
and
getClass().getClassLoader().getResource()
and no joy.
Please help!
Solution 1:[1]
Here's how I recreated that error, how I troubleshooted it, and how I ultimately fixed it, in that order.
Full Error Message:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at [email protected]/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:465)
at [email protected]/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
at [email protected]/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:901)
at [email protected]/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.NullPointerException: Location is required.
at [email protected]/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3324)
at [email protected]/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3287)
at [email protected]/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3255)
at [email protected]/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3227)
at [email protected]/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3203)
at [email protected]/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3196)
at com.company.Main.start(Main.java:29)
at [email protected]/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847)
at [email protected]/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
at [email protected]/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at [email protected]/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
at [email protected]/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at [email protected]/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at [email protected]/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
... 1 more
Here's my Start function code that caused the error:
@Override
public void start(Stage stage) throws Exception {
System.out.println("Start()");
Parent root = FXMLLoader.load(getClass().getResource("login-form.fxml"));
stage.setTitle("Login");
Scene scene = new Scene(root, 200, 150);
stage.setScene(scene);
stage.show();
}
The code above basically is trying to load an fxml file on program entry and we can't load it for some reason. (stay tuned)
Basically what that error message is telling me is that it can't load login-form.fxml
For a quick and dirty test, Copy that fxml file that you are trying to load into the same project dir as the the file that has the function that is loading. Just put everything in the same folder. I use copy/paste in IntelliJ's project viewer to do this.
Just make sure that your project "sees" the file. You may have to import your fxml project into the file. It will load now for me and I can see my login form on program launch.
Now, let's fix this the "correct" ie. "less hacky" way.
As another poster commented, relative paths are not a good idea since navigating "up" only works as long as the app is not deployed as jar. You need to start the path at the classpath root starting with /
You can see in my screencap that I have the fxml file I want to import in a different package called "view". In Java projects a "package" is basically a "folder", so I can use "/view/login-form.xml" as a path I can pass to
FXMLLoader.load(getClass().getResource("/view/login-form.fxml"))
Remember that "/" in this case is the root of your project, not the root directory of your entire hard drive.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | sitting-duck |