问题描述
美好的一天,
当我运行此代码时:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class mcve extends Application {
static Label myScore = new Label("Test");
static Rectangle rect = new Rectangle(0,0,10,10);
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
myScore.setTextFill(Color.WHITE);
myScore.setLayoutY(20);
myScore.setLayoutX(200);
myScore.setFont(new Font("Arial", 30));
myScore.setText("0");
rect.setFill(Color.WHITE);
final Group group = new Group(myScore,rect);
Scene scene = new Scene(group, 500, 500, Color.BLACK);
stage.setScene(scene);
stage.show();
}
}
它会产生以下异常:
Exception in thread "main" java.lang.ExceptionInInitializerError
at mcve.<clinit>(mcve.java:11)
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
但是,如果我删除顶部 Label 之前的 static 关键字,则代码运行得很好.
However if I remove the static keyword before Label at the top, the code runs just fine.
我的问题是:为什么在创建静态标签而不是静态矩形时会出现错误?我希望标签是静态的,而不是类的对象.
My question is: Why does the error occur when creating a static Label but not a static Rectangle? I want the Label to be static and not an object of a class.
推荐答案
本质上,这是一个初始化顺序的问题.创建 Node
对象时需要正确初始化 UI 平台.潜在地,它也可能发生在 Rectangle
,但最有可能的是 Label
(它是一个 Control
)更依赖于正确初始化的平台.在这种特殊情况下,区别在于 Shape
对象不需要 CSS
,而 Control
对象需要.这会导致在堆栈跟踪中看到的平台方法被调用,此时工具包尚未初始化.
Essentially, this is a matter of initialization order. The UI platform needs to be properly initialized when creating Node
objects. Potentially, it could also happen with a Rectangle
, but most likely a Label
(which is a Control
) relies even more on a properly initialized platform. In this particular case, the difference is that Shape
objects do not require CSS
, while Control
objects do. This causes the platform methods to be called as seen in the stack trace, at a point when the toolkit is not yet initialized.
static
类成员在加载class mvce
时被初始化.这是在调用main()
方法之前完成的,因此在调用launch()
方法之前完成.此时平台尚未初始化.
The
static
class member is initialized whenclass mvce
is loaded. This is done before themain()
method is called, and hence before thelaunch()
method is called. The platform is not initialized yet at this point.
另一方面,非静态成员在实例化 class mvce
时被初始化.class mvce
由 launch()
方法在内部实例化,之后工具包已正确初始化.
The non-static member, on the other side, is initialized when class mvce
is instantiated. The class mvce
is instantiated internally by the launch()
method, after the toolkit has been properly initialized.
此外,通常没有理由使用静态引用.只需使用会员.
Also, there is usually no reason to use static references. Just use a member.
这篇关于静态关键字的 JavaFX 问题;带有最小、完整和可验证的示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!