Reputation: 2626
I am trying to load the FXML file and show it as an application window, but i get an exception. The FXML file was created by the FXML Scene Builder.
Here are the codes for the class
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(FXMLLoader.load(getClass().getResource("sample.fxml")));
primaryStage.show();
}
}
and FXML file
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.AnchorPane?>
<TitledPane animated="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefHeight="400.0" prefWidth="600.0" text="Pass4D" xmlns:fx="http://javafx.com/fxml/1"
xmlns="http://javafx.com/javafx/8">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<Button layoutX="211.0" layoutY="134.0" mnemonicParsing="false" prefHeight="33.0" prefWidth="177.0"
text="Log in"/>
<Button layoutX="212.0" layoutY="170.0" mnemonicParsing="false" prefHeight="33.0" prefWidth="175.0"
text="Exit"/>
</children>
</AnchorPane>
</content>
</TitledPane>
And here is the exception i get
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:875)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$147(LauncherImpl.java:157)
at com.sun.javafx.application.LauncherImpl$$Lambda$1/2074407503.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException: Location is required.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3201)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3169)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3142)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3118)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3098)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3091)
at Pass4D.start(Pass4D.java:19)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
at com.sun.javafx.application.LauncherImpl$$Lambda$51/317090070.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/1833150059.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
at com.sun.javafx.application.PlatformImpl$$Lambda$49/2115863517.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/1436737924.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
What am i doing wrong?
p.s. here is the project structure
Upvotes: 18
Views: 35675
Reputation: 1692
Here's what to do when using an IntelliJ IDE.
When you are using getClass().getResource(), the resource must be located in the resources folder under a directory in that resource folder that corresponds to the package name of the class you are using:
src/main/java/com/foo/MyClass.java
src/main/java/resources/com/foo/MyResource.fxml
MyClass.class.getResource(MyResource.fxml) will worked
same rule applies for using FXMLLoader.
In the IntelliJ world, if you put that resource into the same folder that the class is located in, that resource won't be found. The irony of that is when look at jar produced, you'll find that the resource is actually placed into the same jar folder as the source is located in. That's because, when debugging only the compiled java classes are moved into the target folder, together with the resources from the resources directory. So what's really happening is just an artifact of how the debug build process works. I know that if you were using Android Studio for instance it works slightly different. You could place the resource in the same folder that the java source file is located, and it would find that resource. I don't know what IDE Roland above was using, but he was using an IDE that allowed him to place the resource the same directory as the java source was located in.
Upvotes: 0
Reputation: 1296
for me, after a lot of trial and error, the only way that worked was to add getClassLoader()
like so:
MyClass.class.getClassLoader().getResource("views/myview.fxml")
For a layout of:
src
+main
+resources
+views
+myview.fxml
Upvotes: -1
Reputation: 468
If you are using Maven you may need to move the fxml file to your resources directory.
refactor src/main/java/sample/sample.fxml to src/main/resources/sample/sample.fxml
Upvotes: 0
Reputation: 1
Delete the "build" folder in your javafx project and rebuild your project.
Upvotes: 0
Reputation: 369
Append MainApp.class to getClass().getResource("/fxml/Scene.fxml") . worked for me! example: Parent root = FXMLLoader.load(MainApp.class.getClass().getResource("/fxml/Scene.fxml"));
Upvotes: 0
Reputation: 363
Main.class.getResource worked for me. I was trying to get resource from subclass instead of Main class. I used there getClass().getResource() which was pointing to the current class. I didn't have my FXML files in resources directory.
Upvotes: 0
Reputation: 36703
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...
getClass().getResource("/sample.fxml")
instead...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...Upvotes: 22
Reputation: 18415
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:
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:
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)
Upvotes: 3
Reputation: 495
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();
}
Upvotes: 1