我试图将Maven支持添加到现有的JavaFX项目中。
我从OpenJFX的入门指南开始,它教您如何用Maven编译和运行Hello World JavaFX应用程序。 在我完成之后,我将我的项目的文件粘贴到这个新项目中,并进行所需的更改。 我的文件夹结构大致是这样的:
src/main/
java/
org.openjfx/
Main.java
components/
controllers/
resources/org.openjfx/fxml/
要运行项目,我使用以下Maven命令:
compiler:compile
javafx:compile
javafx:run
但是,我得到了这个错误:
应用程序启动方法中的异常,原因是:java.lang.IllegalAccessException:类javafx.fxml.fxmlLoader$ValueElement(在模块javafx.fxml中)无法访问类org.openjfx.Controllers.LoginController(在模块org.openjfx中),因为模块org.openjfx没有将org.openjfx.Controllers导出到模块javafx.fxml
这看起来很奇怪,因为显然我正在导出module-info.java
中的内容:
module org.openjfx {
requires javafx.controls;
requires javafx.fxml;
opens org.openjfx to javafx.fxml;
exports org.openjfx;
}
我想知道将我的包命名为org.openjfx
是不是一个坏主意,可能会引起问题,但我只是按照教程进行了操作。
下面是我的pom.xml
文件,如果它相关的话:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.openjfx</groupId>
<artifactId>hellofx</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>11</maven.compiler.release>
<javafx.version>13</javafx.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>${maven.compiler.release}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.3</version>
<configuration>
<mainClass>org.openjfx.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
javafx.fxml
模块实例化控制器类,并通过反射访问其中的字段和方法。 为了使其工作,您需要打开
包含javafx.fxml
模块的任何控制器的特定包。
这是理解模块系统的一个很好的资源。 引述如下:
打开,打开,打开……到。 在Java 9之前,反射可以用来了解包中的所有类型以及类型的所有成员--甚至是它的私有成员--无论您是否希望允许这种能力。 因此,没有任何东西被真正封装。
模块系统的一个关键动机是强大的封装性。 默认情况下,模块中的类型不能被其他模块访问,除非它是公共类型并且您导出了它的包。 只公开要公开的包。 对于Java 9号,这也适用于反思。
。。。
允许特定模块仅在运行时访问包。 表单的打开…到模块指令
opens package to comma-separated-list-of-modules
指示特定包的公共类型(及其嵌套的公共类型和受保护类型)仅在运行时可由所列模块中的代码访问。 通过对指定模块中代码的反射,可以访问指定包中的所有类型(以及所有类型的成员)。
请注意,您打开的是包,而不是模块。 由于您的控制器位于子包org.openjfx.controllers
中(我确实认为您应该更改您的基本包名称),因此您需要显式地打开该子包(可能还有其他子包)。
因此,添加
opens org.openjfx.controllers to javafx.fxml ;
到module-info.java
文件应该可以修复该问题