[英]Why am I receiving a javafx.fxml.LoadException when loading my FXML file?
我正在使用 Java JDK 13 和 FontAwesomeFX 11。
我有一个 FXML 文件,其中包含一些 FontAwesomeIconViews,但是当将文件加载到我的 controller 时,我得到了 javafx.fxml.LoadException。 这是 FXML 文件的样子:
<?xml version="1.0" encoding="UTF-8"?>
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<VBox id="window" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<BorderPane id="upper" fx:id="upper" prefHeight="50.0" prefWidth="800.0" stylesheets="@style.css">
<left>
<Label text="TEXT" BorderPane.alignment="CENTER">
<font>
<Font size="20.0" />
</font>
</Label>
</left>
<right>
<HBox prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
LINE 27 <FontAwesomeIconView glyphName="WINDOW_MINIMIZE" size="20" />
<FontAwesomeIconView glyphName="CLOSE" size="30" />
</children></HBox>
</right>
</BorderPane>
<AnchorPane id="body" prefHeight="554.0" prefWidth="800.0">
<children>
<TextField layoutX="326.0" layoutY="233.0" promptText="Usuario" />
<PasswordField layoutX="326.0" layoutY="276.0" promptText="Contraseña" />
<Button layoutX="353.0" layoutY="334.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="94.0" text="Acceder" />
<Label layoutX="326.0" layoutY="372.0" text="¿Ha olvidado la contraseña?" />
<FontAwesomeIconView glyphName="USER_CIRCLE" layoutX="350.0" layoutY="185.0" size="100" />
</children>
</AnchorPane>
</children>
</VBox>
</children>
</VBox>
我在第一个 FontAwesomeIconView 元素 (WINDOW_MINIMIZE) 上遇到错误。
我怀疑这可能是因为 FontAwesomeFX 11 期望 FontAwesomeIconViews 以另一种方式格式化,但我完全不确定。
Error al cargar el archivo vista Login.fxml: javafx.fxml.LoadException:
.../bin/view/login.fxml:27
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: Root cannot be null
at javafx.graphics/javafx.scene.Scene.<init>(Scene.java:345)
at javafx.graphics/javafx.scene.Scene.<init>(Scene.java:236)
at controller.SplashController$SplashScreen$2.run(SplashController.java:78)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:830)
每当您收到javafx.fxml.LoadException
时,您都必须阅读整个堆栈跟踪,直到最后。 它通常会在最后显示异常的真正原因。
假设您有这个build.gradle
文件,并且您的项目是非模块化的:
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
repositories {
jcenter()
}
dependencies {
implementation "de.jensd:fontawesomefx-commons:11.0"
implementation "de.jensd:fontawesomefx-fontawesome:4.7.0-11"
}
mainClassName = 'org.openjfx.MainApp'
javafx {
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
以及带有FontAwesomeIconView
的 FXML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.openjfx.FXMLController">
<FontAwesomeIconView glyphName="WINDOW_MINIMIZE" size="20" />
</VBox>
然后运行项目:
./gradlew clean run
你得到:
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javafx.fxml.LoadException:
/.../build/resources/main/org/openjfx/scene.fxml:7
at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
如果您停止阅读,您会认为scene.fxml:7
行有问题,它是FontAwesomeIconView
。
但是,如果您继续阅读堆栈跟踪:
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javafx.fxml.LoadException:
/.../build/resources/main/org/openjfx/scene.fxml:7
at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
...
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml/com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:262)
...
Caused by: java.lang.reflect.InaccessibleObjectException: \
Unable to make javafx.css.ParsedValue javafx.css.CssParser.parseExpr(java.lang.String,java.lang.String) accessible: \
module javafx.graphics does not "opens javafx.css" to unnamed module @32ab3e54
...
at de.jensd.fx.glyphs.GlyphIcon.convert(GlyphIcon.java:248)
...
最后Caused by
正好说明了问题的原因:
模块 javafx.graphics 不会“打开 javafx.css”到未命名模块 @32ab3e54
这是由于在GlyphIcon
中使用反射来访问私有 API。
因此,既然您知道了原因,您所要做的就是提供解决方案:在这种情况下,我们会将请求的--add-opens
添加到 build.gradle 文件中的 jvm args 中:
run {
jvmArgs = ["--add-opens", "javafx.graphics/javafx.css=ALL-UNNAMED"]
}
再次运行它将起作用。
注1
如果您有一个模块化项目,其模块信息描述符如下:
module hellofx {
requires javafx.controls;
requires javafx.fxml;
requires de.jensd.fx.fontawesomefx.fontawesome;
opens org.openjfx to javafx.fxml;
exports org.openjfx;
}
那么你必须添加:
run {
jvmArgs = ["--add-opens", "javafx.graphics/javafx.css=de.jensd.fx.fontawesomefx.commons"]
}
笔记2
如果您不使用 Gradle,您仍然可以这样做。
对于初学者,请查看指南 JavaFX 13 和 Eclipse: https://openjfx.io/openjfx-docs/#IDE-Eclipse ,然后选择您的案例
如果您的案例是 IDE 的非模块化案例,则在设置 VM arguments 时,如下所示:
--module-path /path/to/javafx-sdk-13/lib --add-modules javafx.controls,javafx.fxml
您现在需要做的就是包含额外的参数,例如:
--module-path /path/to/javafx-sdk-13/lib --add-modules javafx.controls,javafx.fxml \
--add-opens javafx.graphics/javafx.css=ALL-UNNAMED
对于其他情况,逻辑是相同的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.