为什么JavaFX的WebView会闪烁红色和绿色?

TWi*_*Rob 5 java groovy javafx webview gradle

我刚刚开始使用JavaFX,我想将一个WebView放入一个Wi​​ndow:

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);
Run Code Online (Sandbox Code Playgroud)

它看起来如此简单,但出于某种原因,当移动鼠标时,绘制区域会以红色和绿色突出显示.如何禁用闪烁的颜色?

将鼠标移到WebView上

更新:问题在于Groovy/Gradle交互

这是一个非常极小的repro
(将所有这些放入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);
Run Code Online (Sandbox Code Playgroud)

我只是注意到它在终止后输出了一些日志记录
(这之前是隐藏的,可能是因为我使用了吞下它的Gradle守护进程):

===========性能统计=============
时间/调用次数:
com.sun.webpane.perf.WCFontPerfLogger.*:...
com.sun. webpane.perf.WCGraphicsPerfLogger.*:...

jdk1.7.0_80_x64/jre/lib/jfxrt.jar在Windows 7 x64 Ultimate上使用.

尝试了我的计算机上的以下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      |
+-----------------+-----------+---------+
Run Code Online (Sandbox Code Playgroud)

TWi*_*Rob 2

经过几个小时的深入研究jfxrt.jar、反复试验,并在 @NwDx 的帮助下,这里总结了正在发生的事情。

Gradle 构建系统与 JUL 根记录器混在一起,并将默认日志记录级别设置为FINER原始INFO. 这会激活 JavaFX 运行时内的许多内部机制。最为显着地:

  • 剪辑区域调试依赖于 JUL Logger
  • PerfLoggers 取决于某些 JUL 记录器级别
  • 许多其他不必要的日志记录,可能到 /dev/null

如果你不小心,你可以使用:LogManager.getLogManager().reset()来修复所有问题。细心的患者可以继续阅读。

剪辑区域调试

有一些由log.isLoggable(Level.FINE)in保护的可视化调试代码com.sun.webpane.sg.prism.WCGraphicsPrismContext

这是此处提交的已知错误: 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);
Run Code Online (Sandbox Code Playgroud)

PerfLogger 日志记录

正如问题中提到的,有一些诊断信息被吐出到标准输出。还要PerfLogger检查FINE级别。这些消息的来源如下:

  • com.sun.webpane.perf.WCGraphicsPerfLogger
  • com.sun.webpane.perf.WCFontPerfLogger
  • com.sun.webpane.platform.Invoker命名的Locks
  • TextBreakIteratorJavainjfxwebkit.dllXXXX通过LOG_PERF_RECORD
    命名的 ...有人从字面上理解了这个例子,为什么?:(

禁用此功能的最简单方法是:

java.util.logging.Logger.getLogger('com.sun.webpane.perf').setLevel(Level.OFF)
Run Code Online (Sandbox Code Playgroud)

因为包名称是硬编码的或者Logger实例位于该包中。

其他一切

可能值得为所有包com.sun.*javafx.*包提高日志级别(INFO-OFF),以防止进一步的怪异或性能下降。

欲了解更多信息,请参阅我们的聊天