JavaFX中WebView的透明背景

12

我需要在父元素的背景图案上显示我的webview内容。有没有简单的方法来实现这个目标?

7个回答

14

这可能会有用。

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

1
使WebView透明只需要以上两行代码。或者您可以将其变成一行代码:com.sun.javafx.webkit.Accessor.getPageFor(webviewgetEngine()).setBackgroundColor(0) - Vishrant
这似乎是一个不错的解决方法来更改webview的背景颜色,尽管它给我带来了一个IllegalAccessError错误: Caused by: java.lang.IllegalAccessError: class com.my.module.MyClassName (in unnamed module @0x4192e30a) cannot access class com.sun.javafx.webkit.Accessor (in module javafx.web) because module javafx.web does not export com.sun.javafx.webkit to unnamed module @0x4192e30a - FARS

10

我在这里找到了关于Webview透明的好解决方案: https://javafx-jira.kenai.com/browse/RT-29186 请参考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) {
                }

            }
        }  
    } 
} 

WebEngine.page是final的,因此您可以在webView创建时执行反射而无需监听文档更改。虽然我的版本(JDK 1.7.80)使用com.sun.webpane.platform,但它可能是相同的。 - TWiStErRob
我尝试过这个,但在滚动时它没有正确地重绘背景。这是使用JavaFX 11时出现的问题。 - john16384
这在我的项目中有效。JDK 15,JavaFX 15。需要添加以下VM选项: --add-exports javafx.web/com.sun.javafx.webkit=ALL-UNNAMED; --add-exports javafx.web/com.sun.webkit=ALL-UNNAMED; --add-opens javafx.web/javafx.scene.web=ALL-UNNAMED; - Dmitriy

6
如果您的背景色较亮,请使用:
webView.setBlendMode(BlendMode.DARKEN);

当背景为暗色时,那么

webView.setBlendMode(BlendMode.LIGHTEN);

这个问题可能会在一段时间内得到解决,该功能已经在JavaFX的错误跟踪器#RT-25004上被请求。


它能在JDK 8(1.8.0_40-ea)上运行,但在JDK 7(1.7.0_65)上不能运行。 - Paolo Fulgoni

1
自JavaFX 18版本以来,终于支持了透明的WebView背景(参见JDK-8090547):
WebEngine engine = webView.getEngine();
webView.setPageFill(Color.TRANSPARENT);

1

您可以使用Chroma KeyBlend效果在您的内容上方覆盖WebView。

更新

我尝试了这个方法,使用JavaFX 2.2内置的Blend效果实现真正的Chroma Key实际上非常困难(超出了我的能力范围)。我设法使该技术适用于预先进行过Chroma Key处理的flv视频格式,但无法适用于任意节点,例如WebView。

不过,目前您仍然可以像martini在他的答案中建议的那样,使用变暗和变亮效果以简单的方式实现类似的效果。虽然不完美,但可能需要满足,直到RT-25004被实现或JavaFX平台提供更全面的alpha合成操作集为止。


0

你需要将网页背景设置为0。但是你可能需要做一些其他的事情,以免在滚动时出现问题。以下GitHub Gist是一个Java代理,可以添加到我们的应用程序中,并操纵Web页面使其透明。https://gist.github.com/riccardobl/18603f9de508b1ab6c9e 或者更更新的版本 https://github.com/FAForever/downlords-faf-client/blob/develop/webview-patch/src/main/java/com/faforever/client/webviewpatcher/TransparentWebViewPatch.java

这是我找到的唯一可行且完全有效的解决方案。


-1
我重新拾起这个话题,因为我找到了一个更好的解决方案,可以解决在渐变上方放置WebView的问题。假设您有一个像这样的渐变,并且想要以白色显示一个HTML字符串,看起来类似于这样:

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

诀窍在于将您的渐变转换为Base64字符串:

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

由于 WebView 可以加载任何 HTML 字符串,这可能涉及到具有背景的 <body>。在我的情况下,WebView 没有占据整个渐变空间,因此我还必须定位背景。以下是我在上面的 HTML 字符串中添加的 HTML:

<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;">

最后:

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

因此,产生这样的代码:
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);

你可以将样式放在<head>中或以其他方式加载,以提高清晰度,但对于此问题,这是我在网络上找到的任何其他解决方法之外更好的解决方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接