As mentioned here and here there is no easy way to determine the required height of a webview, until "RT-25005 Automatic preferred sizing of WebView" is implemented.
Are there any workarounds to this issue? I couldn't find a solution in SO or elsewhere. However since i think this is no uncommon problem, there needs to be a workaround. Any idea?
For Webviews
embeded in a stage
I found the following solution (see here):
webView.getEngine().executeScript(
"window.getComputedStyle(document.body, null).getPropertyValue('height')"
);
or
Double.parseDouble(webView.getEngine().executeScript("document.height").toString())
However this doesn't seem to work for Webviews embedded in a treecell, like here. In this case I always get too big numbers as a result.
Minimal running example (including recommendation of jewelsea
):
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.util.Callback;
import org.w3c.dom.Document;
public class TableViewSampleHTML extends Application {
private final ObservableList<MyData> data = FXCollections.observableArrayList(new MyData(1L), new MyData(3L), new MyData(2L), new MyData(4L), new MyData(1L));
public static void main(final String[] args) {
launch(args);
}
@Override
public void start(final Stage stage) {
final Scene scene = new Scene(new Group());
TableView<MyData> table = new TableView<>();
table.setPrefHeight(700);
final TableColumn<MyData, Long> nameCol = new TableColumn("So So");
nameCol.setMinWidth(200);
nameCol.setCellValueFactory(new PropertyValueFactory<>("i"));
// Allow to display Textflow in Column
nameCol.setCellFactory(new Callback<TableColumn<MyData, Long>, TableCell<MyData, Long>>() {
@Override
public TableCell<MyData, Long> call(TableColumn<MyData, Long> column) {
return new TableCell<MyData, Long>() {
@Override
protected void updateItem(Long item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
setGraphic(null);
setStyle("");
} else {
WebView webview = new WebView();
webview.setPrefWidth(700.0);
WebEngine engine = webview.getEngine();
String textHTML = new String(new char[item.intValue()]).replace("", " <b> bold </b> normal, ");
// textHTML = "<body>"
// + textHTML + "</body>";
engine.loadContent(textHTML);
setGraphic(webview);
engine.documentProperty().addListener((obj, prev, newv) -> {
String heightText = engine.executeScript(
"window.getComputedStyle(document.body, null).getPropertyValue('height')"
).toString();
System.out.println("heighttext: " + heightText);
webview.setPrefHeight(Double.parseDouble(heightText.replace("px", "")));
this.setPrefHeight(Double.parseDouble(heightText.replace("px", "")));
setGraphic(webview);
});
}
}
};
}
});
table.setItems(data);
table.getColumns().addAll(nameCol);
((Group) scene.getRoot()).getChildren().addAll(table);
stage.setScene(scene);
stage.show();
}
public static class MyData {
private Long i;
public MyData(Long i) {
this.i = i;
}
public Long getI() {
return i;
}
}
}
Now the outout is
heighttext: 581px
heighttext: 581px
However these values seem to be too big. See screeenshot:
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…