问题
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
andPopupControl
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