2016-04-22 10 views
1

Guten Tag,JavaFX Statische vs nicht Static

Warum JavaFX ein Problem haben, wenn ich eine statische Beschriftung außerhalb eines Verfahrens zu erstellen, aber doesen't das gleiche Problem mit Formen wie eine Kugel oder ein Rechteck haben.

Folgende funktioniert gut:

static Rectangle upperBorder = new Rectangle(0, 0, 10, 10); 

Aber das schafft eine Ausnahme:

static Label myScore = new Label("Test"); 

Ich habe das Label die folgende Art und Weise zu erstellen:

Label myScore = new Label("Test"); 

Dies ohne ist das Schlüsselwort "statisch"

Dies ist der Fehler:

Exception in thread "main" java.lang.ExceptionInInitializerError 
at pong.Main.<clinit>(Main.java:24) 
at java.lang.Class.forName0(Native Method) 
at java.lang.Class.forName(Class.java:264) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:122) 
Caused by: java.lang.IllegalStateException: Toolkit not initialized 
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:273) 
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:268) 
at com.sun.javafx.application.PlatformImpl.setPlatformUserAgentStylesheet(PlatformImpl.java:550) 
at com.sun.javafx.application.PlatformImpl.setDefaultPlatformUserAgentStylesheet(PlatformImpl.java:512) 
at javafx.scene.control.Control.<clinit>(Control.java:87) 
... 4 more 
+2

Der Fehler besagt, dass das JavaFX-Toolkit nicht initialisiert wurde, was nicht direkt mit der Verwendung einer 'statischen' Variablen zusammenhängt (obwohl, imho, wenn Sie ein UI-Steuerelement erstellen, machen Sie die Dinge sowieso nur falsch). Veröffentlichen Sie ein [MCVE], das die Ausnahme generiert, wenn Sie möchten, dass jemand herausfinden kann, was eigentlich falsch läuft. –

+0

Haben Sie 'Application' erweitert und' Application # launch' von der Hauptmethode aufgerufen? –

+0

Ja, wie oben vorgeschlagen, zeigt der Fehler an, dass Sie die JavaFx-Anwendung nicht richtig starten, es ist möglicherweise nicht verwandt, dass Sie smth 'static' definieren – AntJavaDev

Antwort

2

Der Fehler ist höchstwahrscheinlich nicht durch das static Schlüsselwort verursacht.

dieses einfache Testprogramm vor:

public class Test { 

    static Rectangle a = new Rectangle(0, 0, 10, 10); 
    static Label  b = new Label("b"); 

    public static void main(String[] args) { 
    } 
} 

Beim Start es eine Ausnahme auslöst:

Exception in thread "main" java.lang.ExceptionInInitializerError 
    at Test.<clinit>(Test.java:7) 
Caused by: java.lang.IllegalStateException: Toolkit not initialized 
    at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:273) 
    at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:268) 
    at com.sun.javafx.application.PlatformImpl.setPlatformUserAgentStylesheet(PlatformImpl.java:550) 
    at com.sun.javafx.application.PlatformImpl.setDefaultPlatformUserAgentStylesheet(PlatformImpl.java:512) 
    at javafx.scene.control.Control.<clinit>(Control.java:87) 
    ... 1 more 

Dies deutet auf die JavaFX Application Platform nicht gestartet werden. Der Fehler scheint zu verschwinden, wenn das Schlüsselwort static in diesem Beispiel entfernt wird, aber das liegt daran, dass das Label b nicht im Code verwendet wird.


die gleiche Klasse starten als eine JavaFX-Anwendung sorgt dafür, dass die Plattform initialisiert wird, bevor das erste Control erstellt:

public class Test extends Application { 

    static Rectangle a = new Rectangle(0, 0, 10, 10); 
    static Label  b = new Label("b"); 

    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     // TODO Auto-generated method stub 
    } 
} 

Der Unterschied zwischen Rectangle und Label im Code ist, dass Label ist ein Control und Rectangle ist nicht. Label kann nicht ohne eine laufende JavaFX-Plattform instanziiert werden.

+0

Das ist interessant. 'Control' hat einen statischen Initializer, der das Stylesheet des Benutzeragenten einstellt (weil Steuerelemente CSS erfordern; andere Knoten nicht); das muss auf dem FX-Anwendungs-Thread passieren und so erzeugt das erste Beispiel eine Ausnahme, weil die Plattform nicht gestartet wurde. Aber im zweiten Beispiel, wie wird die Plattform gestartet, bevor das 'Label' erstellt wird? Ich habe immer angenommen, dass 'launch()' es gestartet hat; aber sicher wird das 'Label' aufgerufen, das in diesem Beispiel vor' launch() 'erstellt wurde. –

+0

@James_D Ja, es ist interessant. Ich schaue immer noch darauf. Ich weiß, dass eine Klasse, die die Anwendung erweitert, [von LaucherHelper $ FXHelper.main] gestartet wird (http://stackoverflow.com/a/28328284/1288408).Dieser Helfer muss irgendwie für den Aufruf von 'startup' in' PlatformImpl' verantwortlich sein. –

+0

Aber das wird von der "Start" -Methode aufgerufen, zu welcher Zeit das 'Label' bereits erfolgreich erstellt wurde (Sie können eine' System.out.println (b); '* vor * dem' launch() 'Aufruf durchführen in 'main()' ...). Scheint wie Magie ... –