JavaFX“位置是必需的”,即使它在同一个包中
我试图让我的JavaFX程序运行,但有一些困难。 我不断收到错误“java.lang.NullPointerException:位置是必需的”。 fxml文件与Application类位于同一个包中。 这是我非常简单的代码:
package com.kromalights.designer.entry; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class Main extends Application { @Override public void start(Stage primaryStage) throws Exception{ Parent root = FXMLLoader.load(getClass().getResource("main.fxml")); primaryStage.setTitle("Kromalights Designer"); primaryStage.setScene(new Scene(root, 300, 275)); primaryStage.show(); } public static void main(String[] args) { launch(args); } }
这里是我的main.fxml文件的副本:
<?xml version="1.0" encoding="UTF-8"?> <?import java.lang.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.layout.BorderPane?> <?scenebuilder-stylesheet mailStyles.css?> <?import java.net.*?> <BorderPane prefHeight="300.0" prefWidth="300.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="com.kromalights.designer.entry.Controller"> <bottom> <Pane prefHeight="200.0" prefWidth="200.0"/> </bottom> <center> <Pane prefHeight="200.0" prefWidth="200.0"/> </center> <left> <VBox prefHeight="200.0" prefWidth="100.0"/> </left> <top> <HBox prefHeight="100.0" prefWidth="200.0"/> </top> <stylesheets> <URL value="@mainStyles.css" /> </stylesheets> </BorderPane>
控制器类存在并位于fxml文件中指定的包中。 我所有的名字都是正确的,我认为他们应该是。 我错过了什么? 我曾尝试重命名我的fxml文件,以防它是一个名称问题。 请帮忙。 仅供参考,我在OSX上使用Intellij IDEA。
更新:这是一个Maven问题。 我为这个项目设置了Maven,导致了这个问题。 我暂时删除了Maven,这样我就可以继续工作了。 有没有人有任何洞察力,我怎么会最好的处理这个时候使用Maven?
在我的情况下,以上所有都不是问题。
我replace时解决了我的问题:
getClass().getResource("ui_layout.fxml")
与:
getClass().getClassLoader().getResource("ui_layout.fxml")
将文件移动到主/资源目录工作。
我几次看到这个错误。 因此,我经常用一个Netbeans Maven FXML应用程序模板编写一个名为“Simple”的小型项目,以便在事情发生变化时作为一种“参考模型”返回。 为了testing,我使用这样的东西:
String sceneFile = "/fxml/main.fxml"; Parent root = null; URL url = null; try { url = getClass().getResource( sceneFile ); root = FXMLLoader.load( url ); System.out.println( " fxmlResource = " + sceneFile ); } catch ( Exception ex ) { System.out.println( "Exception on FXMLLoader.load()" ); System.out.println( " * url: " + url ); System.out.println( " * " + ex ); System.out.println( " ----------------------------------------\n" ); throw ex; }
当你运行这个代码片段并且加载失败的时候,你应该看到一个原因,或者至less是来自FXMLLoader的消息。 由于这是一个testing,我抛出exception。 你不想继续。
注意事项。 这是一个maven项目,所以资源将相对于资源文件夹,因此:
- “/fxml/main.fxml”。
- 主要的斜杠是必需的。
-
传递给FXMLLoader的资源区分大小写 :
// If you load "main.fxml" and your file is called: "Main.fxml" // You will will see the message ... java.lang.NullPointerException: Location is required.
-
如果你通过了“需要位置”的问题,那么你可能在FXML中有问题
//像这样:// javafx.fxml.LoadException:file:/ D:/sandbox/javafx/app_examples/person/target/person-00.00.01-SNAPSHOT.jar!/fxml/tableWithDetails.fxml:13
将意味着第13行有一个问题,在文件中,
- tableWithDetails.fxml :13
在消息中。 此时,您需要阅读FXML并查看是否可以发现问题。 你可以尝试一些相关问题的提示。
对于这个问题,我的意见是文件名是正确的情况:“Main.fxml”。 当文件被移动时,名字可能被改变或者string被重新input。 祝你好运。
有关:
- 寻求FXML / FXMLLoader错误诊断工具
URL url = new File("src/main/java/ua/adeptius/goit/sample.fxml").toURL(); Parent root = FXMLLoader.load(url);
这对我有帮助,因为
getClass.getResource("path")
总是返回我空;
我得到了同样的错误。 在我的情况下,在fxml文件名中有一个前导空格符号:
“fxml_example.fxml”而不是“fxml_example.fxml”
我不知道它是从哪里来的。 很难注意到这一点。 当我删除领先的空间,一切都OK了。 我甚至不知道文件名可以以空格符号开头。
如果你的问题不是Maven相关的,并且你在浏览器中运行这个NullPointerExceptionexception(从IDE运行它的时候没问题),试试这个:
– > Netbeans – >右键单击项目 – >属性 – >生成 – >部署 – >选中“请求无限制访问(启用签名,自签名)”
这是由于@FXML注释需要权限才能从FXML标记中注入值(请参阅http://docs.oracle.com/javafx/2/fxml_get_started/fxml_deployment.htm )
我在JDK8u31上运行我的应用程序,如果没有Chrome / Firefox / IE中的证书,它将永远不会运行。
此问题可能是由FXML文件的path不正确导致的。
如果你使用的是绝对path( my/package/views/view.fxml
),那么你必须先用一个斜杠:
getClass().getResource("/my/package/views/view.fxml")
您也可以使用相对path:
getClass().getResource("views/view.fxml")
我无法使用
getClass().getResource("views/view.fxml")
因为我把我的控制器类放到“控制器”包中,所以这里是我的解决scheme:
getClass().getResource("../views/view.fxml")
代替
Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
放
Parent root = FXMLLoader.load(getClass().getResource("/main.fxml"));
区别是“/”。
原因:
第一个:getResource将尝试查找相对于包的资源
第二个:getResource将它视为一个绝对path,并简单地调用类加载器。
加载器的根目录位于maven项目的“resources”文件夹中。 所以如果你有src/main/java
那么fxml文件path应该从src/main/resources
https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html
如果您的项目是基于Maven的,Idea会忽略src / main / java文件夹中的所有java文件。 就像你说的将文件移动到src / main / resources中一样,但是现在SceneBuilder不再了解你的控制器类,因为它在一个完全不同的目录中,你失去了所有的洞察力,你只能盲目地构build。
我相信这是Intellij中的一个问题,因为SceneBuilder 会在(和我引用)“同一目录,直接子目录或.fxml的父目录”文件中find你的控制器类java文件。
我有时也有同样的例外。
当我在Eclipse中使用向导创build一个FXML文件时,我在名称字段中编写example.fxml 。 Eclipse创build一个文件,如example.fxml.fxml 。 有了这个错误,FXMLLoader找不到合适的FXML文件。 所以,我的提示,检查你的启动方法FXML文件名的名称和文件的真实名称。
希望我能帮上忙。 祝你好运。
如果你看看docs [1],你会发现load()
方法可以使用一个URL:
load(URL location)
所以,如果你正在运行Java 7或更新的版本,你可以像这样加载FXML文件:
URL url = Paths.get("./src/main/resources/fxml/Fxml.fxml").toUri().toURL(); Parent root = FXMLLoder.load(url);
这个例子来自Maven项目,这就是FXML文件在资源文件夹中的原因。
[1] https://docs.oracle.com/javase/8/javafx/api/javafx/fxml/FXMLLoader.htm