简体   繁体   English

为什么在加载我的 FXML 文件时收到 javafx.fxml.LoadException?

[英]Why am I receiving a javafx.fxml.LoadException when loading my FXML file?

I'm using Java JDK 13, and FontAwesomeFX 11.我正在使用 Java JDK 13 和 FontAwesomeFX 11。

I have a FXML file which contains some FontAwesomeIconViews, but when loading the file into my controller I'm getting a javafx.fxml.LoadException.我有一个 FXML 文件,其中包含一些 FontAwesomeIconViews,但是当将文件加载到我的 controller 时,我得到了 javafx.fxml.LoadException。 This is how the FXML file looks like:这是 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>

I'm getting the error on the first FontAwesomeIconView element (WINDOW_MINIMIZE).我在第一个 FontAwesomeIconView 元素 (WINDOW_MINIMIZE) 上遇到错误。

I have suspicions it could be because FontAwesomeFX 11 expects FontAwesomeIconViews to be formatted in another way, but I'm not sure at all.我怀疑这可能是因为 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)

Whenever you get a javafx.fxml.LoadException , you have to read the whole stacktrace until the very end.每当您收到javafx.fxml.LoadException时,您都必须阅读整个堆栈跟踪,直到最后。 It will show, usually at the end, the real cause for the exception.它通常会在最后显示异常的真正原因

Let's say you have this build.gradle file, and your project is non-modular:假设您有这个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' ]
}

and the FXML file with FontAwesomeIconView :以及带有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>

Then you run the project:然后运行项目:

./gradlew clean run

and you get:你得到:

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)

If you stop reading there, you will think something is wrong with the line scene.fxml:7 which is the FontAwesomeIconView one.如果您停止阅读,您会认为scene.fxml:7行有问题,它是FontAwesomeIconView

But if you keep reading the 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)
... 

that last Caused by says exactly the reason of the problem:最后Caused by正好说明了问题的原因:

module javafx.graphics does not "opens javafx.css" to unnamed module @32ab3e54模块 javafx.graphics 不会“打开 javafx.css”到未命名模块 @32ab3e54

This is due to the use of reflection in GlyphIcon to access private API.这是由于在GlyphIcon中使用反射来访问私有 API。

So now that you know the reason, all you have to do is provide the solution: In this case, we will add the requested --add-opens to the jvm args in the build.gradle file:因此,既然您知道了原因,您所要做的就是提供解决方案:在这种情况下,我们会将请求的--add-opens添加到 build.gradle 文件中的 jvm args 中:

run {
    jvmArgs = ["--add-opens", "javafx.graphics/javafx.css=ALL-UNNAMED"]
}

Running again it will work.再次运行它将起作用。

Note 1注1

If you have a modular project, with a module-info descriptor like:如果您有一个模块化项目,其模块信息描述符如下:

module hellofx {
    requires javafx.controls;
    requires javafx.fxml;
    requires de.jensd.fx.fontawesomefx.fontawesome;

    opens org.openjfx to javafx.fxml;
    exports org.openjfx;
}

then you have to add instead:那么你必须添加:

run {
    jvmArgs = ["--add-opens", "javafx.graphics/javafx.css=de.jensd.fx.fontawesomefx.commons"]
}

Note 2笔记2

If you are not using Gradle, you can still do the same.如果您不使用 Gradle,您仍然可以这样做。

For starters check the guide JavaFX 13 with Eclipse: https://openjfx.io/openjfx-docs/#IDE-Eclipse , and then choose your case.对于初学者,请查看指南 JavaFX 13 和 Eclipse: https://openjfx.io/openjfx-docs/#IDE-Eclipse ,然后选择您的案例

If your case is non-modular from IDE, when you set the VM arguments like:如果您的案例是 IDE 的非模块化案例,则在设置 VM arguments 时,如下所示:

--module-path /path/to/javafx-sdk-13/lib --add-modules javafx.controls,javafx.fxml

all you need to do now is include the extra argument, like:您现在需要做的就是包含额外的参数,例如:

--module-path /path/to/javafx-sdk-13/lib --add-modules javafx.controls,javafx.fxml \
--add-opens javafx.graphics/javafx.css=ALL-UNNAMED

For other cases, the logic is the same.对于其他情况,逻辑是相同的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM