【问题标题】:Why Document is null even after loadContent(...)? - (WebView JavaFx)为什么即使在 loadContent(...) 之后 Document 仍为空? - (WebView JavaFx)
【发布时间】:2015-12-17 03:51:54
【问题描述】:

下面是MainController类initialize(...)方法的简单代码:

WebEngine webEngine = webView.getEngine();
webEngine.loadContent("<h1>hello</h1>"); // Successfully loaded on form
Document doc = webEngine.getDocument(); // null 

为什么 docnull 以及如何修复它?

【问题讨论】:

  • 好吧,我试过了,并用一个简单的“Platform.runLater(() -> {Document doc = webEngine.getDocument();}”解决了它现在,这是我找到的快速解决方案,可能还有别的东西
  • 用 loadContent() 解决问题,但不能用 load(url) 方法解决。我不明白为什么其他人没有这个问题......
  • 如文档 docs.oracle.com/javafx/2/api/javafx/scene/web/WebEngine.html 中所述,您应该为 loadworker 添加一个监听器,因为加载可能需要一些时间。

标签: java webview javafx


【解决方案1】:

正如我所评论的,您应该添加一个侦听器,因为加载需要时间,以便在内容成功加载后执行:

final WebView webView = new WebView();
final WebEngine webEngine = webView.getEngine();
webEngine.getLoadWorker().stateProperty().addListener((observable, oldState, newState) -> {
    if (newState == State.SUCCEEDED) {
        Document doc = webEngine.getDocument();
    }
});
webEngine.loadContent("<h1>hello</h1>");
//webEngine.load("http://google.ch"); // This works too

【讨论】:

    【解决方案2】:

    有时,即使在成功加载后,引擎也会将文档设置为 null。 这通常发生在更复杂的网页上。

    确保文档不为空的更可靠方法是使用属性侦听器。

    import javafx.scene.web.WebEngine;
    import javafx.scene.web.WebView;
    import org.w3c.dom.Document;
    
    class MyClass {
    
        private WebView view = new WebView();
        private WebEngine engine = view.getEngine();
        private Document document;
    
        MyClass() {
            engine.documentProperty().addListener((v, o, n) -> {
                if (n != null) {
                    document = n;
                }
            });
        }
    }
    

    【讨论】:

      【解决方案3】:

      我已经浪费了很多时间来解决这个问题。 这是我的简单示例,通过单击按钮在警报窗口中显示来自 textarea 的文本:

      index.html

      <!-- ... -->
      <textarea id="inputText" rows="5" placeholder="Enter text"></textarea>
      <!-- ... -->
      <button id="goButton">Go!</button>
      <!-- ... -->
      

      MainController.java

      public class MainController implements Initializable {
          @FXML private WebView webDoc;
      
          public void initialize(URL location, ResourceBundle resources) {
              final WebEngine webEngine = webDoc.getEngine();
              String url = this.getClass().getResource("/html/main.html").toExternalForm();
      
              webEngine.load(url);
              webEngine.getLoadWorker().stateProperty().addListener((observable, oldState, newState) -> {
                  if (newState == Worker.State.SUCCEEDED) {
      
                      final Document doc = webEngine.getDocument();
      
                      EventTarget button = (EventTarget) doc.getElementById("goButton");
      
                      button.addEventListener("click", evt -> {
                          HTMLTextAreaElement textField = (HTMLTextAreaElement) doc.getElementById("inputText");
                          alert(textField.getValue());
                      }, false);
                  }
              });
          }
      
          private void alert(String text) {
              Alert alert = new Alert(Alert.AlertType.CONFIRMATION, text);
              alert.showAndWait();
          }
      }
      

      Main.java

      public class Main extends Application {
      
          public static void main(String[] args) throws Exception {
              launch(args);
          }
      
          @Override
          public void start(Stage stage) throws Exception {
              Scene scene = gecSceneFromXml("/fxml/main.fxml");
      
              stage.setTitle("New window");
              stage.setScene(scene);
      
              stage.show();
          }
      
          private Scene gecSceneFromXml(String fileName) throws java.io.IOException {
              FXMLLoader loader = new FXMLLoader();
              Parent root = loader.load(getClass().getResourceAsStream(fileName));
              return new Scene(root);
          }
      }
      

      main.fxml

      <AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400" prefWidth="500" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainController">
         <children>
            <WebView fx:id="webDoc" maxHeight="-Infinity" maxWidth="-Infinity"  prefHeight="400.0" prefWidth="500.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
         </children>
      </AnchorPane>
      

      【讨论】:

      • 这不正是@Psychokiller1888 给你的解决方案吗?您应该将该答案标记为正确。
      • 我只是举了我的完整例子。我不明白为什么人们认为“这个答案没有用”((
      • 因为你只是抄袭了现有的答案。您提供的其他材料都不是原始问题的一部分,因此它并没有真正添加任何内容。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-26
      • 2019-03-03
      • 1970-01-01
      • 2014-11-03
      • 2015-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多