Size Javafx Webview To The Minimum Size Needed By The Document Body
Solution 1:
Automated sizing support of WebView is covered by a feature request in the JavaFX issue tracker:
The feature request has currently not been implemented or scheduled for implementation. You can vote for or comment on the feature request.
There is no work-around that I know of. Earlier version of WebView seemed to work with the following code engine.executeScript("document.width")
and engine.executeScript("document.height")
. But these commands no longer worked last time I tried them.
Solution 2:
Until automatic preferred sizing is implemented, a certain blogmeister has come up with a solution that seems to work (for now).
It can be found in its original form on his website.
It makes having a preferred-size WebView
as easy as
WebViewFitContent webViewFitContent = new WebViewFitContent(html);
yourContainer.getChildren().add(webViewFitContent);
In case the link were to ever die,
WebViewFitContent.java
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ListChangeListener;
import javafx.concurrent.Worker.State;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.layout.Region;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import netscape.javascript.JSException;
import java.util.Set;
public final classWebViewFitContentextendsRegion {
final WebView webview = newWebView();
final WebEngine webEngine = webview.getEngine();
publicWebViewFitContent(String content) {
webview.setPrefHeight(5);
widthProperty().addListener(newChangeListener<Object>() {
@Overridepublicvoidchanged(ObservableValue<?> observable, Object oldValue, Object newValue) {
Double width = (Double)newValue;
webview.setPrefWidth(width);
adjustHeight();
}
});
webview.getEngine().getLoadWorker().stateProperty().addListener(newChangeListener<State>() {
@Overridepublicvoidchanged(ObservableValue<? extends State> arg0, State oldState, State newState) {
if (newState == State.SUCCEEDED) {
adjustHeight();
}
}
});
webview.getChildrenUnmodifiable().addListener(newListChangeListener<Node>() {
@OverridepublicvoidonChanged(ListChangeListener.Change<? extends Node> change) {
Set<Node> scrolls = webview.lookupAll(".scroll-bar");
for (Node scroll : scrolls) {
scroll.setVisible(false);
}
}
});
setContent(content);
getChildren().add(webview);
}
publicvoidsetContent(final String content) {
Platform.runLater(newRunnable(){
@Overridepublicvoidrun() {
webEngine.loadContent(getHtml(content));
Platform.runLater(newRunnable(){
@Overridepublicvoidrun() {
adjustHeight();
}
});
}
});
}
@OverrideprotectedvoidlayoutChildren() {
double w = getWidth();
double h = getHeight();
layoutInArea(webview,0,0,w,h,0, HPos.CENTER, VPos.CENTER);
}
privatevoidadjustHeight() {
Platform.runLater(newRunnable(){
@Overridepublicvoidrun() {
try {
Object result = webEngine.executeScript(
"var myDiv = document.getElementById('mydiv');" +
"if (myDiv != null) myDiv.offsetHeight");
if (result instanceofInteger) {
Integer i = (Integer) result;
double height = newDouble(i);
height = height + 20;
webview.setPrefHeight(height);
}
} catch (JSException e) {
e.printStackTrace();
}
}
});
}
privateStringgetHtml(String content) {
return"<html><body>" +
"<div id=\"mydiv\">" + content + "</div>" +
"</body></html>";
}
}
Note 1: In the above I added a null-check in the javascript and chose to print out any exceptions that might occur instead of ignoring them.
Note 2: Sometimes the WebView
's content doesn't show through. If anyone else experiences this please leave a comment.
Solution 3:
This is a very late answer.
You have to apply ChangeListener on the document, before calulating the height. Kindly find a running example to your question at: Correct sizing of Webview embedded in Tabelcell
However my experience is that the high is still sometimes to big.
Post a Comment for "Size Javafx Webview To The Minimum Size Needed By The Document Body"