IntelliJ无法使用OpenJDK 11识别JavaFX 11

Alw*_*elp 53 java javafx intellij-idea java-11 javafx-11

我无法让IntellJ识别JavaFX包.使用OpenJDK 11的新JavaFX项目,在尝试构建项目时,IntelliJ无法识别JavaFX包.

我是openjfx:javafx-base-11从Maven回购中导入的.

我已经查看了其他问题,解决方案似乎包括检查字节码是否处于正确的级别(我的是),以及项目语言是否正确(我的是).

有人有主意吗?

pic 1

pic 2

pic 3

编辑:

错误:

在此输入图像描述

Jos*_*eda 100

正如评论中所提到的,Starting Guide是从Java 11和JavaFX 11开始的地方.

像在Java 11之前一样工作的关键是要理解:

  • JavaFX 11不再是JDK的一部分
  • 您可以将它作为SDK或常规依赖项(maven/gradle)以不同的方式获得.
  • 即使项目不是模块化的,您也需要将它包含在项目的模块路径中.

JavaFX项目

如果您在IntelliJ中创建常规JavaFX默认项目(没有Maven或Gradle),我建议您从此处下载SDK .请注意,还有jmods,但对于非模块化项目,SDK是首选.

这些是运行默认项目的简单步骤:

  1. 创建一个JavaFX项目
  2. 设置JDK 11(指向本地Java 11版本)
  3. 将JavaFX 11 SDK添加为库.URL可能是这样的/Users/<user>/Downloads/javafx-sdk-11/lib/.执行此操作后,您会注意到JavaFX类现在已在编辑器中识别.

JavaFX 11项目

  1. 在运行默认项目之前,您只需将这些添加到VM选项:

    --module-path /Users/<user>/Downloads/javafx-sdk-11/lib --add-modules=javafx.controls,javafx.fxml

Maven的

如果您使用Maven构建项目,请按照下列步骤操作:

  1. 使用JavaFX原型创建Maven项目
  2. 设置JDK 11(指向本地Java 11版本)
  3. 添加JavaFX 11依赖项.

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>11</version>
        </dependency>
    </dependencies>
    
    Run Code Online (Sandbox Code Playgroud)

执行此操作后,您会注意到JavaFX类现在已在编辑器中识别.

JavaFX 11 Maven项目

您会注意到Maven为您管理所需的依赖项:它将为javafx.controls添加javafx.base和javafx.graphics,但最重要的是,它将根据您的平台添加所需的分类器.就我而言,Mac.

这就是为什么你的jar org.openjfx:javafx-controls:11空的,因为有三个可能的分类器(windows,linux和mac平台),它们包含所有类和本机实现.

如果您仍想转到.m2仓库并手动从那里获取依赖项,请确保选择正确的(例如.m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11-mac.jar)

  1. 将默认maven插件替换为来自此处的插件.

  2. 运行mvn compile javafx:run,它应该工作.

类似的工作也适用于Gradle项目,详见此处.

编辑

上面提到的入门指南包含IntelliJ的更新文档和示例项目:

  • 如果有人遇到模块路径问题,它需要在Windows上看起来像这样: - module-path ="C:\ Path\To\Your\JavaFX\lib"--add-modules = javafx.controls,javafx .fxml,javafx.base,javafx.media,javafx.graphics,javafx.swing,javafx.web注意"="以及它周围的引号.这对我有用,而任何其他方法都没有.此外,请记住-jar YourJar.jar参数需要在模块路径和add-modules选项之后. (5认同)
  • 嗨@JoséPereda。一段时间以来,我一直在努力阅读本指南,但是即使我完全按照您的编写来做,我也无法真正使IntelliJ运行我的代码。我仍然收到“错误:java:找不到模块:javafx.fxml”,依此类推。有机会进行私人聊天以帮助我解决此问题吗?谢谢。 (2认同)
  • 当我为Gradle的示例项目构建发行版并运行它时,出现错误消息:“错误:缺少JavaFX运行时组件,并且是运行此应用程序所必需的” (2认同)

jew*_*sea 6

快速总结,您可以执行以下任一操作:

  1. 在 José 的回答中包含 JavaFX 模块 via--module-path--add-moduleslike。

或者

  1. 一旦您将 JavaFX 库添加到您的项目中(手动或通过 maven/gradle 导入),请添加module-info.java与此答案中指定的文件类似的文件。(请注意,此解决方案使您的应用程序模块化,因此如果您使用其他库,您还需要添加语句以在module-info.java文件中要求它们的模块)。

这个答案是对何塞答案的补充。

情况是这样的:

  1. 您使用的是最新的 Java 版本,例如 13。
  2. 您有一个 JavaFX 应用程序作为 Maven 项目。
  3. 在您的 Maven 项目中,您已按照 Jose 的回答配置了 JavaFX 插件并设置了 JavaFX 依赖项。
  4. 您转到扩展 Application 的主类的源代码,右键单击它并尝试运行它。
  5. IllegalAccessError尝试启动应用程序时,您会遇到一个“未命名的模块”。

IllegalAccessError尝试从 Intellij Idea 运行 JavaFX 应用程序时生成的堆栈跟踪摘录:

Exception in Application start method
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:567)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at javafx.graphics/com.sun.javafx.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:567)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
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:830)
Caused by: java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module @0x45069d0e) cannot access class com.sun.javafx.util.Utils (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.util to unnamed module @0x45069d0e
    at com.sun.javafx.fxml.FXMLLoaderHelper.<clinit>(FXMLLoaderHelper.java:38)
    at javafx.fxml.FXMLLoader.<clinit>(FXMLLoader.java:2056)
    at org.jewelsea.demo.javafx.springboot.Main.start(Main.java:13)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    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)
Exception running application org.jewelsea.demo.javafx.springboot.Main
Run Code Online (Sandbox Code Playgroud)

好的,现在你有点卡住了,不知道发生了什么。

实际发生的事情是这样的:

  1. Maven 已成功为您的应用程序下载了 JavaFX 依赖项,因此您无需单独下载依赖项或安装 JavaFX SDK 或模块分发或类似的东西。
  2. Idea 已成功将模块作为依赖项导入到您的项目中,因此一切编译正常,所有代码完成,一切正常。

所以看起来一切都应该没问题。但是,当您运行应用程序时,JavaFX 模块中的代码在尝试使用反射来实例化应用程序类(调用启动时)和 FXML 控制器类(加载 FXML 时)的实例时失败。如果没有一些帮助,这种反射的使用在某些情况下可能会失败,产生晦涩的IllegalAccessError. 这是由于 Java 模块系统安全功能不允许来自其他模块的代码在您的类上使用反射,除非您明确允许它(JavaFX 应用程序启动器和 FXMLLoader 都需要在其当前实现中进行反射才能使其正常工作)正确)。

这是该问题的其他一些答案(参考module-info.java)出现的地方。

因此,让我们参加 Java 模块速成课程:

关键部分是这样的:

4.9. 打开

如果我们需要允许反射私有类型,但又不想暴露所有代码,我们可以使用 opens 指令来暴露特定的包。

但请记住,这将向全世界打开包裹,因此请确保这是您想要的:

module my.module { opens com.my.package; }
Run Code Online (Sandbox Code Playgroud)

所以,也许你不想向全世界开放你的包裹,那么你可以这样做:

4.10. 打开……到

好的,所以反射有时很棒,但我们仍然希望从封装中获得尽可能多的安全性。我们可以有选择地将我们的包打开到预先批准的模块列表中,在这种情况下,使用 opens...to 指令:

module my.module { 打开 com.my.package 到 moduleOne、moduleTwo 等;}

所以,你最终创建了一个 src/main/java/module-info.java 类,它看起来像这样:

module org.jewelsea.demo.javafx.springboot {
    requires javafx.fxml;
    requires javafx.controls;
    requires javafx.graphics;
    opens org.jewelsea.demo.javafx.springboot to javafx.graphics,javafx.fxml;
}
Run Code Online (Sandbox Code Playgroud)

org.jewelsea.demo.javafx.springboot包含 JavaFX 应用程序类和 JavaFX 控制器类的包的名称在哪里(将其替换为应用程序的适当包名称)。这告诉Java运行时,它是类的OK javafx.graphics,并javafx.fxml就在你的类调用反射org.jewelsea.demo.javafx.springboot包。完成此操作后,应用程序被编译并重新运行,一切都会正常运行IllegalAccessError,JavaFX 使用反射生成的问题将不再发生。

但是如果你不想创建一个 module-info.java 文件怎么办

如果不是使用 IDE 顶部工具栏中的运行按钮直接运行应用程序类,而是:

  1. 转到IDE一侧的Maven窗口。
  2. 选择 JavaFX maven 插件目标javafx.run
  3. 右键单击它并选择Run Maven BuildDebug...

然后应用程序将在没有module-info.java文件的情况下运行。我想这是因为 maven 插件足够智能,可以动态包含某种设置,即使没有module-info.java文件,JavaFX 类也可以反映应用程序,尽管我不知道这是如何实现的。

要将该设置传输到顶部工具栏中的“运行”按钮,请右键单击javafx.runMaven 目标并Create Run/Debug Configuration为目标选择选项。然后您可以从顶部工具栏中选择 Run 来执行 Maven 目标。


Cod*_*992 5

Java FX不再是JDK 11的问题。以下解决方案使用IntelliJ进行工作(尚未在NetBeans上进行过尝试):

  1. 添加JavaFX全局库作为依赖项:

    设置->项目结构->模块。在模块中,转到“依赖关系”选项卡,然后单击添加“ +”号->库-> Java->从列表中选择JavaFX,然后单击“添加选定项”,然后单击“应用设置”。

  2. 右键单击JavaFX项目中的源文件(src),然后创建一个新的 module-info.java文件。在文件内部编写以下代码:

           module YourProjectName    
           { requires javafx.fxml;
             requires javafx.controls;
             requires javafx.graphics;
              opens sample;}
    
    Run Code Online (Sandbox Code Playgroud)

我向您保证,这两个步骤将解决JavaFX的所有问题。

参考:学习编程频道制作了一个You Tube教程,将在5分钟内解释以上所有详细信息。我还建议您观看它以解决您的问题:https : //www.youtube.com/watch?v=WtOgoomDewo


Yo *_*pps 5

以上都不对我有用。我花了太多时间来清除出现的其他错误。我发现这是最简单,最好的方法。

这也适用于在Jdk 11、12和OpenJdk12上获取JavaFx!

  • 该视频向您展示了JavaFx Sdk下载
  • 如何将其设置为全局库
  • 设置module-info.java(我更喜欢底部的模块)

module thisIsTheNameOfYourProject {
    requires javafx.fxml;
    requires javafx.controls;
    requires javafx.graphics;
    opens sample;
}
Run Code Online (Sandbox Code Playgroud)

整个过程只花了我5分钟!