正确调整嵌入在Tabelcell中的Webview的大小
正如这里和这里所提到的,在实现“RT-25005自动优先选择WebView大小”之前,没有简单的方法来确定Web视图的所需高度。
有没有解决这个问题的办法? 我在SO或其他地方找不到解决方案。 但是,因为我认为这不是一个罕见的问题,所以需要有一个解决方法。 任何想法?
  对于嵌入在一个stage Webviews ,我找到了以下解决方案(请参阅此处): 
webView.getEngine().executeScript(
    "window.getComputedStyle(document.body, null).getPropertyValue('height')"
);
要么
Double.parseDouble(webView.getEngine().executeScript("document.height").toString())
但是,这似乎不适用于嵌入在树形结构中的Webviews,就像这里一样。 在这种情况下,我总是会得到太多的数字。
  最小的运行示例(包括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;
        }
    }
}
现在,外面是
heighttext: 581px
heighttext: 581px
但是,这些价值观似乎太大了。 请参阅screeenshot:

已经取得了一些进展,现在可以更真实地计算单元高度。 请参阅下面的相关代码。
相关变化:
webview.setPrefHeight(-1);  在执行jevascript之前。 开放点:
+ 15.0 。  这是一个黑客。  似乎有些额外的长度必须考虑在某个地方。   重新调整色谱柱后重新计算的功能并不理想。  使用table.refresh()会导致渲染显着延迟。 
public class TableViewSampleHTML extends Application {
private final ObservableList<MyData> data = FXCollections.observableArrayList(new MyData(1L), new MyData(14L), new MyData(2L), new MyData(3L), new MyData(15L));
public static void main(final String[] args) {
    launch(args);
}
@Override
public void start(final Stage stage) {
    final Scene scene = new Scene(new Group(), 400, 800);
    TableView<MyData> table = new TableView<>();
    table.setPrefWidth(400);
    table.setPrefHeight(800);
    final TableColumn<MyData, Long> nameCol = new TableColumn("So So");
    final TableColumn<MyData, Long> col2 = new TableColumn("la la");
    nameCol.setPrefWidth(200);
    col2.setCellValueFactory(new PropertyValueFactory<>("i"));
    nameCol.setCellValueFactory(new PropertyValueFactory<>("i"));
    nameCol.widthProperty().addListener((ob,oldV,newV) -> {table.refresh();} );
    // 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();
                        WebEngine engine = webview.getEngine();
                        webview.setPrefHeight(-1);   // <- Absolute must at this position (before calling the Javascript)
                        setGraphic(webview);
                        String textHTML = new String(new char[item.intValue()]).replace(" ", " <b> bold </b> normal, ");
                        textHTML = "<body>" 
                                + textHTML + "</body>";
                        engine.loadContent(textHTML);
                        engine.documentProperty().addListener((obj, prev, newv) -> {
                        String heightText = engine.executeScript(   // <- Some modification, which gives moreless the same result than the original
                                "var body = document.body,"
                                + "html = document.documentElement;"
                                + "Math.max( body.scrollHeight , body.offsetHeight, "
                                + "html.clientHeight, html.scrollHeight , html.offsetHeight );"
                        ).toString();
                        System.out.println("heighttext: " + heightText);
                        Double height = Double.parseDouble(heightText.replace("px", "")) + 15.0;  // <- Why are this 15.0 required??
                        webview.setPrefHeight(height);
                        this.setPrefHeight(height);
                        });
                    }
                }
            };
        }
    });
    table.setItems(data);
    table.getColumns().addAll(nameCol);
    table.getColumns().addAll(col2);
    ((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;
    }
}
}
输出现在看起来像:

  从您链接的示例(JavaFX webview,获取文档高度),文档的高度在文档上的ChangeListener进行计算: 
engine.documentProperty().addListener((prop, oldDoc, newDoc) -> {
    String heightText = engine.executeScript(
            "window.getComputedStyle(document.body, null).getPropertyValue('height')"
    ).toString();
    System.out.println("heighttext: " + heightText);
});
输出:
heighttext: 36px
heighttext: 581px
heighttext: 581px
在你的问题的代码中,你没有执行基于ChangeListener的高度检查。 因此,在文档加载之前查询WebView文档的高度(这就是为什么它会为您的代码返回零)。
Basedon BerndGirt的答案。
public class WebviewCellFactory<S,T> implements Callback<TableColumn<S,T>, TableCell<S,T>> {
    @Override
    public TableCell<S, T> call(TableColumn<S, T> column) {
        return new TableCell<S, T>() {
            @Override
            protected void updateItem(T item, boolean empty) {
                super.updateItem(item, empty);
                if (item == null || empty) {
                    setText(null);
                    setGraphic(null);
                    setStyle("");
                } else {
                    WebView webview = new WebView();
                    WebEngine engine = webview.getEngine();
                    webview.setPrefHeight(-1);   // <- Absolute must at this position (before calling the Javascript)
                    webview.setBlendMode(BlendMode.DARKEN);
                    setGraphic(webview);
                    engine.loadContent("<body topmargin=0 leftmargin=0 style="background-color: transparent;">"+item+"</body>");
                    engine.documentProperty().addListener((obj, prev, newv) -> {
                        String heightText = engine.executeScript(   // <- Some modification, which gives moreless the same result than the original
                                "var body = document.body,"
                                        + "html = document.documentElement;"
                                        + "Math.max( body.scrollHeight , body.offsetHeight, "
                                        + "html.clientHeight, html.scrollHeight , html.offsetHeight );"
                        ).toString();
                        Double height = Double.parseDouble(heightText.replace("px", "")) + 10 ;  // <- Why are this 15.0 required??
                        webview.setPrefHeight(height);
                        this.setPrefHeight(height);
                    });
                }
            }
        };
    }
}
那么你只需要设置
tableColumn.setCellFactory(new WebviewCellFactory());
如果有任何错误,请告诉我。
链接地址: http://www.djcxy.com/p/38827.html