'Transparent background in the WebView in JavaFX

I need to show my webview content over parent background pattern. Is there a straightforward way to do it?



Solution 1:[1]

This might be useful

final com.sun.webkit.WebPage webPage = com.sun.javafx.webkit.Accessor.getPageFor(engine);
webPage.setBackgroundColor(0);

Solution 2:[2]

Webview transparent I get a good solution here : https://javafx-jira.kenai.com/browse/RT-29186 read comments Harry Hur

    import java.lang.reflect.Field;
    import javafx.application.Application;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue; 
    import javafx.scene.Scene;
    import javafx.scene.web.WebEngine;
    import javafx.scene.web.WebView;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle; 
    import org.w3c.dom.Document; `

    public class TestTranparentApps extends Application { 

    @Override
    public void start(Stage primaryStage) {
        new WebPage(primaryStage);
        primaryStage.show(); 
    } 

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    class WebPage{

        WebView webview;
        WebEngine webengine;
        public WebPage(Stage mainstage){
            webview = new WebView();
            webengine = webview.getEngine();

            Scene scene = new Scene(webview);
            scene.setFill(null);

            mainstage.setScene(scene);
            mainstage.initStyle(StageStyle.TRANSPARENT);
            mainstage.setWidth(700);
            mainstage.setHeight(100);

            webengine.documentProperty().addListener(new DocListener());
            webengine.loadContent("<body style='background : rgba(0,0,0,0);font-size: 70px;text-align:center;'>Test Transparent</body>");
        }

        class DocListener implements ChangeListener<Document>{  
            @Override
            public void changed(ObservableValue<? extends Document> observable, Document oldValue, Document newValue) {
                try {

                    // Use reflection to retrieve the WebEngine's private 'page' field. 
                    Field f = webengine.getClass().getDeclaredField("page"); 
                    f.setAccessible(true); 
                    com.sun.webkit.WebPage page = (com.sun.webkit.WebPage) f.get(webengine);  
                    page.setBackgroundColor((new java.awt.Color(0, 0, 0, 0)).getRGB()); 

                } catch (Exception e) {
                }

            }
        }  
    } 
} 

Solution 3:[3]

If u have a bright background use

webView.setBlendMode(BlendMode.DARKEN);

and when dark background, then

webView.setBlendMode(BlendMode.LIGHTEN);

This will probably be fixed in some time, this feature is requested on the JavaFX bug tracker #RT-25004

Solution 4:[4]

You can Chroma Key your WebView over your content using Blend effects.

Update

I tried this out and implementing a true Chroma Key with the built-in Blend effects of JavaFX 2.2 in JavaFX is actually pretty difficult (and surpassed my capabilities of implementing). I managed to make the technique work with pre-chroma keyed flv video formats, but not with arbitrary nodes such as WebView.

Still, for now, you can achieve something somewhat similar in a simple way using the darken and lighten effects as martini suggests in his answer. It's not perfect, but will probably need to suffice until RT-25004 is implemented or the JavaFX platform provides a more comprehensive set of alpha compositing operations.

Solution 5:[5]

Since JavaFX 18, transparent WebView backgrounds are finally supported (see JDK-8090547):

WebEngine engine = webView.getEngine();
webView.setPageFill(Color.TRANSPARENT);

Solution 6:[6]

You need to set the Web Page Background to 0. But you might need to do some other stuff to not make it break on scrolling. The following GitHub Gist is a java agent that can be added to our app and that manipulates WebPages to be transparent. https://gist.github.com/riccardobl/18603f9de508b1ab6c9e or more up to date version https://github.com/FAForever/downlords-faf-client/blob/develop/webview-patch/src/main/java/com/faforever/client/webviewpatcher/TransparentWebViewPatch.java

Only solution that I found and was fully working.

Solution 7:[7]

I'm resurrecting this because I found a better solution for the problem of having a WebView over a gradient. Suppose you have a gradient like this and want to display an HTML string over it in white color that looks something like this:

<p>Integer semper, est imperdiet mattis porttitor, massa vulputate ipsum</p>

The trick is to convert your gradient to Base64 string:

iVBORw0KGgoAAAANSUhEUgAAAAEAAAHDCAYAAADlQnCCAAAAq0lEQVRIib2VwRWAMAhDaSdwCtd1No8uUzzp0ydBgjwvnmhCPrTKtKxbb73NXcaQLiL5j/olyhQH5JXu4H4sUGyWHAIa9VWjU9qtyAh6JGicIMJno2HcGSX3gJsCKH5EfUfHJUed+qFzekrpuVzM/oq4uFKGr/pI4B7wiP2Vgno0F/uCUQ9ZXWg4vM/JL1Hpt10Nt+hZjhCDKepxV8H3soZGWOqHP3ZSGYDdATTkg3iGU3JnAAAAAElFTkSuQmCC

Since WebView loads any HTML string, this can involve <body> that has a background. In my instance, the WebView was not occupying the whole space with the gradient, so I had to position the background as well. Following is the HTML I added to the HTML string above at the beggining:

<html>
<head>
</head>
<body style="margin: 0px; padding: 0px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAHDCAYAAADlQnCCAAAAq0lEQVRIib2VwRWAMAhDaSdwCtd1No8uUzzp0ydBgjwvnmhCPrTKtKxbb73NXcaQLiL5j/olyhQH5JXu4H4sUGyWHAIa9VWjU9qtyAh6JGicIMJno2HcGSX3gJsCKH5EfUfHJUed+qFzekrpuVzM/oq4uFKGr/pI4B7wiP2Vgno0F/uCUQ9ZXWg4vM/JL1Hpt10Nt+hZjhCDKepxV8H3soZGWOqHP3ZSGYDdATTkg3iGU3JnAAAAAElFTkSuQmCC); background-repeat: repeat-x; background-position: 0 -152px;">
<span style="font-family: Arial; font-size: 12px; color: white; display: block; margin:0px;">

And at the end:

</span></body></html>

Therefore producing such code:

String desc = "<html><head></head><body style=\"margin: 0px; padding: 0px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAHDCAYAAADlQnCCAAAAq0lEQVRIib2VwRWAMAhDaSdwCtd1No8uUzzp0ydBgjwvnmhCPrTKtKxbb73NXcaQLiL5j/olyhQH5JXu4H4sUGyWHAIa9VWjU9qtyAh6JGicIMJno2HcGSX3gJsCKH5EfUfHJUed+qFzekrpuVzM/oq4uFKGr/pI4B7wiP2Vgno0F/uCUQ9ZXWg4vM/JL1Hpt10Nt+hZjhCDKepxV8H3soZGWOqHP3ZSGYDdATTkg3iGU3JnAAAAAElFTkSuQmCC); background-repeat: repeat-x; background-position: 0 -152px;\"><span style=\"font-family: Arial; font-size: 12px; color: white; display: block; margin:0px;\">" + description + "</span></body></html>";
wv_desc.getEngine().loadContent(desc);

You could probably put the styles in the <head> or load them some other way for clarity I suppose, but this is a much better work-around to anything else I found on the net for this issue.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yurets
Solution 2
Solution 3
Solution 4
Solution 5 Michel Jung
Solution 6 Alex
Solution 7 Dreen