2016-04-22 70 views
1

好日子,JavaFX的靜態與非靜態

爲什麼JavaFX的有一個問題,如果我創建一個方法之外的靜態標籤,但doesen't有類似球或矩形形狀相同的問題。

下面的作品就好了:

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

但是這創造了一個例外:

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

我要創建標籤的方式如下:

Label myScore = new Label("Test"); 

這是不「靜態」關鍵字。

這是錯誤:

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

錯誤提示JavaFX工具包尚未初始化,這與使用「靜態」變量沒有直接關係(儘管如此,如果您正在製作UI控件,您只是以錯誤的方式進行操作)。發佈一個能夠產生異常的[MCVE],如果你想讓某人能夠找出實際出錯的地方。 –

+0

您是否從主方法擴展了'Application'並且調用了'Application#launch'? –

+0

是的,正如上面提出的那樣,錯誤表明您沒有正確啓動JavaFx應用程序,它可能與您定義的smth靜態無關。 – AntJavaDev

回答

2

該錯誤是最有可能不是由static關鍵字引起的。

考慮這個簡單的測試程序:

public class Test { 

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

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

推出時,它拋出一個異常:

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 

這暗示在沒有被啓動的JavaFX應用平臺。在此示例中刪除static關鍵字時,錯誤似乎消失,但這是因爲代碼中未使用標籤b


啓動同一類作爲JavaFX應用程序確保第一Control被創建之前,平臺初始化:

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

在代碼RectangleLabel之間的區別在於LabelControlRectangle不是。如果沒有運行的JavaFX平臺,則無法實例化Label

+0

這很有趣。 'Control'有一個靜態初始化器,用於設置用戶代理樣式表(因爲控件需要CSS;其他節點不需要);必須在FX應用程序線程上發生,因此第一個示例會生成異常,因爲該平臺未啓動。但在第二個例子中,平臺在創建'Label'之前如何開始?我一直認爲'launch()'啓動了它;但肯定是在調用launch()之前的例子中創建的'Label'。 –

+0

@James_D是的,這很有趣。我仍在研究它。我知道一個擴展Application的類[由LaucherHelper $ FXHelper.main啓動](http://stackoverflow.com/a/28328284/1288408)。這個幫助者必須負責調用'PlatformImpl'中的'startup'。 –

+0

但是,這是從'launch'方法調用的,那時'Label'已經成功創建(你可以在'launch()'調用之前執行'System.out.println(b);'*在'main()'...)中。看起來像魔術...... –