Javafx "Location Is Required." Even Though It Is in the Same Package

JavaFX Location is required. even though it is in the same package

Moving the file to the main/resources directory worked.

java.lang.NullPointerException: Location is required

Two problems exist:

1)The File path

2)The Controller was not set properly

Recommendation:

If you are using SceneBuilder, when you want to see what your controller might look like, you can go to View -> Show Sample Controller Skeleton.


  • Solution

Main class:

package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;

public class Main extends Application {

@Override
public void start(Stage primaryStage) {
try {
System.out.println(getClass().getResource("anwendung.fxml").getPath());

//other solution
//FXMLLoader loader = new FXMLLoader(getClass().getResource("anwendung.fxml"));
//Parent root = loader.load();

//Keep in mind that you are calling a static method
Parent root = FXMLLoader.load(getClass().getResource("anwendung.fxml"));

primaryStage.setTitle("Benutzerverwaltung");
root.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(new Scene(root));
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
launch(args);
}
}

Controller:

package application;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;

public class AnwendungsController {

@FXML
private Button closeButton;

@FXML
void handleCloseButtonAction(ActionEvent event) {

}

@FXML
void onMouseClickedCancelBtn(MouseEvent event) {

}

}

FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane prefHeight="140.0" prefWidth="350.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.AnwendungsController">
<children>
<Button fx:id="closeButton" layoutX="18.0" layoutY="100.0" mnemonicParsing="false" onAction="#handleCloseButtonAction" onMouseClicked="#onMouseClickedCancelBtn" prefHeight="26.0" prefWidth="77.0" text="Abbrechen" />
<Label layoutX="10.0" layoutY="27.0" prefHeight="27.0" prefWidth="342.0" text="Sie können das Systema nun verwenden" textAlignment="CENTER" textOverrun="CLIP">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Label>
</children>
</AnchorPane>

javaFX, throws NullPointerException, Location is required

getClass().getClassLoader().getResource(...) will load a resource from a path relative to the classpath. Since you placed the FXML file in the application pacakge, you need:

Parent root=FXMLLoader.load(getClass().getClassLoader().getResource("application/Main.fxml"));

If you just use getClass().getResource(...), and do not prefix the path with /, it will load from a path relative to the current class. So

Parent root=FXMLLoader.load(getClass().getResource("Main.fxml"));

should also work.

Make sure that your FXML file is being exported to the build folder, along with the .class files.

Location is required exception when loading FXML file

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

Strange JavaFX NPE Location is required

FXML files are loaded at runtime, so in a sense the organization of your source code hierarchy is completely irrelevant; the only thing that is important is the content of the classpath. Of course, your IDE, via Maven in this case, is determining how source code and resources in the source hierarchy are compiled and deployed to what will become the classpath hierarchy.

So to make this work, there are two things you need to understand: first, what is the eventual location in the classpath of the various resources defined in your different source folders, and second, how does Class.getResource(resourceName) resolve the specified resourceName to find a resource.

For the first question, Maven likes to separate Java source files, which need to be compiled to class files, from other "static" resources. (This makes sense in web applications, where these are often deployed to different locations; imho it makes much less sense in a desktop application; however that is somewhat off-topic.)

Java source code, by default, is in a folder src/main/java. Source code in that folder is compiled and the resulting class files are deployed to the build folder (which by default is target/classes). The usual rules about Java packages apply, so if you have a class Main in a package called org.example, the source code will be in src/main/java/org/example/Main.java and the compiled code will be in target/classes/org/example/Main.class.

Non-Java resources, again by default, are placed in src/main/resources. Files in this folder are deployed (i.e. copied) to the same build folder. Consequently, if you have an FXML file, say Sample.fxml and you want it to end up in the package org.example, you would place it in src/main/resources/org/example/Sample.fxml. When the project is built, it will be copied to target/classes/org/example/Sample.fxml.

For the second question, a Class instance has a getResource(resourceName) method that will return a URL representing the resource. (So, if you are running from classes in the file system, it will return a URL with a file: scheme; if you are running from a jar file, it will return a URL with a jar: scheme, etc.) I like to think of Class.getResource(...) as meaning "Find the resource in the same place you found the current class". If your resource name is absolute, meaning that it begins with a leading /, then the resource is searched for from the root of the classpath. If the resource name is relative, i.e. it doesn't begin with a /, then the resource is searched for from the package for the current class. Note that the components of resource names (the pieces between the /) must be valid Java identifiers. In particular, this means you cannot assume you are loading resources from a file system (usually you aren't), and names containing . and .. are invalid. So you can only search in the current class's package, subpackages of that package, or using absolute resource names.

Here's a simple example. Suppose we're making the usual demo JavaFX program with contact information. We need (at least) a main class, which I'll call ContactApp, an FXML file, Contacts.fxml, and a controller class, ContactController. I will put the main class ContactApp in a package called org.jamesd.fxtest, and the controller class in a subpackage, org.jamesd.fxtest.contacts.

I like to put FXML files in the same package as their corresponding controller classes (the advantage of this will become apparent shortly), so Contacts.fxml is also going to go in org.jamesd.fxtest.contacts.

Here's a screenshot of the project layout for this:

Sample Image

To confirm these are being deployed as expected, use a system file browser (Finder, Windows Explorer, etc) to look in the "build" folder, which by default is target/classes:

Sample Image

As you can see, as expected, the FXML file and the controller class are deployed to the package org.jamesd.fxtest.contacts, and the main class is deployed to org.jamesd.fxtest.

To load the FXML file from the ContactApp class, I could specify an absolute resource name (again, this means relative to the classpath):

URL location = getClass().getResource("/org/jamesd/fxtest/contacts/Contacts.fxml");

Alternatively, I could use a relative resource name. Since the current class is in org.jamesd.fxtest and the resource I want is in org.jamesd.fxtest.contacts, the following will work:

URL location = getClass().getResource("contacts/Contacts.fxml");

The approach I prefer is to place the FXML file in the same package as its corresponding controller. The benefit to this is that I can use the controller class to load the resource. An advantage here is that it's much easier to refactor things, as the code is less dependent on the actual location of the FMXL file (any IDE will handle refactoring imports easily). Here's an entire ContactApp class using this approach.

package org.jamesd.fxtest;

import java.net.URL;

import org.jamesd.fxtest.contacts.ContactController;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class ContactApp extends Application {

@Override
public void start(Stage primaryStage) throws Exception {
URL location = ContactController.class.getResource("Contacts.fxml");
FXMLLoader loader = new FXMLLoader(location);
Parent root = loader.load() ;
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {
launch(args);
}

}

So in your example, I would recommend placing your FXML files in the same package as ViewNavigator: this means that if ViewNavigator is in the package com.demant.controller, then the FXML files go in src/main/resources/com/demant/controller. Then simply using ViewNavigator.class.getResource("ConfigureView.fxml") should work. If it doesn't work, then you can open up target/classes in a system file browser to diagnose the problem.

Finally, note that you want

ViewNavigator.class.getResource(...)

not

ViewNavigator.class.getClass().getResource(...)

In the latter code, ViewNavigator.class resolves to an instance of Class<ViewNavigator>, and so ViewNavigator.class.getClass() resolves to an instance of Class<Class<?>>. Since Class is in java.lang, you would be searching in the classpath for java.lang.ConfigureView.fxml, which clearly doesn't (and shouldn't) exist.



Related Topics



Leave a reply



Submit