FXMLLoader中fx:include的resources属性抛出MissingResourceException问题
问题描述
在FXML文件的<fx:include>标签中使用resources属性加载资源包时抛出MissingResourceException,但手动通过ResourceBundle.getBundle()加载该资源包完全正常。尝试过lang_challenges、wand555/github/io/challengesreworkedgui/lang_challenges等多种路径格式,均无法解决问题。
相关代码
ChallengeApplication.java
package wand555.github.io.challengesreworkedgui; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; import java.io.IOException; import java.util.Enumeration; import java.util.Locale; import java.util.ResourceBundle; import java.util.Set; public class ChallengeApplication extends Application { @Override public void start(Stage stage) throws IOException { ResourceBundle.clearCache(); ResourceBundle bundle = new ResourceBundleWrapper(ResourceBundle.getBundle("wand555/github/io/challengesreworkedgui/lang_challenges")); System.out.println(bundle.getString("challenge.name")); // 输出 "abc" FXMLLoader loader = new FXMLLoader(ChallengeApplication.class.getResource("overview.fxml"), bundle); Parent root = loader.load(); Scene scene = new Scene(root, 1000, 1000); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(); } // 包装类确保资源包由应用类加载器加载 private static class ResourceBundleWrapper extends ResourceBundle { private final ResourceBundle bundle; ResourceBundleWrapper(ResourceBundle bundle) { this.bundle = bundle; } @Override protected Object handleGetObject(String key) { return bundle.getObject(key); } @Override public Enumeration<String> getKeys() { return bundle.getKeys(); } @Override public boolean containsKey(String key) { return bundle.containsKey(key); } @Override public Locale getLocale() { return bundle.getLocale(); } @Override public Set<String> keySet() { return bundle.keySet(); } } }
overview.fxml
<?xml version="1.0" encoding="UTF-8"?> <AnchorPane prefHeight="500.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="wand555.github.io.challengesreworkedgui.controllers.OverviewController"> <children> <VBox> <children> <StackPane alignment="CENTER_LEFT"> <children> <Button fx:id="exportButton" mnemonicParsing="false" onAction="#onExport" text="Export" /> </children> </StackPane> <HBox prefHeight="100.0" prefWidth="200.0" spacing="25.0"> <children> <fx:include fx:id="challengesOverview" source="challenges/challenges_overview.fxml" resources="lang_challenges" charset="utf-8"/> <Separator orientation="VERTICAL" prefHeight="200.0" /> <fx:include source="goals/goal_overview.fxml" /> <Separator orientation="VERTICAL" prefHeight="200.0" /> </children> </HBox> </children> </VBox> </children> </AnchorPane>
资源包文件
lang_challenges.properties:
challenge.name=abc
lang_challenges_de.properties:
challenge.name=abc
错误信息
Exception in Application start method java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at javafx.graphics@19/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:465) at javafx.graphics@19/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1082) Caused by: java.lang.RuntimeException: Exception in Application start method at javafx.graphics@19/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:901) at javafx.graphics@19/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: javafx.fxml.LoadException: /Users/felixnaumann/Documents/ChallengesReworked/ChallengesReworkedGUI/target/classes/wand555/github/io/challengesreworkedgui/overview.fxml:21 at javafx.fxml@19/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2707) at javafx.fxml@19/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2685) at javafx.fxml@19/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548) at javafx.fxml@19/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2516) at challenges.reworked.gui/wand555.github.io.challengesreworkedgui.ChallengeApplication.start(ChallengeApplication.java:22) at javafx.graphics@19/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847) at javafx.graphics@19/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484) at javafx.graphics@19/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at javafx.graphics@19/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456) at javafx.graphics@19/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96) Caused by: java.util.MissingResourceException: Can't find bundle for base name lang_challenges, locale de_DE at java.base/java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:2045) at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1683) at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1575) at java.base/java.util.ResourceBundle.getBundle(ResourceBundle.java:1280) at javafx.fxml@19/javafx.fxml.FXMLLoader$IncludeElement.processAttribute(FXMLLoader.java:1100) at javafx.fxml@19/javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:230) at javafx.fxml@19/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:755) at javafx.fxml@19/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2808) at javafx.fxml@19/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2634) ... 9 more Exception running application wand555.github.io.challengesreworkedgui.ChallengeApplication
解决方案
1. 修正资源包名称格式
FXML的resources属性不支持斜杠分隔的路径,必须使用点分隔的全限定类名格式。把<fx:include>中的resources属性值改成:
resources="wand555.github.io.challengesreworkedgui.lang_challenges"
FXML内部调用ResourceBundle.getBundle()时遵循Java类的全限定名规则,只有点分隔的格式能被正确识别。
2. 复用父FXML的资源包(更推荐)
如果子FXML和父FXML使用同一个资源包,完全不需要在<fx:include>中指定resources属性——子FXML会自动继承父FXML加载时传入的资源包。修改后的代码如下:
<fx:include fx:id="challengesOverview" source="challenges/challenges_overview.fxml" charset="utf-8"/>
这种方式既避免了路径错误,还简化了代码结构。
3. 确认资源文件位置
你的资源包文件已经放在了正确的classpath路径下(target/classes/wand555/github/io/challengesreworkedgui/),手动加载正常也验证了这一点,所以这部分无需调整。
内容的提问来源于stack exchange,提问作者wand555
相关产品推荐
相关产品推荐

