I need to show my webview content over parent background pattern. Is there a straightforward way to do it?
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) {
}
}
}
}
}
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
This might be useful
final com.sun.webkit.WebPage webPage = com.sun.javafx.webkit.Accessor.getPageFor(engine);
webPage.setBackgroundColor(0);
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.
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.
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.