【问题标题】:import of java.lang.String fails in JAVAFX 11 FXML在 JAVAFX 11 FXML 中导入 java.lang.String 失败
【发布时间】:2020-02-06 17:43:18
【问题描述】:

我有一个 JAVAFX 11 FXML 文件,描述了我在应用程序中使用的弹出窗口。在重构项目结构后,我将 FXML 从“app”项目移动到另一个项目,我收到 NullPointerException 错误,因为 XML 加载器无法导入 java.lang.String(和其他)

FXML 如下所示:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.String?>
<?import javafx.collections.FXCollections?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Spinner?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>

<TitledPane fx:id="GeneticMain" 
animated="false"
maxHeight="-Infinity"
maxWidth="-Infinity"
minHeight="-Infinity" 
minWidth="-Infinity"
prefHeight="400.0"
prefWidth="400.0"
text="Genetic Scanner Config" 
xmlns="http://javafx.com/javafx/8.0.141"
xmlns:fx="http://javafx.com/fxml/1">
  <content>
    <AnchorPane minHeight="-Infinity" minWidth="-Infinity">
         <children>
            <GridPane layoutX="10.0"
...

堆栈跟踪的底部:

Caused by: java.lang.NullPointerException
    at javafx.fxml.FXMLLoader.loadTypeForPackage(FXMLLoader.java:2931) ~[javafx-fxml-12.0.1-linux.jar:?]
    at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2920) ~[javafx-fxml-12.0.1-linux.jar:?]
    at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2861) ~[javafx-fxml-12.0.1-linux.jar:?]
    at javafx.fxml.FXMLLoader.processImport(FXMLLoader.java:2707) ~[javafx-fxml-12.0.1-linux.jar:?]
    at javafx.fxml.FXMLLoader.processProcessingInstruction(FXMLLoader.java:2676) ~[javafx-fxml-12.0.1-linux.jar:?]
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2542) ~[javafx-fxml-12.0.1-linux.jar:?]

Javafx 的有效 POM 依赖项如下所示:

<properties>
   ...
   <dependencyversion.openjfx>12.0.1</dependencyversion.openjfx>
   ...
</properties>
...
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-base</artifactId>
    <version>12.0.2</version>
</dependency>
<dependency>
  <groupId>de.gsi.chart</groupId>
  <artifactId>chartfx-chart</artifactId>
  <version>11.0.3</version>
  <scope>compile</scope>
  <exclusions>
    <exclusion>
      <artifactId>commons-logging</artifactId>
      <groupId>commons-logging</groupId>
    </exclusion>
    <exclusion>
      <artifactId>javafx-base</artifactId>
      <groupId>org.openjfx</groupId>
    </exclusion>
    <exclusion>
      <artifactId>javafx-web</artifactId>
      <groupId>org.openjfx</groupId>
    </exclusion>
  </exclusions>
</dependency>

我很高兴有任何建议...

【问题讨论】:

  • 显示完整的 pom(至少 所有 JavaFX 依赖项和运行插件)
  • 为什么只有javafx-base?还有其他JavaFX模块,包括javafx-fxml...见openjfx.io/openjfx-docs/#maven
  • 在我的 POM 中添加了 javafx-fxmljavafx-controls。还是一样……
  • 查看loadTypeForPackageloadType 的源代码,这个异常只有一个可能的原因:FXMLLoader 无法得到ClassLoader,即!= null。 ..(使用System.out.println(new FXMLLoader().getClassLoader()); 验证这一点;除null 之外的任何值,我错了。)您是否使用了不允许访问类加载器的安全管理器?如果是这样,您需要在加载 fxml 之前手动设置加载器的classLoader 属性...
  • 您可以尝试使用用于加载 javafx 类之一的类加载器,例如Node.class.getClassLoader()...

标签: javafx load javafx-11 openjfx


【解决方案1】:

感谢fabian 我能够为我的问题提供解决方案。

我的问题的根本原因是在PopupController.showPopupWindow() 中调用的弹出窗口的类加载器为空。 初始代码

 public void showPopupWindow() throws Exception {
        Parent popupWindowRoot = null;
        try {
            URL url = getClass().getResource(url.to.popupFXML.file);
            final FXMLLoader fxmlLoader = new FXMLLoader(url);
            fxmlLoader.setController(this);
            popupWindowRoot = (Parent) fxmlLoader.load();
        } catch (final IOException e) {
            MessageLogger.logError(getClass(), e);
            throw e;
        }
        ...
}

通过主窗口中的 onAction 方法调用:

private void handle_onAction(event onAction) throws Exception {
    popupController = new PopupController();
    popupController.setParentController(this);
    try {
        popupController.showPopupWindow();
    } catch (final Exception ex) {
        APPLOGGER.error(true, true, "Error caught in method showPopupWindow(): ");
    }
}

按照 Fabian 的建议,我将主窗口的阶段传递给方法showPopupWindow,并使用该阶段明确设置弹出窗口的类加载器。 新代码

 public void showPopupWindow(Stage parentStage) throws Exception {
        Parent popupWindowRoot = null;
        try {
            URL url = getClass().getResource(url.to.popupFXML.file);
            final FXMLLoader fxmlLoader = new FXMLLoader(url);
            fxmlLoader.setController(this);
            fxmlLoader.setClassLoader(parentStage.getClass().getClassLoader());
            popupWindowRoot = (Parent) fxmlLoader.load();
        } catch (final IOException e) {
            MessageLogger.logError(getClass(), e);
            throw e;
        }
        ...
}

调用方式做了相应调整。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 2019-07-20
    • 1970-01-01
    • 2013-06-25
    • 2019-03-07
    相关资源
    最近更新 更多