JavaFX Scene loses color when a button is created

这一生的挚爱 提交于 2020-01-03 18:02:43

问题


Can anyone explain why my scene loses color the moment I create a button in JavaFX?

The following code works, with the background of the scene changing to red

@Override
public void start(Stage primaryStage){

    //Set Primary stage title and create a rootNode
    primaryStage.setTitle("Hello World");
    FlowPane rootNode = new FlowPane();

    //Create a scene and add it to the rootNode
    Scene myScene = new Scene(rootNode, 300, 200, Color.RED);

    //Add the scene to the stage
    primaryStage.setScene(myScene);

    //Show the stage
    primaryStage.show();
}

However, the moment I create another control, like a button in the example below (and I don't even have to add it to the flowpane), the color reverts back to grey.

@Override
public void start(Stage primaryStage){

    //Set Primary stage title and create a rootNode
    primaryStage.setTitle("Hello World");
    FlowPane rootNode = new FlowPane();

    //Create a scene and add it to the rootNode
    Scene myScene = new Scene(rootNode, 300, 200, Color.CORAL);

    Button newBtn = new Button();

    //Add the scene to the stage
    primaryStage.setScene(myScene);

    //Show the stage
    primaryStage.show();
}

Anyone know why this is? Am I trying to change the background color incorrectly?


回答1:


Your scene background color should not be visible at all, because rootNode covers the whole scene, and rootNode has its own background color which is set in the default JavaFx theme (that's the grey color you're seeing):

//modena.css

.root {
  ... 

  /***************************************************************************
   *                                                                         *
   * Set the default background color for the scene                          *
   *                                                                         *
   **************************************************************************/

   -fx-background-color: -fx-background;
}

So, you need to change the background color of rootNode, as the other answer already suggested.

The remaining question is why, in your first example, the default root background color is not applied to rootNode (it's transparent and it shouldn't be) and you see the scene's background color instead.

The answer - it's probably a bug. In JavaFx, the default theme is set with the method PlatformImpl.setDefaultPlatformUserAgentStylesheet() which is called only in these cases:

  • when you call Application.setUserAgentStylesheet (source)
  • in static initializer block of Control and PopupControl classes (source and source)

FlowPane extends neither Control nor PopupControl, so JavaFx doesn't even load the default theme and your rootNode remains transparent (you see the scene's background color).

In your other example you create a Button control, which extends Control class, so static initializer block of Control class is executed and the default modena theme is loaded - your rootPane gets its default grey color from the default theme and you no longer see the scene's background color.




回答2:


TL;DR Set the background color of the rootPane either to the desired color or to Color.TRANSPARENT.

This is a very curious case.

When you initially create the Button the initialize method is called in the Button's constructor:

private void initialize() {
    getStyleClass().setAll(DEFAULT_STYLE_CLASS);
    setAccessibleRole(AccessibleRole.BUTTON);
    setMnemonicParsing(true);     // enable mnemonic auto-parsing by default
}

I assume (but I cannot tell you with 100% certainty) that this applies styles to elements in your app (as explained in this answer it's because of a static initializer), because if you create a Button (and do not even add it to your rootNode) rootNode will have a background after the call to primaryStage.show(). To proof this I have modified your code:

System.out.println("background: " + rootNode.getBackground());
Button newBtn = new Button();
primaryStage.setScene(myScene);
primaryStage.show();
System.out.println("background after showing scene: " + rootNode.getBackground());

The output looks like this (and the background color is grey):

background: null
background after showing scene: javafx.scene.layout.Background@20c95282

If I remove the button creation and run it again the background color is red and I have the following output:

background: null
background after showing scene: null

So I suggest that you either set the background color to the rootNode or explicitly set the background color of the rootNode to transparent (Color.TRANSPARENT). Both solutions worked for me.

rootNode.setBackground(new Background(new BackgroundFill(Color.CORAL, null, null)));


来源:https://stackoverflow.com/questions/52531243/javafx-scene-loses-color-when-a-button-is-created

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!