我正在尝试开发一款需要在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库也让人觉得很俗气——我的Downloads目录和我的本地.m2Maven存储库。
有人能为我的痛苦提出一个更好的解决方案吗?要么是一个替代的3D包,要么是管理JavaFX库的更好方法?
编辑我的问题以显示我所取得的进展(希望我能以另一种方式添加更多细节(
好吧,在舔舐了我的伤口之后,我决定喝MavenKool aid,一直喝到杯子底部。
我首先创建了一个基于javafx原型simple的Maven项目。我是按照JavaFX站点Maven插件的链接找到这一点的。一旦我完成了这项工作,我就可以使用mvn-compile编译代码,然后使用mvn-javafx:run运行它。结果=成功!
我喜极而泣,然后决定将该项目导入IntelliJ,结果喜忧参半。我不得不修改"运行"配置,使用mvn插件(见上文(,这部分似乎可以工作。
更新#2:我现在已经将我的IDE"运行配置"命令增强为mvn-compile javafx:run,它强制代码在运行之前重新编译(如果需要重新编译-maven很聪明(。
祝我好运——我会在继续的时候更新这篇文章。
我在尝试使用--add-modules
参数时遇到了类似的困难。
所以我创建了这个文件:
src/module-info.java
内容如下:
module MyProject{
requires javafx.controls;
}
您可以在此处找到完整的工作示例:https://carlfx.wordpress.com/2016/04/26/a-javafx-helloworld-using-java-9s-project-jigsaw-in-60-seconds/