![](/img/trans.png)
[英]In javafx loading FXML file from another package and error appear?
[英]Javafx location is required (loading FXML file from another folder/package)
我在将Java与FXML文件一起使用时遇到问题。
我现在搜索了几个小时,却找不到能解决我问题的任何东西,所以我的最后希望是针对我的具体情况提出问题(我知道像这样的问题和其他问题,但在这方面没有一个真正的帮助我。
简单说明:我有一个Eclipse Java Project,并且我的(对于这个问题很重要)类位于软件包[Project Name] /src/measurements.gui中。 我的FXML文件在[项目名称] /资源文件夹中。
加载FXML文件ElementsProperties.java的类如下所示:
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;
}
}}
FXML文件显示为带有以下简单行的对话框: ElementsProperties.show(parent, "TestWindow");
我的FXML文件(使用JavaFXSceneBuilder 2.0创建)如下所示:
<?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>
实际上,这就是所需要的。 如果我尝试运行程序并显示对话框,则异常
java.lang.NullPointerException: Location is required.
给出。 如果我将FXML文件移动到与主类相同的包中,即Measurements.gui,并将ELementsProperties.java类的show-method中的filePath更改为"TestWindow.fxml"
,那么一切正常,我看到创建的我的应用程序中的窗口。 但我想将fxml文件放在单独的资源文件夹中,以便于插入其他fxml文件。
希望我能清楚地解释我的问题,并且您可以帮助我解决这个问题。 关于如何从不同于主类的包中加载fxml文件的任何想法? 顺便说一句,我已经尝试过的事情是:
getClass().getClassLoader().getResource(filePath)
作为FXMLLoader的加载方法的参数 先感谢您。
感谢Roland提供的链接。 我试图复制文件夹结构,并提出了以下建议(适用于可能存在相同问题的其他人):
我创建了一个测试项目JavaFXTest。 我在org.example.main包中有一个主类。 像往常一样,该软件包位于项目的src文件夹中。
MyJavaFXDialog.java:
package org.example.main;
import java.io.IOException;
import javafx.application.Application;
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;
public class MyJavaFXDialog extends Application{
public void start(Stage primaryStage) {
MyJavaFXDialog javaFx = new MyJavaFXDialog();
BorderPane root = javaFx.loadFXMLFile("/resources/TestWindow.fxml");
Stage dialog = new Stage();
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;
}
}
public static void main(String[] args){
launch(args);
}
}
我在src文件夹中创建了一个普通文件夹“ resources”。 该资源文件夹仅包含我的TestWindow.fxml文件,该文件与上述问题完全相同。 现在,当我启动应用程序时,找到了fxml文件并将其显示为主窗口。
因此,解决方案实际上是将资源文件夹移至 src文件夹,对于我的情况而言,这仍然是可行的解决方案。 我只是不希望最终用户不得不在其他软件包的最深处四处摸索以保存自己的fxml文件。
再次感谢Roland向我指出该解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.