为啥JavaFX的WebView是红绿闪烁?
Posted
技术标签:
【中文标题】为啥JavaFX的WebView是红绿闪烁?【英文标题】:Why is JavaFX's WebView is flashing red and green?为什么JavaFX的WebView是红绿闪烁? 【发布时间】:2015-09-14 16:03:18 【问题描述】:我刚开始使用 JavaFX,我想将 WebView 放入 Window:
public static class HelloJavaFXWeb extends Application
@Override public void start(Stage stage) throws Exception
final Group root = new Group();
Scene scene = new Scene(root, Color.DODGERBLUE);
WebView webView = new WebView();
webView.getEngine().load("http://www.google.com");
root.getChildren().add(webView);
stage.setTitle("HelloWorld in JavaFX 2.0");
stage.setScene(scene);
stage.show();
Application.launch(HelloJavaFXWeb.class);
它看起来非常简单,但由于某种原因,当鼠标移动时,绘制区域会以红色和绿色突出显示。如何禁用闪烁的颜色?
更新:问题在于 Groovy/Gradle 交互
这是一个极其简单的复制
(将所有这些放在build.gradle
中并运行gradle tasks --no-daemon
):
buildscript
dependencies
def jvm = org.gradle.internal.jvm.Jvm.current()
if (jvm.javaVersion.isJava7())
classpath files("$jvm.jre.homeDir/lib/jfxrt.jar")
import javafx.application.*;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
class HelloJavaFXWeb extends Application
@Override public void start(Stage stage) throws Exception
final Group root = new Group();
Scene scene = new Scene(root, Color.DODGERBLUE);
WebView webView = new WebView();
webView.getEngine().load("http://www.google.com");
root.getChildren().add(webView);
stage.setTitle("HelloWorld in JavaFX 2.0");
stage.setScene(scene);
stage.show();
Application.launch(HelloJavaFXWeb.class);
我刚刚注意到它在终止后输出了一些日志记录 (这之前被隐藏了,可能是因为我使用了一个吞噬它的 Gradle 守护进程):
===========性能统计============= 时间/调用次数: com.sun.webpane.perf.WCFontPerfLogger.*: ... com.sun.webpane.perf.WCGraphicsPerfLogger.*: ...
我在 Windows 7 x64 Ultimate 上使用 jdk1.7.0_80_x64/jre/lib/jfxrt.jar
。
在我的计算机上尝试了以下 Java 版本:
+-----------------+-----------+---------+
| version | flashing | logging |
+-----------------+-----------+---------+
| jdk1.7.0_05_x86 | no JavaFX |
| jdk1.7.0_80_x64 | yes | yes |
| jdk1.7.0_80_x86 | yes | no |
| jre1.7.0_80_x86 | yes | no |
| jre1.7.0_80_x64 | yes | no |
| jre1.8.0_45_x86 | no | no |
| jre1.8.0_45_x64 | no | no |
+-----------------+-----------+---------+
【问题讨论】:
让我们continue this discussion in chat。 【参考方案1】:在深入了解jfxrt.jar
几个小时后,在@NwDx 的帮助下反复试验,这里总结了正在发生的事情。
Gradle 构建系统与 JUL 根记录器混淆,并将默认记录级别从原始 INFO
设置为 FINER
。这会激活 JavaFX 运行时内部的许多内部机制。最值得注意的是:
PerfLogger
s 依赖于一些 JUL Logger 级别
许多其他不必要的日志记录,可能是 /dev/null
如果您不小心,可以使用:LogManager.getLogManager().reset()
来修复所有问题。比较细心的患者可以继续阅读。
剪辑区域调试
在com.sun.webpane.sg.prism.WCGraphicsPrismContext
中有一些由log.isLoggable(Level.FINE)
保护的可视化调试代码。
这是一个在这里提交的已知错误:https://bugs.openjdk.java.net/browse/JDK-8096483
查看修复版本:1.8.0u40 之前的任何内容都容易受到这种不需要的可视化调试的影响(参见相关表格)。在 1.8.0u40+ 中,您可以-Dcom.sun.webkit.debugDrawClipShape=true
启用此“功能”。
为了安全起见,值得通过配置 JUL 或以下方式禁用该类的日志记录:
String name = com.sun.webpane.sg.prism.WCGraphicsPrismContext.class.getName();
java.util.logging.Logger.getLogger(name).setLevel(java.util.logging.Level.OFF);
PerfLogger 日志记录
正如问题中提到的,有一些诊断信息被吐出到标准输出。 PerfLogger
checks the FINE
level 也是。这些消息的来源如下:
com.sun.webpane.perf.WCGraphicsPerfLogger
com.sun.webpane.perf.WCFontPerfLogger
com.sun.webpane.platform.Invoker
命名为 Locks
jfxwebkit.dll
中的 TextBreakIteratorJava
通过 LOG_PERF_RECORD 命名为 XXXX
...有人从字面上举了这个例子,为什么? :(
禁用此功能的最简单方法是:
java.util.logging.Logger.getLogger('com.sun.webpane.perf').setLevel(Level.OFF)
因为the package name is hardcoded 或Logger
实例在该包中。
其他一切
可能值得为所有com.sun.*
和javafx.*
软件包提高日志级别(INFO-OFF),以防止进一步的怪异或性能下降。
如需更多信息,请参阅our chat。
【讨论】:
以上是关于为啥JavaFX的WebView是红绿闪烁?的主要内容,如果未能解决你的问题,请参考以下文章
JavaFX WebView:使用loadContent()链接到文档中的锚点不起作用
JavaFX - 如何创建(不可见)WebView 的快照/屏幕截图