我正在尝试开发一个需要能够在 3D 空间中查看/操作模型的应用程序,JavaFX 似乎是一个明显的候选者。如果有人可以提出更好的选择,那么我会很高兴听到它!
我正在使用在 MacOS Catalina 10.15.4 上运行的 IntelliJ CE 2019.3.3 和 Java 14,据我所知这是最新版本。矛盾的是,考虑到 JavaFX 的曲折历史及其与主流 Java 的关系(感谢 Oracle),我担心使用最新的 JDK 可能是我所有问题的根源。
我下载了一个简单的应用程序,它在我成功运行的场景中添加了一些简单的形状。我通过向我的 pom.xml 添加两个依赖项将 JavaFX 库添加到我的项目中:
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>11</version>
</dependency>
注意我假设(可能是错误的)JavaFX 版本控制独立于 JDK 版本控制运行。
不幸的是,当我在这个程序中添加一些稍微复杂的东西时,我得到了以下错误:
/Library/Java/JavaVirtualMachines/jdk-14.jdk/Contents/Home/bin/java --add-modules FXTest.base,FXTest.graphics --add-reads FXTest.base=ALL-UNNAMED --add-reads FXTest.graphics=ALL-UNNAMED -Dfile.encoding=UTF-8 -classpath /Users/Joe/Programming/myproj-mvn/target/classes:/Users/Andy/.m2/repository/org/junit/jupiter/junit-jupiter/5.4.2/junit-jupiter-5.4.2.jar:/Users/Andy/.m2/repository/org/junit/jupiter/junit-jupiter-api/5.4.2/junit-jupiter-api-5.4.2.jar:/Users/Andy/.m2/repository/org/apiguardian/apiguardian-api/1.0.0/apiguardian-api-1.0.0.jar:/Users/Andy/.m2/repository/org/opentest4j/opentest4j/1.1.1/opentest4j-1.1.1.jar:/Users/Andy/.m2/repository/org/junit/platform/junit-platform-commons/1.4.2/junit-platform-commons-1.4.2.jar:/Users/Andy/.m2/repository/org/junit/jupiter/junit-jupiter-params/5.4.2/junit-jupiter-params-5.4.2.jar:/Users/Andy/.m2/repository/org/junit/jupiter/junit-jupiter-engine/5.4.2/junit-jupiter-engine-5.4.2.jar:/Users/Andy/.m2/repository/org/junit/platform/junit-platform-engine/1.4.2/junit-platform-engine-1.4.2.jar:/Users/Andy/.m2/repository/org/apache/commons/commons-csv/1.8/commons-csv-1.8.jar:/Users/Andy/.m2/repository/org/openjfx/FXTest-controls/11/FXTest-controls-11.jar:/Users/Andy/.m2/repository/org/openjfx/FXTest-controls/11/FXTest-controls-11-mac.jar:/Users/Andy/.m2/repository/org/openjfx/FXTest-graphics/11/FXTest-graphics-11.jar:/Users/Andy/.m2/repository/org/openjfx/FXTest-graphics/11/FXTest-graphics-11-mac.jar:/Users/Andy/.m2/repository/org/openjfx/FXTest-base/11/FXTest-base-11.jar:/Users/Andy/.m2/repository/org/openjfx/FXTest-base/11/FXTest-base-11-mac.jar:/Users/Andy/.m2/repository/org/apache/logging/log4j/log4j-api/2.13.1/log4j-api-2.13.1.jar:/Users/Andy/.m2/repository/org/apache/logging/log4j/log4j-core/2.13.1/log4j-core-2.13.1.jar -p /Users/Andy/.m2/repository/org/openjfx/FXTest-base/11/FXTest-base-11-mac.jar:/Users/Andy/.m2/repository/org/openjfx/FXTest-graphics/11/FXTest-graphics-11-mac.jar net.foobar.myproj.FXTest
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at FXTest.graphics/com.sun.FXTest.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at FXTest.graphics/com.sun.FXTest.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.IllegalAccessError: class FXTest.scene.control.PopupControl (in unnamed module @0x5b464ce8) cannot access class com.sun.FXTest.application.PlatformImpl (in module FXTest.graphics) because module FXTest.graphics does not export com.sun.FXTest.application to unnamed module @0x5b464ce8
at FXTest.scene.control.PopupControl.<clinit>(PopupControl.java:90)
at net.foobar.myproj.FXTest.main(FXTest.java:24)
... 11 more
Exception running application net.foobar.myproj.FXTest
Process finished with exit code 1
我可以通过手动将整个 JavaFX 库下载到新目录并将以下选项添加到我的运行时 VM 选项来克服这个问题:
--add-modules
javafx.controls
-p
/Users/Joe/Downloads/openjfx/javafx-sdk-11.0.2/lib
不幸的是,当我将一个新类导入我的应用程序时,我发现我得到了这个错误的变种,我发现这种方式非常不可预测(并且难以修复)。我的灵感和耐心都快用完了——也没有模块可以添加到 VM 选项列表中。
在两个不同的位置使用 JavaFX 库也感觉很俗气——我的下载目录和我的本地.m2 Maven存储库。
谁能为我的痛苦提出更好的解决方案——替代 3D 包或管理 JavaFX 库的更好方法?
编辑我的问题以显示我取得的进展(希望我可以以另一种方式添加更多细节)。
好的,在舔了一会儿伤口后,我决定喝Maven Kool-aid,一直喝到杯底。
我首先基于javafx-archetype-simple创建了一个 Maven 项目。我通过跟踪JavaFX站点的Maven 插件的链接找到了这一点。完成此操作后,我就可以使用mvn compile编译代码,然后使用mvn javafx:run运行它。结果=成功!
我欣喜若狂,然后决定将项目导入 IntelliJ - 结果好坏参半。我不得不修改“运行”配置,以使用mvn插件(见上文),这部分似乎工作。
更新 #2:我现在增强了我的 IDE '运行配置'命令以mvn compile javafx:run强制代码在运行之前重新编译(如果需要重新编译 - maven 就是这样聪明)。
祝我好运 - 我会在继续的过程中更新这篇文章。