JavaFX WebEngine

由 haiguiking 创建,小路依依 最后一次修改 2017-01-09

JavaFX教程 - JavaFX WebEngine


JavaFX提供与HTML5内容互操作的功能。

JavaFX中的底层网页渲染引擎是名为WebKit的流行的开源API。此API用于Apple的Safari浏览器,Amazon的Kindle设备,并在Google的Chrome浏览器中使用。

嵌入式浏览器使您能够在JavaFX应用程序中执行以下任务:

  • 从本地或远程URL呈现HTML
  • 获取网络历史记录
  • 执行JavaScript命令
  • 从JavaScript调用JavaFX
  • 管理网络弹出窗口

WebEngine

JavaFX提供了一个能够加载HTML5内容的非GUI组件,称为WebEngine API(javafx.scene.web.WebEngine)。

这个API基本上是一个WebEngine类的对象实例,用于加载包含HTML5内容的文件。

要加载的HTML5文件可以位于本地文件系统,Web服务器或JAR文件中。

使用Web引擎对象加载文件时,将使用后台线程来加载Web内容,以便它不会阻止JavaFX应用程序线程。

从网址载入

我们可以通过使用WebEngine的load()方法从URL加载Web内容。

WebEngine使用后台线程,坚持基于事件的编程模型。

Web引擎可以从远程Web服务器异步加载Web内容,并在内容加载完成时通知处理程序代码。

以下代码从后台工作线程中的远程Web服务器加载HTML内容。

要监视或确定工作线程是否已完成javafx.beans.value.ChangeListener添加到state属性。

import javafx.application.Application;
import javafx.concurrent.Worker.State;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;

public class Main extends Application {
  public static void main(String[] args) {
    Application.launch(args);
    
  }

  @Override
  public void start(Stage primaryStage) {
    WebEngine webEngine = new WebEngine();
    webEngine.getLoadWorker().stateProperty()
        .addListener((obs, oldValue, newValue) -> {
          if (newValue == State.SUCCEEDED) {
            System.out.println("finished loading");
          }
        }); // addListener()

    // begin loading...
    webEngine.load("http://www.www.w3cschool.cn");

    
    Group root = new Group();
    Scene scene = new Scene(root, 300, 250);

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

以下是所有可能的工作线程状态:

  • READY
  • SCHEDULED
  • RUNNING
  • SUCCEEDED
  • CANCELLED
  • FAILED

加载HTML字符串

我们可以使用WebEngine的loadContent()方法将HTML字符串加载到WebEngine。

Web引擎的loadContent(String htmlText)方法可以加载表示为字符串的HTML内容动态而不必从远程服务器获取内容。

以下代码段加载预先生成的HTML内容:

webEngine.loadContent("<html><body><b>JavaFX</b></body></html>");

HTML DOM内容

Web引擎能够按照基于W3C标准的Java API来将当前页面的文档对象模型(DOM)加载为XML内容。

在Web引擎实例成功加载HTML内容后,可以通过调用Web引擎的getDocument()方法轻松获取XML DOM。

以下代码获取一个Document(org.w3c.dom.Document)实例,假设Web引擎完成加载HTML或XML内容。

import javafx.application.Application;
import javafx.concurrent.Worker.State;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;

public class Main extends Application {
  public static void main(String[] args) {
    Application.launch(args);
    
  }

  @Override
  public void start(Stage primaryStage) {
    WebEngine webEngine = new WebEngine();
    webEngine.getLoadWorker().stateProperty()
        .addListener((obs, oldValue, newValue) -> {
          if (newValue == State.SUCCEEDED) {
            System.out.println("finished loading");
            org.w3c.dom.Document   xmlDom  = webEngine.getDocument();
            System.out.println(xmlDom);
          }
        }); // addListener()

    // begin loading...
    webEngine.load("http://www.www.w3cschool.cn");

    Group root = new Group();
    Scene scene = new Scene(root, 300, 250);

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

以文本字符串的形式获取原始XML数据

以下代码将XML DOM转换为String。

import java.io.StringWriter;

import javafx.application.Application;
import javafx.concurrent.Worker.State;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

public class Main extends Application {
  public static void main(String[] args) {
    Application.launch(args);

  }

  @Override
  public void start(Stage primaryStage) {
    WebEngine webEngine = new WebEngine();
    webEngine
        .getLoadWorker()
        .stateProperty()
        .addListener(
            (obs, oldValue, newValue) -> {
              System.out.println(newValue);
              if (newValue == State.SUCCEEDED) {
                System.out.println("finished loading");
                try {
                  TransformerFactory transformerFactory = TransformerFactory
                      .newInstance();
                  Transformer transformer = transformerFactory.newTransformer();
                  StringWriter stringWriter = new StringWriter();
                  transformer.transform(new DOMSource(webEngine.getDocument()),
                      new StreamResult(stringWriter));
                  String xml = stringWriter.getBuffer().toString();
                  System.out.println(xml);
                } catch (Exception e) {
                  e.printStackTrace();
                }

              }
            }); // addListener()

    // begin loading...
    webEngine.load("http://www.www.w3cschool.cn");

    Group root = new Group();
    Scene scene = new Scene(root, 300, 250);

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

通过JavaScript桥接生成HTML5内容

JavaFX的WebEngine API有一个JavaScript桥梁,允许Java代码调用HTML5内容中的JavaScript函数或脚本代码。

要获取原始HTML5,您需要与JavaScript桥接器交互,以使用Web引擎的executeScript()方法访问Web内容的DOM。

以下代码访问HTML文档(DOM)以从documentElement.outerHTML获取原始内容:

String html  = (String)  webEngine.executeScript("document.documentElement.outerHTML");
import javafx.application.Application;
import javafx.concurrent.Worker.State;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;

public class Main extends Application {
  public static void main(String[] args) {
    Application.launch(args);
  }
  @Override
  public void start(Stage primaryStage) {
    WebEngine webEngine = new WebEngine();
    webEngine
        .getLoadWorker()
        .stateProperty()
        .addListener(
            (obs, oldValue, newValue) -> {
              System.out.println(newValue);
              if (newValue == State.SUCCEEDED) {
                System.out.println("finished loading");
                String html = (String) webEngine
                    .executeScript("document.documentElement.outerHTML");
                System.out.println(html);

              }
            }); 

    webEngine.load("http://www.www.w3cschool.cn");

    Group root = new Group();
    Scene scene = new Scene(root, 300, 250);

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

从Java传递到JavaScript

以下代码显示了如何从Java代码调用JavaScript函数。

假设我们有一个具有以下JavaScript函数的网页

... 
<script>
function  sayHello( msg ) {
    document.getElementById("my_message").innerHTML = msg;
}
</script>
<div id="my_message"></div>

我们可以从Java代码调用该函数webEngine.executeScript(“sayHello("Hi there“);");

从JavaScript传递到Java

JavaFX允许JavaScript代码调用Java代码。

import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;
import jdk.nashorn.api.scripting.JSObject;

public class Main extends Application {
  public static void main(String[] args) {
    Application.launch(args);
  }

  @Override
  public void start(Stage primaryStage) {
    WebEngine webEngine = new WebEngine();
    webEngine.getLoadWorker().stateProperty()
        .addListener((obs, oldValue, newValue) -> {
          if (newValue == Worker.State.SUCCEEDED) {

            JSObject jsobj = (JSObject) webEngine.executeScript("window");
            jsobj.setMember("ABCD", new HelloWorld());
          }
        });

    webEngine.load("http://www.www.w3cschool.cn");

    Group root = new Group();
    Scene scene = new Scene(root, 300, 250);

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

class HelloWorld {
  public String sayGoodbye(String name) {
    return "hi:" + name;
  }
}

JavaScript代码调用Java代码

<script>
function sayGoodbye(name)  {
var  message  = ABCD.sayGoodbye(name);
document.getElementById("my_message").innerHTML = message;
}
</script>

<div  id="my_message"></div>

以上内容是否对您有帮助:
二维码
建议反馈
二维码