Java 加载 FXML 文件时“需要位置”异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28266492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 05:52:56  来源:igfitidea点击:

"Location is required" exception when loading FXML file

javajavafx

提问by Carmine

I am trying to load the FXML file and show it as an application window, but i get an exception. The FXML file was created by the FXML Scene Builder.

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

Here are the codes for the class

这是课程的代码

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();
    }
}

and FXML file

和 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>

And here is the exception i get

这是我得到的例外

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$launchApplication7(LauncherImpl.java:157)
    at com.sun.javafx.application.LauncherImpl$$Lambda/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$launchApplication13(LauncherImpl.java:821)
    at com.sun.javafx.application.LauncherImpl$$Lambda/317090070.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait6(PlatformImpl.java:323)
    at com.sun.javafx.application.PlatformImpl$$Lambda/1833150059.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null4(PlatformImpl.java:292)
    at com.sun.javafx.application.PlatformImpl$$Lambda/2115863517.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater5(PlatformImpl.java:291)
    at com.sun.javafx.application.PlatformImpl$$Lambda/1436737924.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)

What am i doing wrong?

我究竟做错了什么?

p.s. here is the project structure

ps这里是项目结构

enter image description here

在此处输入图片说明

采纳答案by Adam

The short answer is getClass().getResource("sample.fxml")returns nullsilently if the resource cannot be found on the runtime classpath, not the current directory etc.

如果在运行时类路径上找不到资源,而不是当前目录等,简短的回答是静默getClass().getResource("sample.fxml")返回。null

So this depends on your IDE project setup, if you're using eclipse try adding the folder that sample.fxmlresides in the run configuration.

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

Some ideas...

一些想法...

  • try getClass().getResource("/sample.fxml")instead...
  • try moving sample.fxmlinto the resources folder. I don't know much about your IDE, but I suspect that folder is only used for .javafiles... this is certainly true for gradle projects in eclipse - resources have to be in the src/main/resourcestree as only that is added to the runtime classpath...
  • 试试吧getClass().getResource("/sample.fxml")...
  • 尝试sample.fxml进入资源文件夹。我对您的 IDE 了解不多,但我怀疑该文件夹仅用于.java文件...这对于 eclipse 中的 gradle 项目当然是正确的 - 资源必须在src/main/resources树中,因为只有将其添加到运行时类路径中。 ..

回答by Johan

Try this example from oracle:

从 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();
}

回答by Roland

I already posted this today, so here's again, hope it helps you.

我今天已经发布了,所以再次发布,希望它对您有所帮助。

Here's a solution that works in the development environment, in Scene Builder and in a packaged JAR.

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

The folder structure:

文件夹结构:

enter image description here

在此处输入图片说明

Main.java:

主.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:

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:

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");
    }
}

toolbar.css:

工具栏.css:

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

application.css:

应用程序.css:

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

sun.png:

太阳.png:

enter image description here

在此处输入图片说明

This works in both the development environment and when you package the JAR (choose "Extract required libraries into generated JAR" in Eclipse).

这既适用于开发环境,也适用于打包 JAR(在 Eclipse 中选择“Extract required libraries into generated JAR”)。

Screenshot (just a button with an icon loaded via css)

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

enter image description here

在此处输入图片说明

回答by kaidoj

Main.class.getResource worked for me. I was trying to get resource from subclass instead of Main class. I used there getClass().getResource() which was pointing to the current class. I didn't have my FXML files in resources directory.

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

回答by NELSON RODRIGUEZ

Append MainApp.class to getClass().getResource("/fxml/Scene.fxml") . worked for me! example: Parent root = FXMLLoader.load(MainApp.class.getClass().getResource("/fxml/Scene.fxml"));

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