IntelliJ, OpenJDK 11 ile JavaFX 11'i tanıyamıyor


83

IntellJ'nin JavaFX paketlerini tanımasını sağlamakta sorun yaşıyorum. OpenJDK 11 ile yeni bir JavaFX projesiyle, projeyi oluşturmaya çalışırken IntelliJ JavaFX paketlerini tanıyamaz.

openjfx:javafx-base-11Maven deposundan ithal ettim .

Diğer sorulara baktım ve çözümler bayt kodunun doğru seviyede (benimki) ve proje dilinin doğru (benimki) olup olmadığını kontrol etmekten farklı görünüyor.

Herhangi bir fikri olan var mı?

resim 1

resim 2

resim 3

Düzenle:

Hata:

görüntü açıklamasını buraya girin


terminalden derlemeyi ve çalıştırmayı deneyebilir misin?
drowny

module-info.java
Jacob G.

Sanırım bu esere ihtiyacınız var: mvnrepository.com/artifact/org.openjfx/javafx/11 temelde tahmin ettiğim her şeyi içermiyor.
Jorn Vernee

@JornVernee, denediğimde bir hata alıyorum. OP'yi onunla düzenledim.
AlwaysNeedingHelp

1
Bunu size kim söylediyse muhtemelen yanılmıştır. Bir oluşturmanız gerekir module-info.java: Kaynak klasördeki dosya ve açık şekilde kullandığınız bu hangisi JavaFX modülü gerektirmeyen requires javafx.controls;, requires javafx.graphics;vb
Jacob G.

Yanıtlar:


134

Yorumlarda belirtildiği gibi, Başlangıç ​​Kılavuzu Java 11 ve JavaFX 11 ile başlayabileceğiniz yerdir.

Java 11'den önce yaptığınız gibi çalışmanın anahtarı şunu anlamaktır:

  • JavaFX 11 artık JDK'nın bir parçası değil
  • Bir SDK olarak veya normal bağımlılıklar (maven / gradle) olarak farklı tatlarda elde edebilirsiniz.
  • Projeniz modüler olmasa bile bunu projenizin modül yoluna eklemeniz gerekecektir.

JavaFX projesi

IntelliJ'de (Maven veya Gradle olmadan) normal bir JavaFX varsayılan projesi oluşturursanız, SDK'yı buradan indirmenizi öneririm . Jmod'lar da vardır, ancak modüler olmayan bir proje için SDK tercih edilir.

Varsayılan projeyi çalıştırmanın kolay adımları şunlardır:

  1. JavaFX projesi oluşturun
  2. JDK 11'i ayarlayın (yerel Java 11 sürümünüzü işaret edin)
  3. JavaFX 11 SDK'yı kitaplık olarak ekleyin. URL gibi bir şey olabilir /Users/<user>/Downloads/javafx-sdk-11/lib/. Bunu yaptığınızda, JavaFX sınıflarının artık düzenleyicide tanındığını fark edeceksiniz.

JavaFX 11 Projesi

  1. Varsayılan projeyi çalıştırmadan önce, bunları VM seçeneklerine eklemeniz yeterlidir:

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

  2. Çalıştırmak

Uzman

Projenizi oluşturmak için Maven kullanıyorsanız, şu adımları izleyin:

  1. JavaFX arketipi ile bir Maven projesi oluşturun
  2. JDK 11'i ayarlayın (yerel Java 11 sürümünüzü işaret edin)
  3. JavaFX 11 bağımlılıklarını ekleyin.

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

Bunu yaptığınızda, JavaFX sınıflarının artık düzenleyicide tanındığını fark edeceksiniz.

JavaFX 11 Maven projesi

Maven'in gerekli bağımlılıkları sizin için yönettiğini fark edeceksiniz: javafx.controls için javafx.base ve javafx.graphics'i ekleyecek, ancak en önemlisi, platformunuza bağlı olarak gerekli sınıflandırıcıyı ekleyecektir . Benim durumumda, Mac.

Senin kavanoz nedeni budur org.openjfx:javafx-controls:11olan boş sınıfları ve yerli uygulanmasını tümünü içerir üç olası sınıflandırıcılar (windows, linux ve mac platformlar), çünkü,.

Hala .m2 deponuza gitmek ve oradan bağımlılıkları manuel olarak almak istiyorsanız, doğru olanı seçtiğinizden emin olun (örneğin .m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11-mac.jar)

  1. Varsayılan maven eklentilerini buradakilerle değiştirin .

  2. Koş mvn compile javafx:runve çalışmalı.

Gradle projeleri için de benzer işler, burada ayrıntılı olarak açıklandığı gibi .

DÜZENLE

Bahsedilen Başlarken kılavuzu, IntelliJ için güncellenmiş belgeleri ve örnek projeleri içerir :


1
Yol, klasöre /Users/<user>/Downloads/javafx-sdk-11/lib/dikkat edin gibi bir şeydir lib. Bu, tüm javafx kavanozlarını içermelidir
José Pereda

5
Herhangi biri modül yolu ile ilgili sorunlar yaşıyorsa, Windows'ta şu şekilde görünmesi gerekir: --module-path = "C: \ Path \ To \ Your \ JavaFX \ lib" --add-modules = javafx.controls, javafx .fxml, javafx.base, javafx.media, javafx.graphics, javafx.swing, javafx.web "=" ve ayrıca etrafındaki alıntılara dikkat edin. Bu benim için işe yaradı, diğer yaklaşımlar işe yaramadı. Ayrıca, -jar YourJar.jar parametresinin, modül yolu ve modül ekleme seçeneklerinden SONRA gelmesi gerektiğini unutmayın.
Jalau

4
Merhaba @ JoséPereda. Bir süredir bu kılavuzla uğraşıyorum, ancak yazdığınız şeyi tam olarak yapmış olsam bile IntelliJ'in kodumu çalıştırmasını gerçekten sağlayamam. Hala "Hata: java: modül bulunamadı: javafx.fxml" ve benzerlerini alıyorum. Bu sorunu çözmeme yardımcı olacak özel bir sohbet etme şansınız var mı? Teşekkür ederim.
Davide3i

1
@jalau teşekkür ederim! alıntılar gerçekten yaptı, bunu bir cevap olarak yazmalısınız.
derfect

2
Gradle için örnek proje için dağıtım oluşturup sonra çalıştırdığımda şu hata mesajını alıyorum: "Hata: JavaFX çalışma zamanı bileşenleri eksik ve bu uygulamayı çalıştırmak için gerekli"
Trejkaz

10

JavaFX'in artık JDK 11'in bir parçası olmaması sorunu. Aşağıdaki çözüm IntelliJ kullanarak çalışıyor (NetBeans ile denemedim):

  1. JavaFX Global Library'yi bağımlılık olarak ekleyin:

    Ayarlar -> Proje Yapısı -> Modül. Modülde Bağımlılıklar sekmesine gidin ve "+" işaretini tıklayın -> Kitaplık -> Java-> listeden JavaFX'i seçin ve Seçileni Ekle'yi ve ardından Ayarları uygulayın.

  2. JavaFX projenizde kaynak dosyaya (src) sağ tıklayın ve yeni bir module-info.java dosyası oluşturun . Dosyanın içine aşağıdaki kodu yazın:

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

    Bu 2 adım JavaFX ile ilgili tüm sorunlarınızı çözecektir, sizi temin ederim.

Referans: Programlama Öğrenme kanalı tarafından hazırlanan bir You Tube öğreticisi var, yukarıdaki tüm ayrıntıları sadece 5 dakika içinde açıklayacak. Ayrıca sorununuzu çözmek için izlemenizi de tavsiye ederim: https://www.youtube.com/watch?v=WtOgoomDewo


8

Yukarıdakilerin hiçbiri benim için işe yaramadı. Ortaya çıkan diğer hataları temizlemek için çok fazla zaman harcadım. Bunu en kolay ve en iyi yol olarak buldum.

Bu, JavaFx'i Jdk 11, 12 ve OpenJdk12'de almak için de işe yarar!

  • Video size JavaFx Sdk indirmesini gösterir
  • Global Kitaplık olarak nasıl ayarlanır
  • Module-info.java'yı ayarlayın (alt olanı tercih ederim)

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

Her şey bana sadece 5 dakika sürdü !!!


Küresel bir kitaplık olarak ayarlayın 2019.3. Şimdi nerede olduğunu gösterebilir misin?
Michael S.

5

Hızlı özet, aşağıdakilerden birini yapabilirsiniz:

  1. José'nin cevabına JavaFX modüllerini --module-pathve --add-modulesbenzerlerini ekleyin .

    VEYA

  2. Projenize JavaFX kitaplıkları ekledikten sonra (manuel olarak veya maven / gradle içe aktarma yoluyla), module-info.javadosyayı bu yanıtta belirtilene benzer şekilde ekleyin . (Bu çözümün uygulamanızı modüler hale getirdiğini unutmayın, bu nedenle diğer kitaplıkları kullanırsanız, bunların modüllerinin module-info.javadosya içinde olmasını gerektirecek ifadeler de eklemeniz gerekir ).


Bu cevap Jose'nin cevabına bir tamamlayıcıdır.

Durum şudur:

  1. Yeni bir Java sürümünü kullanıyorsunuz, örn. 13.
  2. Maven projesi olarak bir JavaFX uygulamanız var.
  3. Maven projenizde, JavaFX eklentisi yapılandırılmış ve Jose'nin cevabına göre JavaFX bağımlılıkları ayarlanmıştır.
  4. Uygulamayı genişleten ana sınıfınızın kaynak koduna gidersiniz, üzerine sağ tıklayıp çalıştırmayı denersiniz.
  5. Sen almak bir IllegalAccessErroruygulamayı başlatmak için çalışırken bir "isimsiz modülü" içeren.

IllegalAccessErrorIntellij Idea'dan bir JavaFX uygulamasını çalıştırmaya çalışırken bir yığın izlemesi için alıntı :

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

Tamam, şimdi biraz sıkışmış durumdasın ve neler olduğu hakkında hiçbir fikrin yok.

Gerçekte olan şudur:

  1. Maven, uygulamanız için JavaFX bağımlılıklarını başarıyla indirdi, bu nedenle bağımlılıkları ayrı ayrı indirmenize veya bir JavaFX SDK veya modül dağıtımı veya benzeri bir şey kurmanıza gerek kalmaz.
  2. Idea, modülleri projenize bağımlılıklar olarak başarıyla içe aktardı, böylece her şey tamam derlenir ve tüm kod tamamlanır ve her şey yolunda gider.

Görünüşe göre her şey yoluna girmeli. ANCAK, uygulamanızı çalıştırdığınızda, JavaFX modüllerindeki kod, uygulama sınıfınızın (başlatmayı çağırdığınızda) ve FXML denetleyici sınıflarınızın (FXML'yi yüklediğinizde) örneklerini somutlaştırmak için yansımayı kullanmaya çalışırken başarısız oluyor. Biraz yardım olmadan, bu yansıma kullanımı bazı durumlarda başarısız olabilir ve belirsizlik yaratabilir IllegalAccessError. Bunun nedeni, siz açıkça izin vermediğiniz sürece diğer modüllerden gelen kodun sınıflarınız üzerinde yansıma kullanmasına izin vermeyen bir Java modülü sistem güvenlik özelliğidir (ve JavaFX uygulama başlatıcısı ve FXMLLoader, çalışabilmeleri için her ikisi de mevcut uygulamalarında yansıma gerektirir doğru şekilde).

Referans olan bu soruya verilen diğer cevapların bir kısmı burada module-info.javadevreye giriyor.

Öyleyse Java modüllerinde hızlandırılmış bir kurs alalım:

Anahtar kısım şudur:

4.9. Açık

Özel türlerin yansımasına izin vermemiz gerekiyorsa, ancak tüm kodumuzun açığa çıkmasını istemiyorsak, belirli paketleri açığa çıkarmak için opens yönergesini kullanabiliriz.

Ancak unutmayın, bu paketi tüm dünyaya açacaktır, bu yüzden istediğiniz şeyin bu olduğundan emin olun:

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

Belki de paketinizi tüm dünyaya açmak istemezsiniz, o zaman şunları yapabilirsiniz:

4.10. Açılır…

Tamam, bu yüzden bazen yansıtma harika, ancak yine de kapsüllemeden elde edebileceğimiz kadar güvenlik istiyoruz. Paketlerimizi önceden onaylanmış bir modül listesine seçerek açabiliriz, bu durumda, open… yönergesini kullanarak:

modül my.module {com.my.package'i moduleOne, moduleTwo, vb. olarak açar; }

Böylece, şuna benzeyen bir src / main / java / module-info.java sınıfı oluşturursunuz:

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

Nerede, org.jewelsea.demo.javafx.springbootJavaFX Uygulama sınıfı ve JavaFX Denetleyici sınıfları (uygulamanız için uygun paket adıyla bu değiştirin) içeren paketin adıdır. Bu sınıflar için ok olduğunu Java çalışma zamanını anlatır javafx.graphicsve javafx.fxmlsizin sınıflar üzerinde çağırmak yansıması org.jewelsea.demo.javafx.springbootpaketin. Bu yapıldıktan ve uygulama derlendikten ve yeniden çalıştırıldıktan sonra işler düzgün çalışacak ve IllegalAccessErrorJavaFX'in yansıma kullanımı ile oluşturulanlar artık gerçekleşmeyecek.

Peki ya bir module-info.java dosyası oluşturmak istemezseniz

Uygulama sınıfınızı doğrudan çalıştırmak için IDE'nin üst araç çubuğundaki Çalıştır düğmesini kullanmak yerine, bunun yerine:

  1. IDE'nin yan tarafındaki Maven penceresine gittim.
  2. Javafx maven eklenti hedefini seçin javafx.run.
  3. Buna sağ tıklayın ve ya Run Maven Buildda seçimini yapın Debug....

Ardından uygulama module-info.javadosya olmadan çalışacaktır . Sanırım bunun nedeni, maven eklentisinin, uygulamanın bir module-info.javadosya olmadan bile JavaFX sınıfları tarafından yansıtılmasına izin veren bazı ayarları dinamik olarak içerecek kadar akıllı olmasıdır , ancak bunun nasıl yapıldığını bilmiyorum.

Bu ayarın üst araç çubuğundaki Çalıştır düğmesine aktarılmasını sağlamak için, javafx.runMaven hedefine sağ tıklayın ve hedef için seçeneğini seçin Create Run/Debug Configuration. Ardından, Maven hedefini yürütmek için üst araç çubuğundan Çalıştır'ı seçebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.