将JavaFX WebView的大小调整为文档正文所需的最小大小

时间:2014-09-14 23:19:48

标签: java javascript webview javafx

我正在JavaFX中为我的项目编写自定义对话框。我需要一种变体但快速模式来显示对话框内容。

我知道controlsFX;实际上我正在使用它,但我想在WebView中显示内容,以便它更易于控制。

问题在于WebView的大小我想找到文档正文的高度,并将WebView的大小设置为。

我尝试了下面的javascript hack但是在显示对话框之前我得到0的大小并且在显示对话框后值不可靠。有没有更好的解决方案,或者我应该忘记它并尝试嵌入支持HTML 3的swing组件?

    WebView vw = new WebView();
    vw.getEngine().loadContent("<p>This is my text</p><b>Another</b><p> This is a paragraph</p><ul><li>First cause</li><li>Second cause></li></ul>");
    vw.setPrefSize(500, 50);
    vw.setOnMouseClicked(new EventHandler<MouseEvent>() {

        @Override
        public void handle(MouseEvent event) {
            // I see that executeScript doesn't work correctly even when the WebView is loaded
            Integer h = (Integer) vw.getEngine().executeScript("document.body.offsetHeight");
            System.out.println("scriptRES: " + h );
            vw.setPrefSize(400, h);
            vw.setMinSize(400, h);
            vw.setMaxSize(400, h);
        }
    });

3 个答案:

答案 0 :(得分:2)

JavaFX问题跟踪器中的功能请求涵盖了WebView的自动调整大小支持:

功能请求目前尚未实施或计划实施。您可以对功能请求进行投票或评论。

我知道没有解决方法。早期版本的WebView似乎可以使用以下代码engine.executeScript("document.width")engine.executeScript("document.height")。但是这些命令在我上次尝试时不再有效。

答案 1 :(得分:0)

在实施自动首选大小调整之前,某个博客主管已经提出了一个似乎有效的解决方案( for now )。

可以在his website上找到原始格式。

它使首选大小data变得如

一样简单
WebView

WebViewFitContent in action

如果链接永远死亡,

WebViewFitContent.java

WebViewFitContent webViewFitContent = new WebViewFitContent(html);
yourContainer.getChildren().add(webViewFitContent);

注1:在上面我在javascript中添加了一个空检查,并选择打印出可能发生的任何异常,而不是忽略它们。

注意2:有时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 class WebViewFitContent extends Region { final WebView webview = new WebView(); final WebEngine webEngine = webview.getEngine(); public WebViewFitContent(String content) { webview.setPrefHeight(5); widthProperty().addListener(new ChangeListener<Object>() { @Override public void changed(ObservableValue<?> observable, Object oldValue, Object newValue) { Double width = (Double)newValue; webview.setPrefWidth(width); adjustHeight(); } }); webview.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>() { @Override public void changed(ObservableValue<? extends State> arg0, State oldState, State newState) { if (newState == State.SUCCEEDED) { adjustHeight(); } } }); webview.getChildrenUnmodifiable().addListener(new ListChangeListener<Node>() { @Override public void onChanged(ListChangeListener.Change<? extends Node> change) { Set<Node> scrolls = webview.lookupAll(".scroll-bar"); for (Node scroll : scrolls) { scroll.setVisible(false); } } }); setContent(content); getChildren().add(webview); } public void setContent(final String content) { Platform.runLater(new Runnable(){ @Override public void run() { webEngine.loadContent(getHtml(content)); Platform.runLater(new Runnable(){ @Override public void run() { adjustHeight(); } }); } }); } @Override protected void layoutChildren() { double w = getWidth(); double h = getHeight(); layoutInArea(webview,0,0,w,h,0, HPos.CENTER, VPos.CENTER); } private void adjustHeight() { Platform.runLater(new Runnable(){ @Override public void run() { try { Object result = webEngine.executeScript( "var myDiv = document.getElementById('mydiv');" + "if (myDiv != null) myDiv.offsetHeight"); if (result instanceof Integer) { Integer i = (Integer) result; double height = new Double(i); height = height + 20; webview.setPrefHeight(height); } } catch (JSException e) { e.printStackTrace(); } } }); } private String getHtml(String content) { return "<html><body>" + "<div id=\"mydiv\">" + content + "</div>" + "</body></html>"; } } 的内容无法显示。如果有其他人遇到此问题,请发表评论。

答案 2 :(得分:-1)

这是一个非常晚的答案。

在计算高度之前,您必须在文档上应用ChangeListener。 请在Correct sizing of Webview embedded in Tabelcell

找到问题的示例

然而,我的经验是,有时仍然很高。