vcmkrtchyan
vcmkrtchyan

Reputation: 2626

"Location is required" exception when loading FXML file

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

Upvotes: 18

Views: 35675

Answers (9)

Tom Rutchik
Tom Rutchik

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

Gregor
Gregor

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

bhlowe
bhlowe

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

sheriff oladejo
sheriff oladejo

Reputation: 1

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

Upvotes: 0

NELSON RODRIGUEZ
NELSON RODRIGUEZ

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

kaidoj
kaidoj

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

Adam
Adam

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

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

Upvotes: 22

Roland
Roland

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:

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

Upvotes: 3

Johan
Johan

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

Related Questions