IntelliJ не може розпізнати JavaFX 11 з OpenJDK 11


83

Я маю проблеми з тим, щоб IntellJ розпізнав пакети JavaFX. З новим проектом JavaFX, з OpenJDK 11, при спробі побудови проекту IntelliJ не може розпізнати пакети JavaFX.

Я імпортував openjfx:javafx-base-11з репозиторію Maven.

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

У когось є ідеї?

рис 1

рис 2

рис 3

Редагувати:

Помилка:

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


Ви можете спробувати з терміналу скомпілювати та запустити?
втоплений

Вам потрібно буде зажадати його модуль (и) у вашомуmodule-info.java
Jacob G.

Думаю, вам потрібен цей артефакт: mvnrepository.com/artifact/org.openjfx/javafx/11, базовий містить не все, що я здогадуюсь.
Jorn Vernee

@JornVernee, коли я намагаюся отримати повідомлення про помилку. Я редагував ОП разом з ним.
AlwaysNeedingHelp

1
Той, хто вам це сказав, швидше за все помилявся. Вам потрібно створити module-info.javaфайл у вихідній папці і явно вимагають хоч би якою модулів JavaFX , що ви використовуєте: requires javafx.controls;, requires javafx.graphics;і т.д.
Jacob G.

Відповіді:


135

Як згадувалось у коментарях, Початковий посібник - це місце, де слід розпочати роботу з 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 для створення свого проекту, виконайте такі дії:

  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.

Ось чому ваші банки 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
Хосе Переда

5
Якщо у когось виникають проблеми із шляхом до модуля, він повинен виглядати приблизно так у вікнах: --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 дякую! цитати насправді це зробили, ви повинні написати це як відповідь.
дерфект

2
Коли я будую дистрибутив для зразкового проекту для Gradle, а потім запускаю його, я отримую повідомлення про помилку: "Помилка: відсутні компоненти середовища виконання JavaFX, і вони потрібні для запуску цієї програми"
Трежказ,

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

    Ці два кроки вирішать усі ваші проблеми з JavaFX, я вас запевняю.

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


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. Чи можете ви вказати, де це зараз знаходиться?
Michael S.

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. Ви переходите до вихідного коду вашого основного класу, який розширює додаток, клацаєте правою кнопкою миші і намагаєтесь запустити його.
  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…:

модуль 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 Application і класи JavaFX Controller (замініть це на відповідне ім'я пакета для вашої програми). Це вказує на час виконання 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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.