Mam problem ze zrozumieniem przez IntellJ pakietów JavaFX. Z nowym projektem JavaFX, z OpenJDK 11, podczas próby zbudowania projektu IntelliJ nie może rozpoznać pakietów JavaFX.
Zaimportowałem openjfx:javafx-base-11
z repozytorium Maven.
Przyjrzałem się innym pytaniom i wydaje się, że rozwiązania wahają się od sprawdzenia, czy kod bajtowy jest na właściwym poziomie (mój jest) i czy język projektu jest poprawny (mój jest).
Czy ktoś ma jakieś pomysły?
Edytować:
Błąd:
module-info.java
module-info.java
plik w folderze źródłowym wyraźnie wymagają Niezależnie od modułów JavaFX, że jesteś przy użyciu:requires javafx.controls;
,requires javafx.graphics;
, itd.Odpowiedzi:
Jak wspomniano w komentarzach, przewodnik startowy to miejsce, w którym można rozpocząć pracę z Javą 11 i JavaFX 11.
Kluczem do pracy tak, jak robiłeś to przed Java 11, jest zrozumienie, że:
Projekt JavaFX
Jeśli tworzysz zwykły domyślny projekt JavaFX w IntelliJ (bez Maven lub Gradle), sugeruję pobranie SDK stąd . Zauważ, że istnieją również jmody, ale w przypadku projektów niemodułowych preferowany jest pakiet SDK.
Oto proste kroki, aby uruchomić domyślny projekt:
/Users/<user>/Downloads/javafx-sdk-11/lib/
. Gdy to zrobisz, zauważysz, że klasy JavaFX są teraz rozpoznawane w edytorze.Przed uruchomieniem domyślnego projektu wystarczy dodać je do opcji maszyny wirtualnej:
--module-path /Users/<user>/Downloads/javafx-sdk-11/lib --add-modules=javafx.controls,javafx.fxml
Biegać
Maven
Jeśli używasz Maven do tworzenia projektu, wykonaj następujące kroki:
Dodaj zależności 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>
Gdy to zrobisz, zauważysz, że klasy JavaFX są teraz rozpoznawane w edytorze.
Zauważysz, że Maven zarządza wymaganymi zależnościami za Ciebie: doda javafx.base i javafx.graphics dla javafx.controls, ale co najważniejsze, doda wymagany klasyfikator oparty na Twojej platformie. W moim przypadku Mac.
Dlatego twoje słoiki
org.openjfx:javafx-controls:11
są puste , ponieważ istnieją trzy możliwe klasyfikatory (platformy Windows, Linux i Mac), które zawierają wszystkie klasy i natywną implementację.Jeśli nadal chcesz przejść do repozytorium .m2 i pobrać z niego zależności ręcznie, upewnij się, że wybrałeś właściwy (na przykład
.m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11-mac.jar
)Zastąp domyślne wtyczki Maven tymi z tego miejsca .
Uruchom
mvn compile javafx:run
i powinno działać.Podobnie działa również w przypadku projektów Gradle, jak szczegółowo wyjaśniono tutaj .
EDYTOWAĆ
Wspomniany przewodnik Pierwsze kroki zawiera zaktualizowaną dokumentację i przykładowe projekty dla IntelliJ:
JavaFX 11 bez Maven / Gradle, zobacz niemodułowe przykładowe lub modułowe przykładowe projekty.
JavaFX 11 z Maven, zobacz niemodułowe przykładowe lub modułowe przykładowe projekty.
JavaFX 11 z Gradle, zobacz niemodularne przykładowe lub modułowe przykładowe projekty.
źródło
/Users/<user>/Downloads/javafx-sdk-11/lib/
, zwróć uwagę nalib
folder. To powinno zawierać wszystkie słoiki javafxProblem polegający na tym, że JavaFX nie jest już częścią JDK 11. Następujące rozwiązanie działa przy użyciu IntelliJ (nie próbowałem go z NetBeans):
Dodaj bibliotekę globalną JavaFX jako zależność:
Ustawienia -> Struktura projektu -> Moduł. W module przejdź do zakładki Zależności i kliknij znak „+” -> Biblioteka -> Java-> wybierz z listy JavaFX i kliknij Dodaj wybrane, a następnie Zastosuj ustawienia.
Kliknij prawym przyciskiem myszy plik źródłowy (src) w projekcie JavaFX i utwórz nowy plik module-info.java . Wewnątrz pliku napisz następujący kod:
module YourProjectName { requires javafx.fxml; requires javafx.controls; requires javafx.graphics; opens sample; }
Zapewniam, że te 2 kroki rozwiążą wszystkie problemy z JavaFX.
Odniesienie: Istnieje samouczek You Tube przygotowany przez kanał Learn Programming, który wyjaśni wszystkie powyższe szczegóły w zaledwie 5 minut. Polecam również obejrzenie go w celu rozwiązania problemu: https://www.youtube.com/watch?v=WtOgoomDewo
źródło
Żadne z powyższych nie działało dla mnie. Spędziłem zbyt dużo czasu na usuwaniu innych błędów, które się pojawiły. Uważam, że jest to najłatwiejszy i najlepszy sposób.
Działa to również w przypadku uzyskiwania JavaFx na Jdk 11, 12 i OpenJdk12!
module thisIsTheNameOfYourProject { requires javafx.fxml; requires javafx.controls; requires javafx.graphics; opens sample; }
Całość zajęła mi tylko 5 min !!!
źródło
Szybkie podsumowanie, możesz:
Dołącz moduły JavaFX za pośrednictwem
--module-path
i--add-modules
jak w odpowiedzi José.LUB
Po dodaniu bibliotek JavaFX do projektu (ręcznie lub za pomocą importu maven / gradle) dodaj
module-info.java
plik podobny do podanego w tej odpowiedzi. (Zwróć uwagę, że to rozwiązanie sprawia, że Twoja aplikacja jest modułowa, więc jeśli używasz innych bibliotek, będziesz musiał również dodać instrukcje, aby wymagać ich modułów wmodule-info.java
pliku).Ta odpowiedź jest uzupełnieniem odpowiedzi Jose.
Sytuacja jest następująca:
IllegalAccessError
obejmujące moduł „nienazwany” podczas próby uruchomienia aplikacji.Fragment śledzenia stosu generującego plik
IllegalAccessError
podczas próby uruchomienia aplikacji JavaFX z 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
OK, teraz utknęłaś i nie masz pojęcia, co się dzieje.
Co się właściwie wydarzyło, to:
Więc wydaje się, że wszystko powinno być w porządku. ALE, gdy uruchamiasz aplikację, kod w modułach JavaFX kończy się niepowodzeniem podczas próby użycia odbicia w celu utworzenia instancji Twojej klasy aplikacji (podczas wywoływania uruchomienia) i klas kontrolera FXML (podczas ładowania FXML). Bez pewnej pomocy takie wykorzystanie refleksji może w niektórych przypadkach zawieść, generując niejasność
IllegalAccessError
. Wynika to z funkcji zabezpieczeń systemu modułu Java, która nie pozwala kodowi z innych modułów na używanie odbicia na twoich klasach, chyba że wyraźnie na to zezwolisz (a program uruchamiający aplikacje JavaFX i FXMLLoader wymagają odzwierciedlenia w ich bieżącej implementacji, aby mogły działać prawidłowo).W tym miejscu
module-info.java
pojawiają się niektóre inne odpowiedzi na to pytanie, które zawierają odniesienie .Zróbmy więc szybki kurs dotyczący modułów Java:
Kluczowa część jest taka:
Więc być może nie chcesz otwierać swojego pakietu na cały świat, możesz zrobić:
W rezultacie tworzysz klasę src / main / java / module-info.java, która wygląda następująco:
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; }
Gdzie
org.jewelsea.demo.javafx.springboot
jest nazwą pakietu zawierającego klasę aplikacji JavaFX i klasy kontrolera JavaFX (zastąp ją odpowiednią nazwą pakietu dla aplikacji). To informuje środowisko wykonawcze Java, że jest OK dla klas wjavafx.graphics
ijavafx.fxml
wywołać refleksję na temat klas worg.jewelsea.demo.javafx.springboot
pakiecie . Gdy to zrobisz, a aplikacja zostanie skompilowana i ponownie uruchomiona, wszystko będzie działać dobrze, aIllegalAccessError
wygenerowane przez JavaFX odbicie nie będzie już występować.Ale co, jeśli nie chcesz tworzyć pliku module-info.java
Jeśli zamiast używać przycisku Uruchom na górnym pasku narzędzi IDE do bezpośredniego uruchamiania klasy aplikacji, zamiast tego:
javafx.run
.Run Maven Build
alboDebug...
.Wtedy aplikacja będzie działać bez
module-info.java
pliku. Wydaje mi się, że dzieje się tak dlatego, że wtyczka maven jest wystarczająco inteligentna, aby dynamicznie włączać pewne ustawienia, które pozwalają na odzwierciedlenie aplikacji przez klasy JavaFX nawet bezmodule-info.java
pliku, chociaż nie wiem, jak to się dzieje.Aby przenieść to ustawienie do przycisku Uruchom na górnym pasku narzędzi, kliknij prawym przyciskiem myszy
javafx.run
cel Mavena i wybierz opcjęCreate Run/Debug Configuration
dla celu. Następnie możesz po prostu wybrać Uruchom z górnego paska narzędzi, aby wykonać cel Mavena.źródło