JavaFX 8 tooltip removes transparency of stage

2019-02-19 06:38发布

I had a hard time figuring out why my transparent stage refuses to be transparent. Finally I found out, that it was caused by a Tooltip that was installed into an ImageView:

ImageView imageViewIcon = new ImageView();
imageViewIcon.setFitWidth(70);
imageViewIcon.setFitHeight(70);
imageViewIcon.setPreserveRatio(false);
imageViewIcon.setImage(new Image("./next.png"));

Tooltip tooltip = new Tooltip("Tooltip!");
if (this.config.getShowTooltip("true")) {
    Tooltip.install(imageViewIcon, tooltip);
}

When I comment out the last 4 lines, the transparency works as expected, but with the Tooltip installed the stages background is grayish (e.g. the default window background). Though it's obvious what the button does and the tooltip is not essential for my layout it'd be nice to have, just to give a little hint...

Any suggestions or workarounds?

1条回答
2楼-- · 2019-02-19 07:15

Solution

Set the style -fx-background-color: transparent on the root node of the scene.

Background

Similar behavior is discussed in an Oracle JavaFX Forum post on the JavaFX Scene/Fill Color.

Relevant comments from the thread by David Grieve, the lead developer for the JavaFX CSS features:

This happens because modena.css sets the background color of the root node. Setting the style -fx-background-color: transparent on the root node of the scene is the solution.

BorderPane root = new BorderPane();  
root.setStyle("-fx-background-color: transparent;");  

Scene scene = new Scene(root, 600, 400, Color.BLACK); 

The default user agent stylesheet is loaded the first time a Control is instantiated. The reason for this is to avoid loading stylesheets and reduce CSS overhead in scene-graphs that contain nodes that don't use CSS.


The history behind it is that the designer of the modena theme felt that the controls looked better on this particular background color, which is a very light grey. Unfortunately, the Scene's background fill cannot be styled from CSS, so the style was set on the root node of the scene. There is an issue logged in JIRA to make Scene so that it can be styled by CSS (RT-31282)

The merit of loading in this way is to avoid css overhead in scene's that don't use controls. This would be typical of a splash screen, for example. Or maybe a game. This design choice was made a long time ago when CSS performance was a big issue, but it still makes sense for embedded devices.


In the case of your question, Tooltip is a control, so when you add it to the scene it implicitly triggers the default modena.css stylesheet to be loaded for the scene (which sets the background of the root node of the scene to gray rather than a null or transparent fill which is used when there are no controls in the scene). To retain the transparent background for the application when a control is used in the scene, it is necessary to explicitly set the scene root node background to transparent.


Sample code for a transparent stage:

//this is where the transparency is achieved:
//the three layers must be made transparent
//(i)  make the VBox transparent (the 4th parameter is the alpha)
root.setStyle("-fx-background-color: rgba(0, 0, 0, 0);");
//(ii) set the scene fill to transparent
scene.setFill(null);
//(iii) set the stage background to transparent
stage.initStyle(TRANSPARENT);
查看更多
登录 后发表回答