IntelliJ не может распознать JavaFX 11 с OpenJDK 11

У меня проблемы с тем, чтобы IntellJ распознавал пакеты JavaFX. В новом проекте JavaFX, в OpenJDK 11, при попытке создать проект IntelliJ не может распознать пакеты JavaFX.

Я импортировал openjfx:javafx-base-11 из openjfx:javafx-base-11 Maven.

Я смотрел на другие вопросы, и решения, кажется, варьируются от проверки того, что байт-код находится на правильном уровне (у меня есть), и что язык проекта правильный (у меня есть).

У кого-нибудь есть идеи?

pic 1

pic 2

pic 3

Редактировать:

Ошибка:

enter image description here

Ответы

Ответ 1

Как упоминалось в комментариях, Руководство по началу работы - это то место, с которого можно начинать с Java 11 и JavaFX 11.

Ключ к работе, как вы делали до Java 11, заключается в том, чтобы понять, что:

  • JavaFX 11 больше не является частью JDK
  • Вы можете получить его в разных вариантах, либо в виде SDK, либо как регулярные зависимости (maven/gradle).
  • Вам нужно будет включить его в путь модуля вашего проекта, даже если ваш проект не является модульным.

Проект JavaFX

Если вы создаете обычный проект JavaFX по умолчанию в IntelliJ (без Maven или Gradle), я бы предложил вам загрузить SDK с здесь. Обратите внимание, что также существуют jmod, но для немодулярного проекта предпочтителен SDK.

Это простые шаги для запуска проекта по умолчанию:

  1. Создать проект JavaFX
  2. Установите JDK 11 (укажите на локальную версию Java 11)
  3. Добавьте JavaFX 11 SDK в качестве библиотеки. URL-адрес может быть что-то вроде /Users/<user>/Downloads/javafx-sdk-11/lib/. После этого вы заметите, что классы JavaFX теперь распознаются в редакторе.

JavaFX 11 Project

  1. Перед запуском проекта по умолчанию вам просто нужно добавить их в опции VM:

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

  2. Запуск

Maven

Если вы используете Maven для создания своего проекта, выполните следующие действия:

  1. Создайте проект Maven с архетипом JavaFX
  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>
    

После этого вы заметите, что классы JavaFX теперь распознаются в редакторе.

JavaFX 11 Maven project

Вы заметите, что Maven управляет необходимыми зависимостями для вас: он добавит javafx.base и javafx.graphics для javafx.controls, но самое главное, он добавит требуемый классификатор на основе вашей платформы. В моем случае, 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, как подробно описано здесь здесь.

EDIT

Упомянутое руководство по началу работы содержит обновленную документацию и примеры проектов для IntelliJ:

Ответ 2

Проблема в том, что Java FX больше не является частью JDK 11. Следующее решение работает с использованием IntelliJ (еще не пробовал с NetBeans):

  1. Добавьте глобальную библиотеку JavaFX в качестве зависимости:

    Настройки → Структура проекта → Модуль. В модуле перейдите на вкладку "Зависимости" и нажмите значок "+" добавления → Библиотека → Java-> выберите JavaFX из списка и нажмите "Добавить выбранное", затем "Применить настройки".

  2. Щелкните правой кнопкой мыши исходный файл (src) в вашем проекте JavaFX и создайте новый файл module-info.java. Внутри файла напишите следующий код:

           module YourProjectName    
           { requires javafx.fxml;
             requires javafx.controls;
             requires javafx.graphics;
              opens sample;}
    

Эти 2 шага решат все ваши проблемы с JavaFX, уверяю вас.

Ссылка: Там учебник You Tube, сделанный каналом Learn Programming, объяснит все детали выше всего за 5 минут. Я также рекомендую посмотреть его, чтобы решить вашу проблему: https://www.youtube.com/watch?v=WtOgoomDewo

Ответ 3

Ничто из вышеперечисленного не помогло мне. Я потратил слишком много времени на устранение других ошибок. Я обнаружил, что это самый простой и лучший способ.

Это работает для получения JavaFx на JDK 11, 12 & на OpenJdk12 тоже!

  • Видео показывает загрузку JavaFx Sdk
  • Как установить его в качестве глобальной библиотеки
  • Установите module-info.java (я предпочитаю нижний)

module thisIsTheNameOfYourProject {
    requires javafx.fxml;
    requires javafx.controls;
    requires javafx.graphics;
    opens sample;
}

Все это заняло у меня всего 5 минут !!!

Ответ 4

Проверьте локальный.m2, была ли загружена банка или нет в местоположении

Ответ 7

Быстрая сводка, вы можете сделать:

  1. Включите модули JavaFX через --module-path и --add-modules, как в ответе Хосе.

    ИЛИ

  2. Как только у вас есть библиотеки JavaFX, добавленные в ваш проект (вручную или через импорт maven/gradle), добавьте файл module-info.java, аналогичный указанному в этом ответе. (Обратите внимание, что это решение делает ваше приложение модульным, поэтому, если вы используете другие библиотеки, вам также потребуется добавить операторы, чтобы их модули содержались в файле module-info.java).


Этот ответ является дополнением к ответу Хосе.

Ситуация такая:

  1. Вы используете последнюю версию Java, например, 13.
  2. У вас есть приложение JavaFX в качестве проекта Maven.
  3. В вашем проекте Maven у вас настроен плагин JavaFX и настроены зависимости JavaFX в соответствии с ответом Jose.
  4. Вы переходите к исходному коду вашего основного класса, который расширяет Application, вы щелкаете по нему правой кнопкой мыши и пытаетесь запустить его.
  5. Вы получаете IllegalAccessError с "безымянным модулем" при попытке запустить приложение.

Выдержка для трассировки стека, генерирующей IllegalAccessError при попытке запустить приложение JavaFX из Intellij Idea:

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

Хорошо, теперь вы застряли и понятия не имеете, что происходит.

На самом деле произошло следующее:

  1. Maven успешно загрузил зависимости JavaFX для вашего приложения, поэтому вам не нужно отдельно загружать зависимости или устанавливать JavaFX SDK или дистрибутив модуля или что-то подобное.
  2. Idea успешно импортировала модули как зависимости в ваш проект, поэтому все компилируется нормально, все завершение кода и все работает нормально.

Так что, похоже, все должно быть в порядке. НО, когда вы запускаете свое приложение, код в модулях JavaFX дает сбой при попытке использовать отражение для создания экземпляров класса вашего приложения (при вызове запуска) и классов контроллера FXML (при загрузке FXML). Без некоторой помощи это использование отражения может в некоторых случаях потерпеть неудачу, порождая неясность IllegalAccessError. Это происходит из-за функции безопасности системы модулей Java, которая не позволяет коду из других модулей использовать отражение в ваших классах, если вы явно не разрешаете это (а для запуска приложений JavaFX и FXMLLoader оба требуют отражения в их текущей реализации, чтобы они могли функционировать правильно).

Вот где некоторые другие ответы на этот вопрос, которые ссылаются на module-info.java, входят в картину.

Итак, давайте пройдем ускоренный курс по модулям Java:

Ключевая часть такова:

4.9. Opens

Если нам нужно разрешить отражение частных типов, но мы не хотим, чтобы все нашего кода, мы можем использовать директиву opens, чтобы пакеты.

Но помните, это откроет пакет для всего мира, поэтому убедитесь, что это то, что вы хотите:

module my.module { opens com.my.package; }

Поэтому, возможно, вы не хотите открывать свою посылку для всего мира, тогда вы можете сделать следующее:

4.10. Opens … To

Хорошо, иногда рефлексия великолепна, но мы по-прежнему хотим обеспечить максимальную безопасность, которую мы можем получить от инкапсуляции. Мы можем выборочно открывать наши пакеты для предварительно утвержденного списка модулей, в этом случае, используя директиву 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;
}

Где, org.jewelsea.demo.javafx.springboot - это имя пакета, который содержит класс приложения JavaFX и классы контроллера JavaFX (замените его соответствующим именем пакета для вашего приложения). Это сообщает среде выполнения Java, что классы в javafx.graphics и javafx.fxml могут вызывать отражение в классах в вашем пакете org.jewelsea.demo.javafx.springboot. Как только это будет сделано, приложение скомпилировано и перезапущено, все будет работать нормально, и IllegalAccessError, сгенерированный JavaFX, использует отражение больше не будет.

Но что, если вы не хотите создавать файл module-info.java

Если вместо непосредственного запуска класса приложения вместо кнопки "Выполнить" на верхней панели инструментов среды IDE, вы вместо этого:

  1. Пошел к окну Maven на боковой панели IDE.
  2. Выберите цель для плагина javafx maven javafx.run.
  3. Щелкните по нему правой кнопкой мыши и выберите либо Run Maven Build, либо Debug....

Тогда приложение будет работать без файла module-info.java. Я полагаю, это потому, что плагин maven достаточно умен, чтобы динамически включать в себя какие-то настройки, которые позволяют отражать приложение в классах JavaFX даже без файла module-info.java, хотя я не знаю, как это сделать.

Чтобы передать эту настройку кнопке "Выполнить" на верхней панели инструментов, щелкните правой кнопкой мыши цель javafx.run Maven и выберите для цели параметр Create Run/Debug Configuration. Затем вы можете просто выбрать Run на верхней панели инструментов для выполнения цели Maven.