Javafx8 Popup Transparency issue

后端 未结 1 1054
伪装坚强ぢ
伪装坚强ぢ 2021-01-06 04:36

I am trying to port my javafx2 application over to javafx8 but have noticed some issues on Linux with popup controls.

相关标签:
1条回答
  • 2021-01-06 04:47

    What the Problem Is

    The default JavaFX 8 (modena.css) does not take into account that the transparent window feature is optional on some platforms (specifically some Linux platforms).

    It is unlikely that the default css will be changed until Java 9 comes out.

    How to Fix It

    This is a solution for Java 8+ only.

    Supply your own css to override the default css so that you can support those platforms without displaying an ugly white border areas around some of your controls. The css you provide can assume that transparent windows are not a feature of the underlying platform and style the UI so that it still looks good on such platforms. As the transparent window feature is a ConditionalFeature, on application startup, check to see if the conditional feature is supported, and if it is not, apply your custom stylesheet via Application.setUserAgentStyleSheet().

    Sample Application

    I have only tested this on a Mac (which supports the transparent window feature), so I can't really verify it will work as expected on Linux, but I hope it will work fine :-)

    import javafx.application.Application;
    import javafx.application.ConditionalFeature;
    import javafx.application.Platform;
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.ColorPicker;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    public class SolidPick extends Application {
    
        public static void main(String[] args) { launch(args); }
    
        @Override public void start(Stage stage) throws Exception {
            ColorPicker picker = new ColorPicker();
    
            if (Platform.isSupported(ConditionalFeature.TRANSPARENT_WINDOW)) {
                Application.setUserAgentStylesheet(
                    this.getClass().getResource(
                            "solid-pick.css"
                    ).toExternalForm()
                );
            }    
    
            StackPane layout = new StackPane(picker);
            layout.setPadding(new Insets(10));
    
            stage.setScene(new Scene(layout));
            stage.show();
        }
    
    }
    

    Then the file solid-pick.css an exact copy of the entire modena.css with the following additional lines appended to the end:

    .color-palette {
        -fx-background-radius: 0, 0;
        -fx-effect: null;
    }
    

    These lines:

    1. Give the color picker popup a square background rather than a rounded one.
    2. Remove the translucent drop shadow effect which normally surrounds the popup.

    The combination of these things provide the popup with a shape and border which looks much better in an environment which does not provide transparent windows.

    The solid-pick.css file should be placed in the same directory as the SolidPick application, so that it gets bundled into the application jar and will be available to the application classloader.

    Sample Output

    Here is some sample output of rendering on my Mac with and without the dropshadow border on the popup.

    Standard rendering =>

    standard rendering

    Modified rendering, with square borders and no shadow =>

    rendering without shadow

    Suggested Approach

    Go through your entire application (and possibly the entire modena.css stylesheet) and, using a similar approach to that done above for the color picker, fix up any rendering issues that arise in a transparent window incapable environment. Then use the resultant stylesheet in your application and (if licensing permits), contribute your custom stylesheet to the community by submitting it to a 3rd party project such as ControlsFX.

    0 讨论(0)
提交回复
热议问题