【问题标题】:"Location is required" exception when loading FXML file加载 FXML 文件时出现“需要位置”异常
【发布时间】:2015-03-31 17:38:37
【问题描述】:

我正在尝试加载 FXML 文件并将其显示为应用程序窗口,但出现异常。 FXML 文件由 FXML 场景生成器创建。

这是类的代码

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setScene(FXMLLoader.load(getClass().getResource("sample.fxml")));
        primaryStage.show();
    }
}

和 FXML 文件

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.AnchorPane?>
<TitledPane animated="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
            prefHeight="400.0" prefWidth="600.0" text="Pass4D" xmlns:fx="http://javafx.com/fxml/1"
            xmlns="http://javafx.com/javafx/8">
    <content>
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
            <children>
                <Button layoutX="211.0" layoutY="134.0" mnemonicParsing="false" prefHeight="33.0" prefWidth="177.0"
                        text="Log in"/>
                <Button layoutX="212.0" layoutY="170.0" mnemonicParsing="false" prefHeight="33.0" prefWidth="175.0"
                        text="Exit"/>
            </children>
        </AnchorPane>
    </content>
</TitledPane>

这是我得到的例外

Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:875)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$147(LauncherImpl.java:157)
    at com.sun.javafx.application.LauncherImpl$$Lambda$1/2074407503.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException: Location is required.
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3201)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3169)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3142)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3118)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3098)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3091)
    at Pass4D.start(Pass4D.java:19)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
    at com.sun.javafx.application.LauncherImpl$$Lambda$51/317090070.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
    at com.sun.javafx.application.PlatformImpl$$Lambda$47/1833150059.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
    at com.sun.javafx.application.PlatformImpl$$Lambda$49/2115863517.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
    at com.sun.javafx.application.PlatformImpl$$Lambda$48/1436737924.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)

我做错了什么?

附言这是项目结构

【问题讨论】:

  • 项目结构是什么?特别是,sample.fxml 与您的 Main 类相比在哪里?
  • 在这里,我更新了帖子

标签: java javafx


【解决方案1】:

从 oracle 试试这个例子:

 @Override
public void start(Stage stage) throws Exception {
   Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml"));

    Scene scene = new Scene(root, 300, 275);

    stage.setTitle("FXML Welcome");
    stage.setScene(scene);
    stage.show();
}

【讨论】:

  • 我遇到了同样的异常
  • 也许我在项目的配置中遗漏了一些东西?该项目最初并不打算成为 JavaFX 程序,所以它是作为一个空白应用程序创建的,所以也许我在那里遗漏了什么?
  • 我解决了这个问题,但你的回答也很有用,我确实需要为场景设置参数
【解决方案2】:

我今天已经发了,所以又来了,希望对你有帮助。

这是一个适用于开发环境、Scene Builder 和打包 JAR 的解决方案。

文件夹结构:

Main.java:

package application;

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


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {

            FXMLLoader loader = new FXMLLoader(Main.class.getResource("view/RootLayout.fxml"));
            AnchorPane rootLayout = (AnchorPane) loader.load();

            Scene scene = new Scene(rootLayout, 400, 400);
            scene.getStylesheets().add(getClass().getResource("css/application.css").toExternalForm());

            primaryStage.setScene(scene);
            primaryStage.show();

        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

RootLayout.fxml:

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

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.view.RootLayoutController">
   <children>
      <Pane layoutX="0.0" layoutY="0.0" prefHeight="200.0" prefWidth="200.0">
         <children>
            <Button fx:id="sunButton" layoutX="74.0" layoutY="88.0" mnemonicParsing="false" onAction="#handleSunButtonClick" styleClass="sun-button" stylesheets="@../css/toolbar.css" text="Button" />
         </children>
      </Pane>
   </children>
</AnchorPane>

RootLayoutController.java:

package application.view;

import javafx.fxml.FXML;
import javafx.scene.control.Button;

public class RootLayoutController {


    @FXML
    Button sunButton;

    @FXML
    public void handleSunButtonClick() {
        System.out.println( "Button clicked");
    }
}

工具栏.css:

.sun-button {
  -fx-graphic: url('./icons/sun.png');
}

application.css:

.root {
    -fx-background-color:lightgray;
}

sun.png:

这在开发环境和打包 JAR 时都有效(在 Eclipse 中选择“将所需的库提取到生成的 JAR”中)。

屏幕截图(只是一个带有通过 css 加载的图标的按钮)

【讨论】:

  • 这很好。但是如果 OP 将 fxml 放在 main/resources/views 上会怎样。代码是什么? Main.class.getResource("../resources/view/RootLayout.fxml")?
【解决方案3】:

如果在运行时 classpath 上找不到资源,而不是当前目录等,getClass().getResource("sample.fxml") 会以静默方式返回 null

所以这取决于您的 IDE 项目设置,如果您使用的是 eclipse,请尝试在运行配置中添加 sample.fxml 所在的文件夹。

一些想法...

  • 改用getClass().getResource("/sample.fxml")...
  • 尝试将sample.fxml 移动到资源文件夹中。我对您的 IDE 了解不多,但我怀疑该文件夹仅用于 .java 文件......这对于 eclipse 中的 gradle 项目当然是正确的 - 资源必须在 src/main/resources 树中,因为只有这样添加到运行时类路径...

【讨论】:

  • 将它移动到资源文件夹有帮助,不,我明白出了什么问题,非常感谢!)
  • 在 Intellij 中,moving sample.fxml into the resources foldergetClass().getResource("/sample.fxml") 的组合对我有用。我必须在主文件夹的同一级别创建一个“资源”目录。
  • 谢谢! IntelliJ Idea 也在这里。我已经在这样的目录中有我的资源并且它工作正常,但是在重构类并将它们放在一些包中以保持整洁之后,我得到了这个错误。事实证明,在文件名的开头添加斜杠解决了整个问题。
  • 在 Eclipse 中,使用标准的 Gradle 文件夹结构,您通常必须将其放在 ...EclipseWorkspace\MyProject\bin\main\mypackagename\ 中,因为这是 Eclipse 放置 .class 文件的位置默认情况下(并用于类路径)。
  • 将文件添加到 bin/ 文件夹是不明智的恕我直言。如果您要进行干净的构建,则该文件夹将被擦除。对于 gradle,我认为应该使用 arc/main/resources 的标准 maven 约定...
【解决方案4】:

Main.class.getResource 为我工作。我试图从子类而不是主类获取资源。我在那里使用了指向当前类的 getClass().getResource()。我的资源目录中没有我的 FXML 文件。

【讨论】:

    【解决方案5】:

    将 MainApp.class 附加到 getClass().getResource("/fxml/Scene.fxml") 。为我工作! 例子: 父根 = FXMLLoader.load(MainApp.class.getClass().getResource("/fxml/Scene.fxml"));

    【讨论】:

      【解决方案6】:

      删除 javafx 项目中的“build”文件夹并重新构建项目。

      【讨论】:

        【解决方案7】:

        如果您使用的是 Maven,您可能需要将 fxml 文件移动到您的资源目录。

        refactor src/main/java/sample/sample.fxml to src/main/resources/sample/sample.fxml 
        

        【讨论】:

          【解决方案8】:

          对我来说,经过大量试验和错误,唯一可行的方法是像这样添加getClassLoader()

          MyClass.class.getClassLoader().getResource("views/myview.fxml")
          

          对于以下布局:

          src
             +main
                +resources
                   +views
                      +myview.fxml
          

          【讨论】:

            【解决方案9】:

            以下是使用 IntelliJ IDE 时应执行的操作。
            当您使用 getClass().getResource() 时,资源必须位于该资源文件夹中与您正在使用的类的包名称相对应的目录下的资源文件夹中:

            src/main/java/com/foo/MyClass.java
            src/main/java/resources/com/foo/MyResource.fxml

            MyClass.class.getResource(MyResource.fxml) 将起作用

            同样的规则适用于使用 FXMLLoader。
            在 IntelliJ 世界中,如果您将该资源放入该类所在的同一文件夹中,则将找不到该资源。具有讽刺意味的是,当查看生成的 jar 时,您会发现资源实际上与源所在的 jar 文件夹位于同一文件夹中。这是因为,在调试时,只有编译好的 java 类被移动到目标文件夹中,以及资源目录中的资源。所以真正发生的只是调试构建过程如何工作的一个工件。我知道,如果你使用的是 Android Studio,它的工作方式会略有不同。您可以将资源放在 java 源文件所在的同一文件夹中,它会找到该资源。我不知道上面 Roland 使用的是什么 IDE,但他使用的 IDE 允许他将资源放置在与 java 源所在的目录相同的目录中。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-01-07
              • 2019-02-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-07-07
              相关资源
              最近更新 更多