2016-04-22 71 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()'...)中。看起来像魔术...... –