即使由于位于另一个选项卡中而不可见,我如何使JavaFX的webview渲染?

pup*_*eno 12 java javafx webview

我正在JavaFX WebView上加载一个网站,过了一段时间用以下内容截取屏幕截图:

WritableImage image = webView.snapshot(null, null);
Run Code Online (Sandbox Code Playgroud)

如果我正在查看工作正常的WebView,但如果它被隐藏在不在前台的选项卡中(我不确定隐藏它的其他情况),那么,截图是适当的网站,但完全空白.

即使不可见,如何强制WebView呈现?

在这段时间里,webView.isVisible()是真的.

我发现有一个WebView被调用的方法isTreeReallyVisible(),目前它包含:

private boolean isTreeReallyVisible() {
    if (getScene() == null) {
        return false;
    }

    final Window window = getScene().getWindow();

    if (window == null) {
        return false;
    }

    boolean iconified = (window instanceof Stage) ? ((Stage)window).isIconified() : false;

    return impl_isTreeVisible()
           && window.isShowing()
           && window.getWidth() > 0
           && window.getHeight() > 0
           && !iconified;
}
Run Code Online (Sandbox Code Playgroud)

当WebView被非前景选项卡隐藏时,它impl_isTreeVisible()是false(return语句中的所有其他因素都为true).该方法已启用Node,如下所示:

/**
 * @treatAsPrivate implementation detail
 * @deprecated This is an internal API that is not intended for use and will be removed in the next version
 */
@Deprecated
public final boolean impl_isTreeVisible() {
    return impl_treeVisibleProperty().get();
}

/**
 * @treatAsPrivate implementation detail
 * @deprecated This is an internal API that is not intended for use and will be removed in the next version
 */
@Deprecated
protected final BooleanExpression impl_treeVisibleProperty() {
    if (treeVisibleRO == null) {
        treeVisibleRO = new TreeVisiblePropertyReadOnly();
    }
    return treeVisibleRO;
}
Run Code Online (Sandbox Code Playgroud)

我可以覆盖impl_treeVisibleProperty()提供我自己的实现,但是WebView是最终的,所以,我不能继承它.

最小化(图标化)或隐藏选项卡上的另一个完全不同的情况是让舞台完全隐藏(如在托盘栏中运行).在该模式下,即使我可以进行渲染,WebView也不会调整大小.我调用webView.resize()然后截取屏幕截图,屏幕截图的大小合适,但实际呈现的页面大小与WebView以前一样.

在显示和隐藏的阶段调试这个大小调整行为,我发现最终我们得到的Node.addToSceneDirtyList()包含:

private void addToSceneDirtyList() {
    Scene s = getScene();
    if (s != null) {
        s.addToDirtyList(this);
        if (getSubScene() != null) {
            getSubScene().setDirty(this);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在隐藏模式下,getScene()返回时null,与正在显示时发生的情况不同.这意味着s.addToDirtyList(this)永远不会被召唤.我不确定这是不是因为它没有得到适当调整大小的原因.

有一个关于这个的错误,一个非常古老的错误,在这里:https://bugs.openjdk.java.net/browse/JDK-8087569,但我不认为这是整个问题.

我正在使用Java 1.8.0_151这样做.我尝试了9.0.1以查看它是否会表现不同,因为我理解WebKit已升级,但不是,它是相同的.

Ada*_*lík -1

我会考虑使用以下命令在适当的时候重新加载页面:

webView.getEngine().reload();
Run Code Online (Sandbox Code Playgroud)

还尝试更改SnapshotParameters方法中的参数snapShot

如果它不起作用,那么我会考虑在屏幕上渲染 WebView 时将 Image 存储在内存中。