JavaFX WebEngine

2020-10-21 15:38 更新

JavaFX教程 - JavaFX WebEngine


JavaFX 提供與 HTML5 內(nèi)容互操作的功能。

JavaFX 中的底層網(wǎng)頁渲染引擎是名為 WebKit 的流行的開源API。此 API 用于 Apple 的 Safari 瀏覽器,Amazon 的 Kindle 設(shè)備,并在 Google 的 Chrome 瀏覽器中使用。

嵌入式瀏覽器使您能夠在 JavaFX 應(yīng)用程序中執(zhí)行以下任務(wù):

  • 從本地或遠(yuǎn)程 ?URL? 呈現(xiàn) HTML
  • 獲取網(wǎng)絡(luò)歷史記錄
  • 執(zhí)行 ?JavaScript ?命令
  • 從? JavaScript? 調(diào)用 ?JavaFX?
  • 管理網(wǎng)絡(luò)彈出窗口

WebEngine

JavaFX 提供了一個(gè)能夠加載 HTML5 內(nèi)容的非 GUI 組件,稱為 ?WebEngine API?(?javafx.scene.web.WebEngine?)。

這個(gè) API 基本上是一個(gè) ?WebEngine ?類的對象實(shí)例,用于加載包含 HTML5 內(nèi)容的文件。

要加載的 HTML5 文件可以位于本地文件系統(tǒng),Web 服務(wù)器或 JAR 文件中。

使用 Web 引擎對象加載文件時(shí),將使用后臺(tái)線程來加載 Web 內(nèi)容,以便它不會(huì)阻止 JavaFX 應(yīng)用程序線程。

從網(wǎng)址載入

我們可以通過使用 ?WebEngine?的?load()?方法從 ?URL ?加載 Web 內(nèi)容。

?WebEngine? 使用后臺(tái)線程,堅(jiān)持基于事件的編程模型。

Web 引擎可以從遠(yuǎn)程 Web 服務(wù)器異步加載 Web 內(nèi)容,并在內(nèi)容加載完成時(shí)通知處理程序代碼。

以下代碼從后臺(tái)工作線程中的遠(yuǎn)程 Web 服務(wù)器加載 HTML 內(nèi)容。

要監(jiān)視或確定工作線程是否已完成 ?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.o2fo.com");

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

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

以下是所有可能的工作線程狀態(tài):

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

加載HTML字符串

我們可以使用?WebEngine?的?loadContent()?方法將 HTML 字符串加載到?WebEngine?。

Web 引擎的 ?loadContent?(?String htmlText?) 方法可以加載表示為字符串的 HTML 內(nèi)容動(dòng)態(tài)而不必從遠(yuǎn)程服務(wù)器獲取內(nèi)容。

以下代碼段加載預(yù)先生成的 HTML 內(nèi)容:

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

HTML DOM內(nèi)容

Web 引擎能夠按照基于 W3C 標(biāo)準(zhǔn)的 Java API 來將當(dāng)前頁面的文檔對象模型(DOM)加載為 XML 內(nèi)容。

在 Web 引擎實(shí)例成功加載 HTML 內(nèi)容后,可以通過調(diào)用Web引擎的 ?getDocument()? 方法輕松獲取 XML DOM。

以下代碼獲取一個(gè) ?Document?(?org.w3c.dom.Document?) 實(shí)例,假設(shè) Web 引擎完成加載 HTML 或 XML 內(nèi)容。

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.o2fo.com");

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

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

以文本字符串的形式獲取原始XML數(shù)據(jù)

以下代碼將 XML DOM 轉(zhuǎn)換為?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.o2fo.com");

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

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

通過 JavaScript 橋接生成 HTML5 內(nèi)容

JavaFX 的 WebEngine AP I有一個(gè) JavaScript 橋梁,允許 Java 代碼調(diào)用 HTML5 內(nèi)容中的 JavaScript 函數(shù)或腳本代碼。

要獲取原始 HTML5,您需要與 JavaScript 橋接器交互,以使用 Web 引擎的? executeScript()? 方法訪問 Web 內(nèi)容的 DOM。

以下代碼訪問HTML文檔(DOM)以從 ?documentElement.outerHTML? 獲取原始內(nèi)容:

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.o2fo.com");

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

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

從 Java 傳遞到 JavaScript

以下代碼顯示了如何從 Java 代碼調(diào)用 ?JavaScript? 函數(shù)。

假設(shè)我們有一個(gè)具有以下? JavaScript? 函數(shù)的網(wǎng)頁

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

我們可以從 Java 代碼調(diào)用該函數(shù) ?webEngine.executeScript(“sayHello("Hi there“);");?

從 JavaScript 傳遞到 Java

JavaFX 允許? JavaScript ?代碼調(diào)用 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.o2fo.com");

    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 ?代碼調(diào)用 Java 代碼

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

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


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號