Good day,
When I run this Code:
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();
}
}
it creates the following exception:
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
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.
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 aRectangle
, but most likely aLabel
(which is aControl
) relies even more on a properly initialized platform. In this particular case, the difference is thatShape
objects do not requireCSS
, whileControl
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.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.The non-static member, on the other side, is initialized when
class mvce
is instantiated. Theclass mvce
is instantiated internally by thelaunch()
method, after the toolkit has been properly initialized.Also, there is usually no reason to use static references. Just use a member.
Have you tried to just declare the static label, but instanciate and set it later on in the start() method? This should work, too.