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

83

Мне не удается заставить IntellJ распознавать пакеты JavaFX. В новом проекте JavaFX с OpenJDK 11 при попытке создать проект IntelliJ не может распознать пакеты JavaFX.

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

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

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

рис 1

рис 2

рис 3

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

Ошибка:

введите описание изображения здесь

AlwaysNeedingHelp
источник
можно попробовать с терминала скомпилировать и запустить?
drowny
Вам потребуется его модуль (-ы) в вашемmodule-info.java
Джейкоб Г.
Я думаю, вам нужен этот артефакт: mvnrepository.com/artifact/org.openjfx/javafx/11 базовый не содержит всего, что я думаю.
Йорн Верни
@JornVernee, когда я пытаюсь это сделать, я получаю сообщение об ошибке. Я редактировал OP с ним.
AlwaysNeedingHelp
1
Кто бы ни сказал вам это, скорее всего, ошибался. Вам нужно создать module-info.javaфайл в исходной папке и явно требуют какой бы ни модулей JavaFX , что вы используете: requires javafx.controls;, requires javafx.graphics;и т.д.
Jacob G.

Ответы:

134

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

Ключ к тому, чтобы работать так, как вы работали до Java 11, - это понимать, что:

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

Проект JavaFX

Если вы создаете обычный проект JavaFX по умолчанию в IntelliJ (без 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. Прежде чем запускать проект по умолчанию, вам просто нужно добавить их в параметры виртуальной машины:

    --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

Вы заметите, что 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, как подробно описано здесь .

РЕДАКТИРОВАТЬ

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

Хосе Переда
источник
1
Путь что-то вроде /Users/<user>/Downloads/javafx-sdk-11/lib/, обратите внимание на libпапку. Он должен содержать все javafx jar-файлы
Хосе Переда
5
Если у кого-то возникают проблемы с путем к модулю, он должен выглядеть примерно так в 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.
Jalau
4
Привет, @ JoséPereda. Я долго боролся с этим руководством, но я не могу заставить IntelliJ запускать мой код, даже если я сделал именно то, что вы написали. Я все еще получаю сообщение «Ошибка: java: модуль не найден: javafx.fxml» и так далее. Есть ли шанс поговорить в приватном чате, чтобы помочь мне разобраться с этой проблемой? Спасибо.
Davide3i
1
@jalau, спасибо! цитаты действительно сделали это, вы должны написать это как ответ.
derfect
2
Когда я создаю дистрибутив для образца проекта для Gradle и затем запускаю его, я получаю сообщение об ошибке: «Ошибка: компоненты времени выполнения JavaFX отсутствуют и необходимы для запуска этого приложения»
Trejkaz
10

Проблема в том, что JavaFX больше не является частью 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, уверяю вас.

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

Кодер992
источник
8

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

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

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

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

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

Йо, приложения
источник
Установите его как глобальную библиотеку, перемещенную в 2019.3. Вы можете указать, где это сейчас находится?
Майкл С.
5

Краткое резюме, вы можете сделать либо:

  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 в соответствии с ответом Хосе.
  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 для предоставления определенных пакетов.

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

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

Итак, возможно, вы не хотите открывать свой пакет для всего мира, тогда вы можете сделать:

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;
}

Где, 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для цели. Затем вы можете просто выбрать «Выполнить» на верхней панели инструментов, чтобы выполнить цель Maven.

Jewelsea
источник