Добавить текст WebEngine - JavaFX

Как я могу добавить текст в webengine? Я пробовал это:

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);
}

Но документ null


person Lukasz    schedule 05.12.2012    source источник


Ответы (3)


Вы также можете использовать JavaScript для добавления.

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!'));"
   );
 }
});

Иногда мне кажется, что для управления DOM проще использовать jQuery, чем Java Document или собственные интерфейсы DOM JavaScript.

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 + "});"
  );
}

Независимо от того, используете ли вы API-интерфейс Java Document, как это делает Улук, или API-интерфейсы JavaScript или JQuery, все остальные пункты в превосходном ответе Улука по-прежнему применимы.

person jewelsea    schedule 05.12.2012
comment
эй, как насчет того, если я хочу удалить несколько изображений внешнего вида веб-сайта с помощью jquery этого веб-движка (javafx), не могли бы вы поделиться руководством @jewelsea.... - person gumuruh; 19.02.2017

Во-первых, Document возвращает null, если webengine не может загрузить контент или вы вызываете engine.getDocument() до того, как контент полностью завершит загрузку.

Во-вторых, doc.getElementById("body") ищет элемент DOM с идентификатором «body». Однако загруженный вами контент не имеет такого идентификатора или вообще какого-либо идентификатора.

Чтобы лучше понять это, вот полный работающий пример, нажмите на кнопку:

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);
    }
}

Обратите внимание, что я поместил div с id=content в тело, поэтому doc.getElementById("content") возвращает этот div.

person Uluk Biy    schedule 05.12.2012

Хотя ответ очень старый и уже принят, я помещаю здесь свои выводы.

Хитрость заключалась в том, чтобы вызвать engine.loadContent в методе инициализации контроллера, а затем попытаться добавить содержимое в какое-либо действие, как указано в примере btn.setOnAction(). Таким образом, когда вы запустили действие, страница уже была загружена. Если я помещаю код для загрузки в сам setOnAction(), я получаю документ как нулевой.

person ashah    schedule 06.02.2018