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未设置。可以从以下几个方向排查:
修正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"));标记资源目录
确保fxml所在目录被IDE标记为资源目录(比如IDEA中右键目录选择「Mark Directory as -> Resources Root」),编译时文件才会被复制到classpath对应位置。添加存在性检查
在加载前验证资源是否存在,方便快速定位问题:URL fxmlUrl = getClass().getResource("/fxml/main.fxml"); if (fxmlUrl == null) { throw new IOException("FXML文件未找到:/fxml/main.fxml"); } fxmlLoader.setLocation(fxmlUrl);避免相对路径歧义
代码中定义的../fxml/main.fxml这类相对路径在classpath中容易出错,统一使用基于类路径的绝对路径写法。
内容的提问来源于stack exchange,提问作者Aziret
相关产品推荐
相关产品推荐

