I have an issue using Java with FXML files.
I searched for hours now and couldn't find anything that solves my problem, so my last hope is to ask the question for my specific case (I'm aware of question like this one and others but none really helped me in this regard.
Simple explanation: I have an Eclipse Java Project and my (important for this question) classes are in the package [Project Name]/src/measurements.gui. My FXML file is in the folder [Project Name]/resources.
My class that loads the FXML file ElementsProperties.java looks like this:
import java.io.IOException;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Window;
public class ElementsProperties {
public static void show(Window parent, String title) {
ElementsProperties el = new ElementsProperties();
BorderPane root = el.loadFXMLFile("resources/TestWindow.fxml");
Stage dialog = new Stage();
dialog.initOwner(parent);
dialog.setTitle(title);
dialog.initModality(Modality.WINDOW_MODAL);
dialog.setScene(new Scene(root));
dialog.show();
}
@SuppressWarnings({ "finally", "static-access" })
private BorderPane loadFXMLFile(String filePath) {
BorderPane borderPane = null;
try {
borderPane = new BorderPane();
FXMLLoader fxmlLoader = new FXMLLoader();
Parent content = fxmlLoader.load(getClass().getResource(filePath));
borderPane.setCenter(content);
}
catch (IOException e) {
e.printStackTrace();
System.err.println("Couldn't find the specified file");
}
catch(Exception e){
e.printStackTrace();
}
finally {
return borderPane;
}
}}
The FXML file is shown as a dialog with the following simple line:
ElementsProperties.show(parent, "TestWindow");
My FXML file (created with the JavaFXSceneBuilder 2.0) looks like this: `
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.effect.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.text.*?>
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<MenuBar VBox.vgrow="NEVER">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="New" />
<MenuItem mnemonicParsing="false" text="Open…" />
<Menu mnemonicParsing="false" text="Open Recent" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Close" />
<MenuItem mnemonicParsing="false" text="Save" />
<MenuItem mnemonicParsing="false" text="Save As…" />
<MenuItem mnemonicParsing="false" text="Revert" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Preferences…" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Quit" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Undo" />
<MenuItem mnemonicParsing="false" text="Redo" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Cut" />
<MenuItem mnemonicParsing="false" text="Copy" />
<MenuItem mnemonicParsing="false" text="Paste" />
<MenuItem mnemonicParsing="false" text="Delete" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Select All" />
<MenuItem mnemonicParsing="false" text="Unselect All" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About MyHelloApp" />
</items>
</Menu>
</menus>
</MenuBar>
<AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS">
<children>
<Label alignment="CENTER" layoutX="155.0" layoutY="177.0" style=" " text="Drag components from Library here…" textAlignment="CENTER" textFill="#9f9f9f" wrapText="false">
<font>
<Font size="18.0" />
</font>
</Label>
<GridPane layoutX="-2.0" layoutY="-3.0" prefHeight="407.0" prefWidth="659.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<HBox prefHeight="134.0" prefWidth="654.0" spacing="20.0" GridPane.rowIndex="1">
<children>
<Button mnemonicParsing="false" prefHeight="46.0" prefWidth="60.0" text="Click me" wrapText="true" />
<Button mnemonicParsing="false" prefHeight="47.0" prefWidth="73.0" text="No, click me" wrapText="true" />
<Button mnemonicParsing="false" prefHeight="46.0" prefWidth="120.0" text="Don't you dare click me" wrapText="true" />
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</HBox>
<TextField promptText="Type something here..." GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="20.0" right="20.0" />
</GridPane.margin>
</TextField>
</children>
</GridPane>
</children>
</AnchorPane>
</children>
</VBox>
This is actually all that is needed. If I try to run the programm and make the dialog show up, the Exception
java.lang.NullPointerException: Location is required.
is given. If I move the FXML file into the same package as the main class, being measurements.gui, and change the filePath in the ELementsProperties.java class' show-method to "TestWindow.fxml"
, it all works fine and I see the created window in my application. But I want to have the fxml file in the seperate resource folder for convenience of inserting other fxml files.
I hope I could explain my problem clearly and you can help me solve this. Any ideas on how to load fxml files from a different package than the main class is? Btw, things I've already tried are:
- adding the resource folder to the class path
- set the path to "/resources/TestWindow.fxml" (with the forward slash at the beginning
- use
getClass().getClassLoader().getResource(filePath)
as parameter for the FXMLLoader's load method
Thank you in advance.