18

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

enter image description here

Adam
  • 35,919
  • 9
  • 100
  • 137
vcmkrtchyan
  • 2,536
  • 5
  • 30
  • 59

9 Answers9

22

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

  • try getClass().getResource("/sample.fxml") instead...
  • try moving 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...
fabian
  • 80,457
  • 12
  • 86
  • 114
Adam
  • 35,919
  • 9
  • 100
  • 137
  • moving it to the resource folder helped, no i understand what was wrong, thank you very much!) – vcmkrtchyan Feb 01 '15 at 19:24
  • 10
    In Intellij, the combination of `moving sample.fxml into the resources folder` and `getClass().getResource("/sample.fxml")` worked for me. I had to create a "resources" directory at the same level that the main folder. – ol_v_er Aug 25 '16 at 13:58
  • Thank you! IntelliJ Idea here too. I already had my resources in such directory and it was working fine, BUT after refactoring the classes and putting them in some packages to keep things tidy, I got this error. It turned out that adding that slash at the start of the file name solved the whole thing. – Fran Marzoa Oct 14 '18 at 18:31
  • In Eclipse, with a standard Gradle folder structure, you will typically have to put it in ...EclipseWorkspace\MyProject\bin\main\mypackagename\, as this is where Eclipse puts the .class files by default (and uses for the classpath). – mike rodent Mar 18 '19 at 15:04
  • Adding files into bin/ folder is unwise IMHO. If you were to do a clean build this folder would be wiped. For gradle I believe the standard maven convention of arc/main/resources should be used... – Adam Mar 18 '19 at 15:51
  • @ol_v_er Your answer helped me and made my program run.But i don't get why you need to make a new "resources" folder in order the IDE to find the fxml. I mean i the fxml the same package with the controller class. i used the same path for both "packageName.sample.fxml" but in Main class it kept giving null error exception and "give location" message..... – Panagiss May 06 '20 at 11:03
3

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:

enter image description here

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:

enter image description here

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)

enter image description here

Roland
  • 18,114
  • 12
  • 62
  • 93
  • That is nice. But what if OP put fxml on main/resources/views. What would be the code? Main.class.getResource("../resources/view/RootLayout.fxml")? – Marcos Rocha Apr 24 '20 at 02:34
1

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();
}
Johan
  • 475
  • 4
  • 17
  • 1
    I'm getting the same exception – vcmkrtchyan Feb 01 '15 at 19:05
  • Maybe i'm missing something in the configurations of the project? The project wasn't initially intended to be JavaFX program, so it was created as a blank application, so maybe i'm missing something there? – vcmkrtchyan Feb 01 '15 at 19:06
  • i fixed that out, but your answer was also very useful, i do need to set the parameters for the scene – vcmkrtchyan Feb 01 '15 at 19:27
0

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.

kaidoj
  • 353
  • 1
  • 4
  • 5
0

Append MainApp.class to getClass().getResource("/fxml/Scene.fxml") . worked for me! example: Parent root = FXMLLoader.load(MainApp.class.getClass().getResource("/fxml/Scene.fxml"));

0

Delete the "build" folder in your javafx project and rebuild your project.

0

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 
bhlowe
  • 418
  • 4
  • 8
0

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.

Tom Rutchik
  • 1,183
  • 1
  • 12
  • 15
-1

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
Gregor
  • 1,297
  • 1
  • 19
  • 31