我正在使用Java JDK 13和FontAwesomeFX11。
我有一个FXML文件,其中包含一些FontAwesomeIconViews,但是将文件加载到控制器中时,我得到的是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)
答案 0 :(得分:6)
每当获得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
出了问题。
但是,如果您继续阅读stacktrace:
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,您仍然可以这样做。
对于初学者来说,请查看带有Eclipse的JavaFX 13指南:https://openjfx.io/openjfx-docs/#IDE-Eclipse,然后选择您的情况。
如果您的情况不是IDE的模块化,则在设置VM参数时应像这样:
--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
对于其他情况,逻辑是相同的。