如何解决如何使 WebView 的背景透明?
我在 IntelliJ IDEA 中有一个 Maven 项目,使用 JDK 15 和 JavaFX 15。
我试过了:
- 为 WebEngine 设置样式
- 为 WebView 设置混合模式
- 尝试过的网页
没有成功。如何使 WebView 的背景透明?
我的模块信息.java:
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 依赖项:
<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:
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)).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();
}
}
虚拟机选项:
--module-path ${PATH_TO_FX} --add-modules javafx.controls,javafx.web --add-exports javafx.web/com.sun.webkit.dom=ALL-UNNAMED
解决方法
WebView 在网页中呈现 DOM CSS。如果你想要一个透明的背景,你还必须修改那里的 CSS。
编辑......以下有效,但打开了一罐蠕虫。
@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)).getRGB());
f.setAccessible(false);
} catch (Exception e) {
}
});
vb.getChildren().add(b);
primaryStage.setScene(new Scene(vb));
primaryStage.show();
}
添加导入列表
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;
您可能需要添加以下内容:
--add-exports=javafx.web/com.sun.webkit.dom=ALL-UNNAMED \
在 run.jvm
文件的 project.properties
args 参数中。
注意...这是一种黑客行为,oracle 不鼓励这样做。
编辑 (2)
同样,这是一种黑客行为,充其量是不完整的。
此快照是在移除背景后立即向下滚动后拍摄的。
从技术上讲,我认为正在发生的事情是,每当 DOM 渲染引擎重新绘制框架时,都希望分层绘制所有内容,而背景永远不会是透明的。因此,它不会“清除”内容,它只是重复地在自身之上绘制前景。
此外,还有一件有趣的事情正在发生。
如果你点击 + reloadpage,或者如果你点击“接受 cookie”,页面背景会被删除......我很确定这会触发 dom 更新。
所以显然正在发生的事情是 WebView 和 WebPage 组件是 2 个不同领域的一部分。 WebView 是 DOM 操作... WebPage 是 DOM 在处理渲染的特定阶段使用的东西。
如果我就 WebPage 中的功能为何被“隐藏”发表我的看法,我可能会暂停此帐户……但根据个人经验,每当难以掌握的内容(例如 WebPage)在openJFx,这通常意味着您将浪费数月的时间来寻找解决方案,而这些解决方案很可能在未来某个时候更改,从而使您的更改过时。
我的建议是要么放弃这个问题,要么彻底改变你的心态。
我认为您应该做的基本上是在窗格之类的东西中模拟渲染。
so... new Stage... PaneX 作为场景,解析 webview 中的任何内容,并使用 css 和诸如此类的东西将节点放在 PaneX 中,这些节点的外观和感觉基本上与 webview 中的节点相同。 ...正如您所想的那样...这将是屁股中的一个窗格...
或者,您可能需要考虑获取 openjfx 代码库并使用修改后的源代码,以便通过添加额外代码使网页有效地清除自身......但这取决于您。
最后,您必须考虑这样做的原因可能与性能问题有关。
例如,不是只清除网页中的背景,而是删除页面中 CSS 中的任何和所有背景,您必须执行很多操作。这意味着性能问题,因为它本质上意味着在页面加载时解析完整的 dom 树。
,经过多次尝试,我终于达到了预期的效果。
JDK 15、JavaFX 15。
我尝试从这里实现一个示例:https://stackoverflow.com/a/26519831/10946427
还有一个透明的背景。然后我就知道为什么了。这是由于我通过大量试验和错误添加的 VM 选项。
如果没有这些 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
我选择的最佳答案中的示例很可能也适用于这些选项。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。