ich eine Website auf einem JavaFX WebView Laden und nach eine Weile einen Screenshot mit so etwas wie unter:Wie mache ich JavaFX's Webview rendern, auch wenn es nicht sichtbar ist, weil es in einem anderen Tab ist?
WritableImage image = webView.snapshot(null, null);
Wenn ich an diesem WebView suchen, funktioniert gut, aber wenn es versteckt ist, indem sie in einer Registerkarte, die nicht im Vordergrund ist (ich bin nicht sicher über andere Fälle von es zu verbergen), dann ist der Screenshot der entsprechenden Website, aber völlig leer.
Wie kann ich die WebView zwingen zu rendern, auch wenn nicht sichtbar?
Während dieser Zeit ist webView.isVisible()
wahr.
Ich fand es ein Verfahren in WebView
isTreeReallyVisible()
genannt und enthält zur Zeit:
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;
}
Wenn die WebView, indem sie in einem nicht-Vordergrund Registerkarte ausgeblendet ist, ist impl_isTreeVisible()
false (alle anderen Faktoren in der return-Anweisung sind wahr). Das Verfahren ist auf Node
und sieht wie folgt aus:
/**
* @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;
}
ich impl_treeVisibleProperty()
außer Kraft gesetzt hätte meine eigene Implementierung zur Verfügung zu stellen, aber WebView
ist endgültig, so kann ich nicht von ihm erben.
Eine andere völlig andere Situation als minimiert (ikonifiziert) oder auf einer versteckten Registerkarte ist die Bühne vollständig ausgeblendet (wie in der Taskleiste). In diesem Modus ändert sich die Größe der WebView
nicht, selbst wenn das Rendern möglich ist. Ich rufe webView.resize()
an und mache dann einen Screenshot und der Screenshot hat die passende Größe, aber die tatsächlich gerenderte Seite ist von welcher Größe auch immer die WebView
vorher war.
Debuggen dieses Schlichte Verhalten in gezeigt und versteckten Stufen, fand ich, dass wir schließlich zu Node.addToSceneDirtyList()
erhalten, die enthält:
private void addToSceneDirtyList() {
Scene s = getScene();
if (s != null) {
s.addToDirtyList(this);
if (getSubScene() != null) {
getSubScene().setDirty(this);
}
}
}
Wenn im verborgenen Modus, getScene()
kehren null
, im Gegensatz zu, was passiert, wenn es Show zu sein. Das heißt, dass s.addToDirtyList(this)
nie aufgerufen wird. Ich bin mir nicht sicher, ob dies der Grund ist, warum es nicht richtig skaliert wird.
Hier ist ein Fehler, ein sehr alter, hier: https://bugs.openjdk.java.net/browse/JDK-8087569 aber ich denke nicht, dass das das ganze Problem ist.
Ich mache das mit Java 1.8.0_151. Ich habe versucht 9.0.1 zu sehen, ob es sich anders verhalten würde, da ich weiß, dass WebKit aktualisiert wurde, aber nein, es ist das gleiche.
Ich erinnere mich nicht, wie die Skin für ein Registerkartenfenster implementiert ist, aber es ist möglich, dass sich die Webansicht in dem Szenario, das Sie beschreiben, nicht in einer Szene befindet. In diesem Fall funktioniert der Schnappschuss nicht (Sie können die Web-Ansicht jedoch vorübergehend zu einer Szene hinzufügen, während Sie den Schnappschuss machen). Wenn es immer noch Teil einer Szene ist, habe ich keine Ahnung ... –
@James_D hat keine Ahnung ... Doomsday. – Mordechai
sehen Sie es, wenn seine Hilfe https://stackoverflow.com/questions/40642573/trying-to-render-javafx-webview-to-offs-buffer-or-fbo – AsifAli72090