我正在尝试加载包含另一个FXML文件(Test2.fxml)的FXML文件(Test1.fxml)。 包含的文件应该使用自己的资源包(test2.properties),该资源包由" resources" fx:include标记内的属性。
当我运行应用程序时,FXMLLoader抛出一个NullPointerException,由以下代码引起。
resources = ResourceBundle.getBundle(value, Locale.getDefault(),
FXMLLoader.this.resources.getClass().getClassLoader());
通过调试我发现FXMLLoader.this.resources为null,这会导致NPE。起初我以为我只是给出了一个错误的文件路径,但请注意,这在ResourceBundle尝试加载属性文件之前就已经发生了!
知道如何解决这个问题,以便可以加载资源吗?
以下是我的文件。它们都在同一目录中(为简单起见,默认包)。
TestApp.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class TestApp extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getClassLoader().getResource("Test1.fxml"));
loader.load();
Scene scene = new Scene((Parent) loader.getRoot());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
Test1.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<center>
<fx:include source="Test2.fxml" resources="test2" />
</center>
</BorderPane>
Test2.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<center>
<Label text="%test" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
test2.properties
test=Test 2
完整的堆栈跟踪:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$152(LauncherImpl.java:182)
at com.sun.javafx.application.LauncherImpl$$Lambda$50/1645995473.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Caused by: javafx.fxml.LoadException:
/C:/Eclipse/fx/bin/Test1.fxml:9
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2605)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2583)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2445)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2413)
at TestApp.start(TestApp.java:16)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$159(LauncherImpl.java:863)
at com.sun.javafx.application.LauncherImpl$$Lambda$53/1370226249.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl$$Lambda$45/186276003.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/1026297962.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/237061348.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda$36/2117255219.run(Unknown Source)
... 1 more
Caused by: java.lang.NullPointerException
at javafx.fxml.FXMLLoader$IncludeElement.processAttribute(FXMLLoader.java:1088)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:216)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:740)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2711)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2531)
... 17 more
Exception running application TestApp
答案 0 :(得分:2)
FXMLLoader中有一个bug。解决这个问题:
可以在oracle论坛中找到可能的解决方法:https://community.oracle.com/message/11240449
如果您不需要root fxml文件的resourceBundle(如示例所示),您可以使用这个简单的解决方法:
<强> TestApp.java 强>
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class TestApp extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
FXMLLoader loader = new FXMLLoader();
// add the resource wrapper
loader.setResources(new ResourceWrapper());
loader.setLocation(getClass().getClassLoader().getResource("Test1.fxml"));
loader.load();
Scene scene = new Scene((Parent) loader.getRoot());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
// an empty resource bundle
private static class ResourceWrapper extends ListResourceBundle {
@Override
protected Object[][] getContents() {
return new Object[0][];
}
}
}