javafx 8-Kompatibilitätsprobleme – Statische FXML-Felder

Lesezeit: 5 Minuten

javafx 8 Kompatibilitatsprobleme Statische FXML Felder
Christopher_Daniel

Ich habe eine Javafx-Anwendung entworfen, die in jdk 7 einwandfrei funktioniert. Wenn ich versuche, sie in Java 8 auszuführen, erhalte ich die folgenden Ausnahmen:

javafx.fxml.LoadException: 
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2617)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2595)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3230)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3191)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3164)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3140)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3132)


Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: Root cannot be null
    at javafx.scene.Scene.<init>(Scene.java:364)
    at javafx.scene.Scene.<init>(Scene.java:232)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:204)
    at javafx.concurrent.EventHelper.fireEvent(EventHelper.java:219)
    at javafx.concurrent.Task.fireEvent(Task.java:1357)
    at javafx.concurrent.Task.setState(Task.java:720)
    at javafx.concurrent.Task$TaskCallable$2.run(Task.java:1438)
    at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:301)
    at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:298)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl$6.run(PlatformImpl.java:298)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
    at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
    at java.lang.Thread.run(Thread.java:744)

Ich fand heraus, dass der Grund dafür in der initialize-Methode der Controller-Klasse liegt. Ich kann die eingebauten Methoden in keiner statischen Komponente verwenden. (Zum Beispiel: staticMyTextField.setText() verursacht das Problem in Java 8, aber nicht in Java 7). In den Javafx-Anleitungen kann ich diesbezüglich nichts Dokumentiertes finden. Kann jemand bitte einige Ideen dazu geben, warum dies ein Problem in Java 8 verursacht? Und teilen Sie auch diesbezügliche Dokumente, falls vorhanden.

  • können Sie ein Codebeispiel bereitstellen?

    – Sergej Grinew

    16. April 2014 um 10:40 Uhr

  • Bitte beziehen Sie sich auf diesen Link. Dies funktioniert in JDK 7, aber nicht in jdk 8. stackoverflow.com/questions/8434787/… helfen Sie bitte?

    – Christopher_Daniel

    17. April 2014 um 10:41 Uhr

1646647030 474 javafx 8 Kompatibilitatsprobleme Statische FXML Felder
James_D

Es hört sich so an, als würdest du versuchen, a zu injizieren TextField in ein statisches Feld. Etwas wie

@FXML
private static TextField myTextField ;

Dies funktionierte anscheinend in JavaFX 2.2. Es funktioniert nicht in JavaFX 8. Da keine offizielle Dokumentation diese Verwendung jemals unterstützt hat, verstößt es nicht wirklich gegen die Abwärtskompatibilität, obwohl fairerweise die Dokumentation genau darüber informiert, was die FXMLLoader tut ist ziemlich bedauerlich.

Es macht nicht wirklich viel Sinn zu machen @FXML-injizierte Felder statisch. Wenn Sie eine FXML-Datei laden, werden neue Objekte für jedes der Elemente in der FXML-Datei erstellt. Jedem Aufruf von wird eine neue Controllerinstanz zugeordnet FXMLLoader.load(...) und die Felder in diesem Controller Beispiel werden mit den entsprechenden Objekten injiziert, die für die FXML-Elemente erstellt wurden. Die eingefügten Felder sind also notwendigerweise spezifisch für die Controller-Instanz. Wenn Sie statische eingefügte Felder im Controller hätten und dieselbe FXML-Datei zweimal geladen und zweimal in der Benutzeroberfläche angezeigt hätten, hätten Sie keine Möglichkeit, auf beide Gruppen von Steuerelementen zu verweisen.

Aktualisieren: Antwort auf die Frage in den Kommentaren

Verwenden Sie insbesondere keine statischen Felder, nur damit sie von außerhalb der Klasse zugänglich sind. Ein statisches Feld hat einen einzigen Wert, der zur Klasse gehört, anstatt einen Wert für jede Instanz der Klasse, und die Entscheidung, Felder statisch zu machen, sollte nur getroffen werden, wenn dies sinnvoll ist. Mit anderen Worten, static definiert Umfangnicht Barrierefreiheit. Um den Zugriff auf Instanzdaten zu ermöglichen, müssen Sie lediglich einen Verweis auf die Instanz haben. Die FXMLLoader hat ein getController() Methode, mit der Sie einen Verweis auf den Controller abrufen können.

Ein verwandter Punkt: Es ist auch keine gute Idee, die UI-Steuerelemente vom Controller aus verfügbar zu machen. Stattdessen sollten Sie die Daten verfügbar machen. Anstatt beispielsweise a getTextField() -Methode im Controller, definieren Sie stattdessen a textProperty() Methode, die a zurückgibt StringProperty repräsentiert den Inhalt der TextField. Der Grund dafür ist, dass wenn Ihr Chef ins Büro kommt und Ihnen sagt, dass er das will TextField durch a ersetzt werden TextAreaoder ein ComboBox<String>oder ein anderes Steuerelement, dann wird es viel schwieriger, wenn Klassen außerhalb des Controllers Ihr verwenden TextField. Es ist viel weniger wahrscheinlich, dass sich die Struktur der Daten ändert, die von Ihrem Controller dargestellt werden, als die Implementierung, wie diese Daten dem Benutzer präsentiert werden.

Für einige Beispiele

  • Danke James..Gibt es irgendwie Zugriff auf den Inhalt einer Komponente von anderen Controller-Klassen? Zum Beispiel habe ich einige Inhalte (Kontrollkästchen und Beschriftungen) in einer ListView in einer Controller-Klasse angezeigt. Wie soll ich vorgehen, wenn ich von einer anderen Controller-Klasse aus darauf zugreifen möchte, ohne den Inhalt zu ändern oder zu ändern?

    – Christopher_Daniel

    17. April 2014 um 10:38 Uhr

  • +1 für eine gute Erklärung. Ich fand Statik in solchen Situationen immer sinnvoll. Sie könnten noch bis 8b109 statisch verwenden. Dies ist ungefähr die fünfte Frage, die ich bisher dazu gesehen habe, aber nie eine Erklärung für “Warum nicht statisch”.

    – Brian

    17. April 2014 um 14:31 Uhr


964980cookie-checkjavafx 8-Kompatibilitätsprobleme – Statische FXML-Felder

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy