首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使WebView的背景透明?

如何使WebView的背景透明?
EN

Stack Overflow用户
提问于 2021-02-19 10:59:59
回答 2查看 400关注 0票数 0

我在IntelliJ IDEA中有一个Maven项目,使用JDK 15和JavaFX 15。

我试过:

  1. Set style for WebEngine
  2. Set WebEngine WebView
  3. 尝试WebPage

什么也没成功。如何使WebView的背景透明?

我的模块-info.java:

代码语言:javascript
复制
module project {
    requires javafx.controls;
    requires javafx.web;
    requires javafx.graphics;
    requires uk.co.caprica.vlcj;
    requires uk.co.caprica.vlcj.javafx;

    exports project;
}

我的pom.xml依赖关系:

代码语言:javascript
复制
<dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>15</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-web</artifactId>
            <version>15</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>15</version>
        </dependency>
        <dependency>
            <groupId>uk.co.caprica</groupId>
            <artifactId>vlcj</artifactId>
            <version>4.7.0</version>
        </dependency>
        <dependency>
            <groupId>uk.co.caprica</groupId>
            <artifactId>vlcj-javafx</artifactId>
            <version>1.0.2</version>
        </dependency>
</dependencies>

我创建了一个新项目,并试图从答案中实现这个示例。发生了。不幸的是,单击按钮后背景色变得不透明。你知道为什么这个例子不管用吗?

Main.java:

代码语言:javascript
复制
import javafx.application.Application;
import javafx.stage.Stage;

import com.sun.webkit.dom.HTMLDocumentImpl;
import java.lang.reflect.Field;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.web.WebView;

public class Main extends Application {

    @Override
    public void start(final Stage stage) {
        initStage(stage);
    }

    private void initStage(Stage stage){
        WebView wv = new WebView();
        wv.setStyle("-fx-background-color: transparent;");

        wv.getEngine().load("https://w3schools.com");
        VBox vb = new VBox(wv);
        vb.setBackground(new Background(new BackgroundFill(Color.ORANGERED, CornerRadii.EMPTY, Insets.EMPTY)));

        Button b = new Button("remove page background");

        b.setOnAction((event) -> {
            HTMLDocumentImpl cast = (HTMLDocumentImpl) wv.getEngine().getDocument();

            try {
                Field f = wv.getEngine().getClass().getDeclaredField("page");
                f.setAccessible(true);
                com.sun.webkit.WebPage page = (com.sun.webkit.WebPage) f.get(wv.getEngine());
                page.setBackgroundColor((new java.awt.Color(1, 1, 1, 1)).getRGB());
                f.setAccessible(false);
            } catch (Exception e) {
            }

        });
        vb.getChildren().add(b);

        stage.setScene(new Scene(vb));
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

VM选项:

代码语言:javascript
复制
--module-path ${PATH_TO_FX} --add-modules javafx.controls,javafx.web --add-exports javafx.web/com.sun.webkit.dom=ALL-UNNAMED

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-19 11:08:10

WebView在网页中呈现DOM。如果您想要一个透明的背景,您将不得不修改那里的CSS。

编辑..。以下工作,但打开了一罐蠕虫。

代码语言:javascript
复制
    @Override
    public void start(Stage primaryStage) throws Exception {
    WebView wv = new WebView();
    wv.setStyle("-fx-background-color: transparent;");

    wv.getEngine().load("https://w3schools.com");
    VBox vb = new VBox(wv);
    vb.setBackground(new Background(new BackgroundFill(Color.ORANGERED, CornerRadii.EMPTY, Insets.EMPTY)));

    Button b = new Button("remove page background");

    b.setOnAction((event) -> {
        HTMLDocumentImpl cast = HTMLDocumentImpl.class.cast(wv.getEngine().getDocument());
        Node item = cast.getElementsByTagName("html").item(0);

        try {
            // Use reflection to retrieve the WebEngine's private 'page' field. 
            Field f = wv.getEngine().getClass().getDeclaredField("page");
            f.setAccessible(true);
            com.sun.webkit.WebPage page = (com.sun.webkit.WebPage) f.get(wv.getEngine());
            page.setBackgroundColor((new java.awt.Color(0, 0, 0, 0)).getRGB());
            f.setAccessible(false);
        } catch (Exception e) {
        }

    });
    vb.getChildren().add(b);

    primaryStage.setScene(new Scene(vb));
    primaryStage.show();
}

新增进口清单

代码语言:javascript
复制
import com.sun.webkit.dom.HTMLDocumentImpl;
import java.lang.reflect.Field;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import org.w3c.dom.Node;

您可能需要添加如下内容:

代码语言:javascript
复制
--add-exports=javafx.web/com.sun.webkit.dom=ALL-UNNAMED \

run.jvm文件的project.properties args参数中。

注意..。这是一种黑客行为,不受甲骨文的鼓励。

编辑(2)

同样,这是一种黑客行为,充其量也是不完整的。

此快照是在移除背景后立即向下滚动后拍摄的。

从技术上讲,我认为的是,每当DOM呈现引擎重新绘制一个框架时,它都会按层次绘制所有内容,而背景则永远不会是透明的。因此,它并不是“清晰”的东西,它只是简单地把前景画在自己的上面。

另外,有一件有趣的事情正在发生。

如果您的rClick +重新加载页面,或者如果您单击“接受cookie”的内容,页面背景将被移除.我很确定这会触发dom更新。

很明显,WebView和WebPage组件是两个截然不同的宇宙的一部分。WebView是DOM操作..。WebPage是DOM在处理呈现的特定阶段使用的东西。

如果我说出为什么WebPage中的功能是“隐藏”的,我可能会暂停这个帐户.但是从个人的经验来看,无论什么事情在openJFx中很难掌握,比如openJFx,这通常意味着您将花费几个月的时间来为一些最有可能在将来某个时候发生改变的事情找到解决方案,从而使您的更改变得过时。

我的建议是要么放弃这个问题,要么完全改变你的心态。

我认为你应该做的基本上是模仿渲染在一个类似的窗格。

所以..。新阶段..。PaneX作为场景,解析css视图中的任何内容,并使用css和诸如此类的方法在PaneX中放置节点,这些节点的外观和感觉与css视图中的节点基本相同。..。你可以想象..。这会是屁股里的一块玻璃..。

或者,您可能需要考虑获取openjfx代码库并使用修改的源代码,以便通过添加额外的代码使WebPage有效地清除自身。但这取决于你。

最后,您必须考虑这样做是出于一个可能围绕性能问题的原因。

例如,不只是清除网页中的背景,而是删除页面中CSS中的任何背景和所有背景,您将不得不这样做。这意味着性能问题,因为它本质上意味着在页面加载时进行完整的dom树解析。

票数 0
EN

Stack Overflow用户

发布于 2021-02-22 14:23:43

经过多次尝试,我终于达到了预期的效果。

JDK 15,JavaFX 15.

我试着从这里实现一个例子:https://stackoverflow.com/a/26519831/10946427

背景是透明的。然后我想出了原因。这是因为我通过大量的尝试和错误添加了VM选项。

如果没有这些VM选项,这个示例就无法工作。

代码语言:javascript
复制
--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

最有可能的例子,从答案,我选择是最好的,也将与这些选项。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66276295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档