Append text WebEngine - JavaFX

倾然丶 夕夏残阳落幕 提交于 2019-12-09 00:56:03

问题


How can I append text to webengine? I tried this:

public TabMessage(String title) {
    super(title);
    view = new WebView();
    engine = view.getEngine();
    engine.loadContent("<body></body>");
    view.setPrefHeight(240);
}

private void append(String msg){
    Document doc = engine.getDocument();
    Element el = doc.getElementById("body");
    String s = el.getTextContent();
    el.setTextContent(s+msg);
}

But document is null


回答1:


You can also use JavaScript to do the append.

final WebEngine appendEngine = view.getEngine();
btn.setOnAction(new EventHandler<ActionEvent>() {
 @Override public void handle(ActionEvent event) {
   appendEngine.executeScript(
     "document.getElementById('content').appendChild(document.createTextNode('World!'));"
   );
 }
});

I sometimes find it simpler to use jQuery to manipulate the DOM rather than the Java Document or native JavaScript DOM interfaces.

final WebEngine appendEngine = view.getEngine();
btn.setOnAction(new EventHandler<ActionEvent>() {
 @Override public void handle(ActionEvent event) {
   executejQuery(appendEngine, "$('#content').append('World!');");
 }
});

...

private static Object executejQuery(final WebEngine engine, String script) {
  return engine.executeScript(
    "(function(window, document, version, callback) { "
    + "var j, d;"
    + "var loaded = false;"
    + "if (!(j = window.jQuery) || version > j.fn.jquery || callback(j, loaded)) {"
    + " var script = document.createElement(\"script\");"
    + " script.type = \"text/javascript\";"
    + " script.src = \"http://code.jquery.com/jquery-1.7.2.min.js\";"
    + " script.onload = script.onreadystatechange = function() {"
    + " if (!loaded && (!(d = this.readyState) || d == \"loaded\" || d == \"complete\")) {"
    + " callback((j = window.jQuery).noConflict(1), loaded = true);"
    + " j(script).remove();"
    + " }"
    + " };"
    + " document.documentElement.childNodes[0].appendChild(script) "
    + "} "
    + "})(window, document, \"1.7.2\", function($, jquery_loaded) {" + script + "});"
  );
}

Whether you use the Java Document API, as Uluk has, or JavaScript or JQuery APIs, all of the other points in Uluk's excellent answer still apply.




回答2:


First, Document returns null if webengine fails to load the content or you call engine.getDocument() before the content is fully finished its loading.

Second, doc.getElementById("body") searches for the DOM element with id "body". However the loaded content by you has no such id or any id at all.

To understand these better here is a complete runnable example, click on the button:

package demo;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class Demo extends Application {

    private WebView view;
    private WebEngine engine;

    @Override
    public void start(Stage primaryStage) {

        view = new WebView();
        engine = view.getEngine();
        engine.loadContent("<body><div id='content'>Hello </div></body>");
        view.setPrefHeight(240);

        Button btn = new Button("Append the \"World!\"");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                append(" \"World!\"");
            }
        });

        StackPane root = new StackPane();
        root.getChildren().addAll(view, btn);
        Scene scene = new Scene(root, 300, 250);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void append(String msg) {
        Document doc = engine.getDocument();
        Element el = doc.getElementById("content");
        String s = el.getTextContent();
        el.setTextContent(s + msg);
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Note that I have put a div with id=content in th body so doc.getElementById("content") returns that div.




回答3:


Though answer is very old and already accepted, I am putting my finding here.

The trick was to call engine.loadContent in init method of controller and then try to append content on some action like mentioned in example btn.setOnAction(). This way when you have action fired, the page was already loaded. If I put code for loading in setOnAction() itself, I get document as null.



来源:https://stackoverflow.com/questions/13719669/append-text-webengine-javafx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!