JavaFX"位置是必需的." 即使它在同一个包装中

Gre*_*ash 43 java javafx-2

我试图让我的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的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>
Run Code Online (Sandbox Code Playgroud)

控制器类确实存在,并且位于fxml文件中指定的包中.我的所有名字都是正确的,我认为应该是这样.我错过了什么?我确实尝试重命名我的fxml文件,以防它出现名称问题.请帮忙.仅供参考,我在OSX上使用Intellij IDEA.

更新:这是一个Maven问题.我为这个项目设置了Maven并导致了这个问题.我暂时删除了Maven,所以我可以继续工作而不用它.有没有人知道如何在使用Maven时最好地处理这个问题?

Ami*_*rad 71

在我的情况下,以上所有都不是问题.

我替换时解决了我的问题:

getClass().getResource("ui_layout.fxml")
Run Code Online (Sandbox Code Playgroud)

用:

getClass().getClassLoader().getResource("ui_layout.fxml")
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用的是IDE,问题可能是IDE不知道它需要在构建期间将.fxml文件与类文件一起复制到输出目录中,这是getClass().getResource()的样子为它(它不会在您的源树中查找!).例如,如果您使用的是IntelliJ,则可能需要在"文件"|"设置"|"编译器"设置中添加";?.fxml;?.css"之类的内容,以告知它在构建期间复制文件.有关更多信息,请参阅/sf/ask/1639492781/. (2认同)

Gre*_*ash 40

将文件移动到main/resources目录工作.

  • 我还必须使用`Parent root = FXMLLoader.load(getClass().getResource("/ fxml/Scene.fxml"));`. (10认同)
  • 每次我开始一个新项目时,我都要回到这个帖子,这是第一个有效的评论,可以保存我的理智.是的,`resources/fxml/Scene.fxml`和`.getResource("/ fxml/Scene.fxml")`就像往常一样. (3认同)
  • @ OldCurmudgeon的评论至关重要,因为它需要将`.fxml`文件移动到`resources/fxml`文件夹.如果它不存在,则创建`fxml`文件夹. (2认同)

小智 23

URL url = new File("src/main/java/ua/adeptius/goit/sample.fxml").toURI().toURL();
Parent root = FXMLLoader.load(url);
Run Code Online (Sandbox Code Playgroud)

这对我有帮助,因为

getClass.getResource("path")
Run Code Online (Sandbox Code Playgroud)

总是让我无效;

  • toURL()方法被贬低. (2认同)
  • 更正解决方案。现在不赞成使用toURL,然后成为:(path).toURI()。toURL(); (2认同)

wil*_*ill 20

我现在已经看过几次这个错误了.所以我常常用Netbeans Maven FXML应用程序模板编写一个名为"Simple"的小项目,以便在事情变得歪斜时回归到一种"参考模型".为了测试,我使用这样的东西:

    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;
    }
Run Code Online (Sandbox Code Playgroud)

当您运行该代码段并且加载失败时,您应该看到一个原因,或者至少是来自FXMLLoader的消息.由于这是一个测试,我抛出异常.你不想继续.

注意事项.这是一个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.
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果您过了"需要位置"问题,那么您可能在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".移动文件时,名称可能已更改或字符串已重新输入.祝好运.

有关:


min*_*eek 11

代替

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

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

差异是"/".

原因:

第一个:getResource将尝试查找相对于包的资源

第二个:getResource将它视为绝对路径,只需调用类加载器即可.


ale*_*kov 5

我无法使用

getClass().getResource("views/view.fxml")
Run Code Online (Sandbox Code Playgroud)

因为我把我的控制器类放到了“控制器”包中,所以这是我的解决方案:

getClass().getResource("../views/view.fxml")
Run Code Online (Sandbox Code Playgroud)

  • 我会避免使用`..`,因为部署的构建往往不知道如何使用该路径符号。相反,我做的是绝对路径。 (2认同)

jam*_*iss 5

如果您查看文档 [1],您会发现该load()方法可以采用 URL:

load(URL location)
Run Code Online (Sandbox Code Playgroud)

因此,如果您运行的是 Java 7 或更新版本,您可以像这样加载 FXML 文件:

URL url = Paths.get("./src/main/resources/fxml/Fxml.fxml").toUri().toURL();
Parent root = FXMLLoder.load(url);
Run Code Online (Sandbox Code Playgroud)

此示例来自 Maven 项目,这就是 FXML 文件位于资源文件夹中的原因。

[1] https://docs.oracle.com/javase/8/javafx/api/javafx/fxml/FXMLLoader.html