You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX启动报错:Exception in Application start method路径问题求助

JavaFX加载FXML时抛出Location is not set异常

我试过Stack Overflow上所有相关解决方案,还是没法解决问题。运行Main.java时一直抛出Exception in Application start method异常,核心错误是java.lang.IllegalStateException: Location is not set。我多次修改main.fxml的路径,结果都一样。相关代码、错误日志和环境信息如下:


Main.java代码

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import ru.javabegin.training.fastjava2.javafx.controllers.MainController;
import ru.javabegin.training.fastjava2.javafx.objects.Lang;
import ru.javabegin.training.fastjava2.javafx.utils.LocaleManager;

import java.io.IOException;
import java.util.Locale;
import java.util.Observable;
import java.util.Observer;
import java.util.ResourceBundle;

public class Main extends Application implements Observer {


    private static final String FXML_MAIN = "../fxml/main.fxml";
    public static final String BUNDLES_FOLDER = "ru.javabegin.training.fastjava2.javafx.bundles.Locale";

    private Stage primaryStage;

    private Parent fxmlMain;

    private MainController mainController;
    private FXMLLoader fxmlLoader;

    private VBox currentRoot;

    @Override
    public void start(Stage primaryStage) throws Exception {
        this.primaryStage = primaryStage;
        createGUI(LocaleManager.RU_LOCALE);
    }


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

    @Override
    public void update(Observable o, Object arg) {
        Lang lang = (Lang) arg;
        VBox newNode = loadFXML(lang.getLocale()); // 获取对应语言的新组件树
        currentRoot.getChildren().setAll(newNode.getChildren());// 替换旧组件为新语言版本的组件
    }



    // 加载组件树并以VBox类型返回(FXML的根元素)
    private VBox loadFXML(Locale locale) {
        fxmlLoader = new FXMLLoader();

        fxmlLoader.setLocation(getClass().getResource("fxml/main.fxml"));
        fxmlLoader.setResources(ResourceBundle.getBundle(BUNDLES_FOLDER, locale));

        VBox node = null;

        try {
            node = (VBox) fxmlLoader.load();

            mainController = fxmlLoader.getController();
            mainController.addObserver(this);
            primaryStage.setTitle(fxmlLoader.getResources().getString("address_book"));

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

        return node;
    }

    private void createGUI(Locale locale) {
        currentRoot = loadFXML(locale);
        Scene scene = new Scene(currentRoot, 300, 275);
        primaryStage.setScene(scene);
        primaryStage.setMinHeight(600);
        primaryStage.setMinWidth(400);
        primaryStage.show();
    }
}

main.fxml代码

<?import java.lang.*?>
<?import org.controlsfx.control.textfield.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import org.controlsfx.control.textfield.CustomTextField?>

<VBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ru.javabegin.training.fastjava2.javafx.controllers.MainController">
    <children>
        <HBox maxHeight="50.0" prefHeight="100.0">
            <children>
                <Button fx:id="btnAdd" minWidth="80.0" mnemonicParsing="false" onAction="#actionButtonPressed" text="%add">
                    <HBox.margin>
                        <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
                    </HBox.margin>
                </Button>
                <Button fx:id="btnEdit" minWidth="80.0" mnemonicParsing="false" onAction="#actionButtonPressed" text="%edit">
                    <HBox.margin>
                        <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
                    </HBox.margin>
                </Button>
                <Button fx:id="btnDelete" minWidth="80.0" mnemonicParsing="false" onAction="#actionButtonPressed" text="%delete">
                    <HBox.margin>
                        <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
                    </HBox.margin>
                </Button>
            </children>
        </HBox>
        <AnchorPane maxHeight="30.0" prefHeight="100.0">
            <children>
                <CustomTextField fx:id="txtSearch" prefHeight="31.0" prefWidth="293.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="80.0" />
                <Button fx:id="btnSearch" layoutX="266.0" mnemonicParsing="false" onAction="#actionSearch" text="%search" AnchorPane.rightAnchor="0.0" />
            </children>
            <VBox.margin>
                <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
            </VBox.margin>
        </AnchorPane>
        <AnchorPane prefHeight="100.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
            <children>
                <TableView fx:id="tableAddressBook" prefHeight="400.0" prefWidth="357.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                    <columns>
                        <TableColumn fx:id="columnFIO" minWidth="100.0" text="%fio" />
                        <TableColumn fx:id="columnPhone" minWidth="100.0" prefWidth="-1.0" text="%phone" />
                    </columns>
                    <columnResizePolicy>
                        <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
                    </columnResizePolicy>
                </TableView>
            </children>
            <VBox.margin>
                <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
            </VBox.margin>
        </AnchorPane>
      <AnchorPane prefHeight="30.0" prefWidth="200.0">
         <children>
                <Label fx:id="labelCount" text="%count" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" />
            <ComboBox fx:id="comboLocales" layoutX="229.0" layoutY="-1.0" prefHeight="31.0" prefWidth="144.0" AnchorPane.bottomAnchor="0.0" AnchorPane.rightAnchor="0.0" />
         </children>
         <VBox.margin>
            <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
         </VBox.margin>
      </AnchorPane>
    </children>
</VBox>

错误日志

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
    at java.base/java.lang.reflect.Method.invoke(Method.java:578)
    at javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
    at java.base/java.lang.reflect.Method.invoke(Method.java:578)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1081)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:893)
    at javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:1589)
Caused by: java.lang.IllegalStateException: Location is not set.
    at javafx.fxml@20.0.1/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2556)
    at javafx.fxml@20.0.1/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2531)
    at ru.javabegin.training.fastjava2.javafx.start.Main.loadFXML(Main.java:64)
    at ru.javabegin.training.fastjava2.javafx.start.Main.createGUI(Main.java:78)
    at ru.javabegin.training.fastjava2.javafx.start.Main.start(Main.java:37)
    at javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839)
    at javafx.graphics@20.0.1/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
    at javafx.graphics@20.0.1/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at javafx.graphics@20.0.1/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
    at javafx.graphics@20.0.1/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Exception running application ru.javabegin.training.fastjava2.javafx.start.Main

Process finished with exit code 1

环境版本信息

  • Java:openJDK 19 LTS/17
  • 依赖库:controlsfx-8.40.12
  • JavaFX:javafx-sdk-20.0.1
  • VM参数:--module-path $JavaFX19$ --add-modules javafx.controls,javafx.fxml

解决方法

这个异常的核心原因是getClass().getResource("fxml/main.fxml")返回了null,导致FXMLLoader的Location未设置。可以从以下几个方向排查:

  1. 修正FXML路径写法
    假设Main类的包是ru.javabegin.training.fastjava2.javafx.start,如果fxml目录和start包同级,必须使用类路径绝对路径:

    fxmlLoader.setLocation(getClass().getResource("/ru/javabegin/training/fastjava2/javafx/fxml/main.fxml"));
    

    或者如果fxml目录在类路径根目录下,直接写:

    fxmlLoader.setLocation(getClass().getResource("/fxml/main.fxml"));
    
  2. 标记资源目录
    确保fxml所在目录被IDE标记为资源目录(比如IDEA中右键目录选择「Mark Directory as -> Resources Root」),编译时文件才会被复制到classpath对应位置。

  3. 添加存在性检查
    在加载前验证资源是否存在,方便快速定位问题:

    URL fxmlUrl = getClass().getResource("/fxml/main.fxml");
    if (fxmlUrl == null) {
        throw new IOException("FXML文件未找到:/fxml/main.fxml");
    }
    fxmlLoader.setLocation(fxmlUrl);
    
  4. 避免相对路径歧义
    代码中定义的../fxml/main.fxml这类相对路径在classpath中容易出错,统一使用基于类路径的绝对路径写法。

内容的提问来源于stack exchange,提问作者Aziret

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 08:13:07