Le Tutoriel de JavaFX WebView et WebEngine

View more Tutorials:

1- JavaFX WebView

JavaFX WebView est un mini navigateur qui est appelé comme un navigateur intégré (embedded browser) dans l'application JavaFX. Ce navigateur est basé sur WebKit, un moteur de navigateur ( browser engine )de code source ouvert, il prend en charge CSS, JavaScript, JavaScript, DOM et HTML5.

JavaFX WebView vous permet d'effectuer les tâches suivantes dans les applications JavaFX :


  • Traduire le contenu HTML à partir de l'URL locale et à distance
  • Garder l'historique Web
  • Exécuter des commandes JavaScript
  • Réaliser des appels de Javascript à JavaFX
  • Gérer des fenêtres pop-up sur le web
  • Appliquer des effets à navigateur intégré
La version actuelle ( JavaFX 2.3) du composant WebView prend en charge les fonctionnalités suivantes de HTML5 :

  • Canvas
  • Media Playback
  • Form controls (except for <input type="color"> )
  • Editable content
  • History maintenance
  • Support for the <meter> and <progress> tags.
  • Support for the <details> and <summary> tags.
  • DOM
  • SVG
  • Support for domain names written in national languages
L'image ci-dessous est l'architecture du navigateur intégré dans JavaFX :

WebEngine

La classe WebEngine fournit les fonctionnalités de base d'un site web. Elle prend en charge l'interaction de l'utilisateur, comme la navigation de liens et la soumission de formulaires HTM même si elle n'interagisse pas directement avec les utilisateurs. La classe WebEngine gère une page web en même moment . Il s'occupe les fonctions de navigation de base du chargement du contenu HTML et l'accès au DOM ainsi que la réalisation de de commandes JavaScript.

WebView

La classe  WebView est étendue de classe  Node, elle enveloppe un objet  WebEngine et affiche le contenu Html. Vous pouvez obtenir un objet   WebEngine de  WebView en utilisant la méthode  getEngine().
// Create a WebView
WebView browser = new WebView();

// Get WebEngine via WebView
WebEngine webEngine = browser.getEngine();

// Load page
webEngine.load("http://eclipse.com");

2- Exemple de WebView

Chargez une URL distante.
WebView browser = new WebView();
WebEngine webEngine = browser.getEngine();

String url = "https://eclipse.org";

// Load a page from remote url.
webEngine.load(url);
A part d'afficher des données à partir d'une URL distante, vous pouvez également afficher un contenu HTML statique.

// A HTML text

String html = "<html><h1>Hello</h1><h2>Hello</h2></html>";

// Load content.
webEngine.loadContent(html);

// Or
webEngine.loadContent(html,"text/html");
Ou le chargement de contenu html à partir d'un fichier local.
File file = new File("C:/test/a.html");
URL url= file.toURI().toURL();

// file:/C:/test/a.html
webEngine.load(url.toString());
Voyez l'exemple complet de  WebView. Notez que le  WebView par défaut a un ScrollPane, les défilements apparaient lorsque le contenu de site web est plus grand que la zone d'affichage.

WebViewDemo.java
package org.o7planning.javafx.webview;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class WebViewDemo extends Application {

    @Override
    public void start(final Stage stage) {

        Button buttonURL = new Button("Load Page https://eclipse.org");
        Button buttonHtmlString = new Button("Load HTML String");
        Button buttonHtmlFile = new Button("Load File C:/test/a.html");

        final WebView browser = new WebView();
        final WebEngine webEngine = browser.getEngine();

        buttonURL.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                String url = "https://eclipse.org";
                // Load a page from remote url.
                webEngine.load(url);
            }
        });

        buttonHtmlString.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                String html = "<html><h1>Hello</h1><h2>Hello</h2></html>";
                // Load HTML String
                webEngine.loadContent(html);
            }
        });
        buttonHtmlFile.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                try {
                    File file = new File("C:/test/a.html");
                    URL url = file.toURI().toURL();
                    // file:/C:/test/a.html
                    System.out.println("Local URL: " + url.toString());
                    webEngine.load(url.toString());
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }

            }
        });

        VBox root = new VBox();
        root.setPadding(new Insets(5));
        root.setSpacing(5);
        root.getChildren().addAll(buttonURL, buttonHtmlString, buttonHtmlFile, browser);

        Scene scene = new Scene(root);

        stage.setTitle("JavaFX WebView (o7planning.org)");
        stage.setScene(scene);
        stage.setWidth(450);
        stage.setHeight(300);

        stage.show();
    }

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

}

3- Exemple de WebView et de ProgressBar

Le téléchargement d'une page web sur le navigateur prend un certain temps. Parfois, vous devez utiliser un ProgressBar pour afficher le pourcentage du site qui a été téléchargé .
WebViewWithProgressDemo.java
package org.o7planning.javafx.webview;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class WebViewWithProgressDemo extends Application {

   @Override
   public void start(final Stage stage) {

       TextField addressBar = new TextField();
       addressBar.setText("https://eclipse.org");
       Button goButton = new Button("Go!");
       Label stateLabel = new Label();

       stateLabel.setTextFill(Color.RED);
       ProgressBar progressBar = new ProgressBar();

       final WebView browser = new WebView();
       final WebEngine webEngine = browser.getEngine();

       // A Worker load the page
       Worker<Void> worker = webEngine.getLoadWorker();

        // Listening to the status of worker
       worker.stateProperty().addListener(new ChangeListener<State>() {

           @Override
           public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
               stateLabel.setText("Loading state: " + newValue.toString());
               if (newValue == Worker.State.SUCCEEDED) {
                   stage.setTitle(webEngine.getLocation());
                   stateLabel.setText("Finish!");
               }
           }
       });

       // Bind the progress property of ProgressBar
       // with progress property of Worker
       progressBar.progressProperty().bind(worker.progressProperty());

       goButton.setOnAction(new EventHandler<ActionEvent>() {

           @Override
           public void handle(ActionEvent event) {
               String url = addressBar.getText();
               // Load the page.
               webEngine.load(url);
           }
       });
       //

       VBox root = new VBox();
       root.getChildren().addAll(addressBar, goButton, stateLabel, progressBar, browser);

       Scene scene = new Scene(root);

       stage.setTitle("JavaFX WebView (o7planning.org)");
       stage.setScene(scene);
       stage.setWidth(450);
       stage.setHeight(300);

       stage.show();
   }

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

}

4- Appeller Javascript de JavaFX

Après que WebView a chargé une page web, vous pouvez interagir avec la page web de JavaFX. Dans l'exemple ci-dessous, l'utilisateur clique sur un bouton de l'application JavaFX, cela appele une fonction de Javascrip de la page qui est affichée sur WebView​​​​​​​.




// Enable Javascript.
webEngine.setJavaScriptEnabled(true);

// Call a JavaScript function of the current page
webEngine.executeScript("changeBgColor();");A
WebViewExecuteJsDemo.java
package org.o7planning.javafx.webview;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class WebViewExecuteJsDemo extends Application {

   // A HTML Content with a javascript function.
   private static String HTML_STRING = //
           "<html>"//
                   + "<head> " //
                   + "  <script language='javascript'> " //
                   + "     function changeBgColor()  { "//
                   + "       var color= document.getElementById('color').value; "//
                   + "       document.body.style.backgroundColor= color; " //
                   + "     } " //
                   + "  </script> "//
                   + "</head> "//
                   + "<body> "//
                   + "   <h2>This is Html content</h2> "//
                   + "   <b>Enter Color:</b> "//
                   + "   <input id='color' value='yellow' /> "//
                   + "   <button onclick='changeBgColor();'>Change Bg Color</button> "//
                   + "</body> "//
                   + "</html> "//
   ;

   @Override
   public void start(final Stage stage) {

       Button button = new Button("Execute Javascript (Call from JavaFX)");

       final WebView browser = new WebView();
       final WebEngine webEngine = browser.getEngine();

       // Enable Javascript.
       webEngine.setJavaScriptEnabled(true);

       webEngine.loadContent(HTML_STRING);

       button.setOnAction(new EventHandler<ActionEvent>() {

           @Override
           public void handle(ActionEvent event) {
               // Call a JavaScript function of the current page
               webEngine.executeScript("changeBgColor();");
           }
       });

       VBox root = new VBox();
       root.setPadding(new Insets(5));
       root.setSpacing(5);
       root.getChildren().addAll(button, browser);

       Scene scene = new Scene(root);

       stage.setTitle("JavaFX WebView (o7planning.org)");
       stage.setScene(scene);
       stage.setWidth(450);
       stage.setHeight(300);

       stage.show();
   }

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

}
Vous pouvez accéder également à des objets JavaScript à travers des objets Java. La plupart des objets JavaScript sont enveloppés par netscape.javascript.JSObject. Les méthodes de JSObject :

public Object call(String methodName, Object... args);

public Object eval(String s);

public Object getMember(String name);

public void setMember(String name, Object value);

public void removeMember(String name);

public Object getSlot(int index);

public void setSlot(int index, Object value);
Exemple :
// Back Browser History

webEngine.executeScript("history.back()");

// Or
// Get the object representing the history of JavaScript objects JSObject.
JSObject history = (JSObject) webEngine.executeScript("history");

// Call 'back' method, without parameter.
history.call("back");
Un cas particulier où un appel  JavaScript renvoie un objet DOM ( Node DOM). Dans ce cas, le résultat qui est enveloppé par l'objet JSObject exécute l'interface org.w3c.dom.Node.

Element p = (Element) ebEngine.executeScript("document.getElementById('para')");

p.setAttribute("style", "font-weight: bold");

5- Créer un appel de JavaScript à JavaFX

.Au-dessus, vous pouvez appeler une fonction JavaScript affichée sur WebView de JavaFX. Inversement vous pouvez également créer un appel (Upcalls) de Javascript à JavaFX.

Sur le côté de JavaFX, vous devez créer un objet d'interface (d'une classe) et assurez-vous qu'il est connu par JavaScript en appelant JSObject.setMember(). Après avoir effectué cela, vous pouvez appeler les méthodes publiques de JavaScript et accéder aux champs publiques de ces objets.

// A Bridge class and must a public class
public class Bridge {

    public void showTime() {
        System.out.println("Show Time");

        label.setText("Now is: " + df.format(new Date()));
    }
}

// Get window object of page.
JSObject jsobj = (JSObject) webEngine.executeScript("window");

// Set member cho đối tượng 'window'
jsobj.setMember("myJavaMember", new Bridge());
Sur la page HTML :
<!-- In HTML -->

<button onclick='myJavaMember.showTime();'>Call To JavaFX</button>
Voyez l'exemple complet :
WebViewUpCallsDemo.java
package org.o7planning.javafx.webview;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

public class WebViewUpCallsDemo extends Application {

    private DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");

    private Label label;

    // A Bridge class and must a public class
    public class Bridge {

        public void showTime() {
            System.out.println("Show Time");

            label.setText("Now is: " + df.format(new Date()));
        }
    }

    // A HTML Content with a javascript function.
    private static String HTML_STRING = //
            "<html>"//
                    + "<head> " //
                    + "  <script language='javascript'> " //
                    + "     function callToJavaFX()  { "//
                    + "        myJavaMember.showTime(); " //
                    + "     } " //
                    + "  </script> "//
                    + "</head> "//
                    + "<body> "//
                    + "   <h2>This is Html content</h2> "//
                    + "   <button onclick='callToJavaFX();'>Call To JavaFX</button> "//
                    + "</body> "//
                    + "</html> "//
    ;

    @Override
    public void start(final Stage stage) {

        label = new Label("-");

        final WebView browser = new WebView();
        final WebEngine webEngine = browser.getEngine();

        // Enable Javascript.
        webEngine.setJavaScriptEnabled(true);

        // A Worker load the page
        Worker<Void> worker = webEngine.getLoadWorker();

        // Listening to the status of worker
        worker.stateProperty().addListener(new ChangeListener<State>() {

            @Override
            public void changed(ObservableValue<? extends State> observable, //
                    State oldValue, State newValue) {

                // When load successed.
                if (newValue == Worker.State.SUCCEEDED) {
                    // Get window object of page.
                    JSObject jsobj = (JSObject) webEngine.executeScript("window");

                    // Set member for 'window' object.
                    // In Javascript access: window.myJavaMember....
                    jsobj.setMember("myJavaMember", new Bridge());
                }
            }
        });

        // Load HTML content.
        // Tải nội dung HTML
        webEngine.loadContent(HTML_STRING);

        VBox root = new VBox();
        root.setPadding(new Insets(5));
        root.setSpacing(5);
        root.getChildren().addAll(label, browser);

        Scene scene = new Scene(root);

        stage.setTitle("JavaFX WebView (o7planning.org)");
        stage.setScene(scene);
        stage.setWidth(450);
        stage.setHeight(300);

        stage.show();
    }

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

}

View more Tutorials: