Ваше утверждение, что вы не можете сделать снимок скрытых элементов, неверно. Вы можете даже захватить, если он не находится в сцене (если свойство visible явно не установлено в false). Просмотр веб-страниц по какой-то причине является здесь исключением, и в этом проблема.

ружаю веб-сайт в JavaFX WebView и послекакое-то время сделать скриншот с чем-то вроде:

WritableImage image = webView.snapshot(null, null);

Если я смотрю на этот 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;
}

Когда WebView скрыт, находясь на вкладке без переднего плана,impl_isTreeVisible() ложно (все остальные факторы в операторе возврата верны). Этот метод включен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;
}

Я мог бы переопределить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);
        }
    }
}

В скрытом режимеgetScene() возвращаетсяnullВ отличие от того, что происходит, когда это показывают. Это означает, чтоs.addToDirtyList(this) никогда не называется. Я не уверен, является ли это причиной того, что размер не был должным образом изменен.

Здесь есть ошибка, очень старая, здесь:https://bugs.openjdk.java.net/browse/JDK-8087569 но я не думаю, что это весь вопрос.

Я делаю это с Java 1.8.0_151. Я попробовал 9.0.1, чтобы увидеть, будет ли он вести себя по-другому, так как я понимаю, что WebKit был обновлен, но нет, это то же самое.

Ответы на вопрос(3)

Ваш ответ на вопрос