Tech and Media Labs
This site uses cookies to improve the user experience.


JavaFX WebView

Jakob Jenkov
Last update: 2018-10-22

The JavaFX WebView (javafx.scene.web.WebView) component is capable of showing web pages (HTML, CSS, SVG, JavaScript) inside a JavaFX application. As such, the JavaFX WebView is a mini browser. The WebView component is very handy when you need to show documentation (e.g. Help texts), news, blog posts or other content which needs to be downloaded from a web server at runtime.

The JavaFX WebView uses the WebKit open source browser engine internally to render the web pages.

JavaFX WebView Example

The WebView component is a JavaFX Node so it can be included in the scene graph like any other JavaFX component which is also a Node. Here is a simple JavaFX WebView example:

package com.jenkov.javafx;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class WebViewExample extends Application {

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

    public void start(Stage primaryStage) {
        primaryStage.setTitle("JavaFX WebView Example");

        WebView webView = new WebView();

        webView.getEngine().load("http://google.com");

        VBox vBox = new VBox(webView);
        Scene scene = new Scene(vBox, 960, 600);

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

    }
}

This example shows a JavaFX application that creates a WebView which is inserted into a JavaFX VBox layout component - which is again placed inside a JavaFX Stage - which is set on the primary Stage.

WebView WebEngine

The JavaFX WebView WebEngine (javafx.scene.web.WebEngine) is an internal component used by the WebView to load the data that is to be displayed inside the WebView. To make the WebView WebEngine load data, you must first obtain the WebEngine instance from the WebView.

Obtaining the WebEngine

You obtain the WebEngine from the WebView by calling the WebView getEngine() method. Here is an example of obtaining the WebEngine from a JavaFX WebView:

WebView webView = new WebView();

WebEngine webEngine = webView.getEngine();

Load a Web Page

Once you have obtained a WebEngine instance from the WebView you can load data by calling its load() method. The load() method takes a URL as parameter. Here is an example of loading a web page via the WebEngine load() method:

webEngine.load("http://google.com");

Load Local Content

The WebView WebEngine can load local content too - meaning content that is supplied to it directly in a method call (not loaded over the Internet). The WebEngine loads local content via the loadContent() method. Here is an example of loading local contain in a JavaFX WebView using loadContent()

String content =
    "Hello World!";

webEngine.loadContent(content, "text/html");

The first parameter to the loadContent() call in the example above is the content itself. In this example it is a very simple HTML document contained in a Java String.

The second parameter to the loadContent() call in the example above is the content type (mime type) of the content. Since we are loading an HTML document, the standard content type for that is text/html.

Reload Content

It is possible to reload the content currently loaded in a JavaFX WebView. You do so using the WebEngine reload() method. Here is an example of reloading content in a JavaFX WebView using the WebEngine reload() method:

webEngine.reload();

WebView Zoom

It is possible to set the zoom level of a JavaFX WebView. For instance, you can specify that the WebView should always zoom in 25%, or zoom out 10% etc. Zooming in scales up or down all of the content displayed inside the WebView. You set the WebView zoom level via the setZoom() method. Here is an example of setting the JavaFX WebView zoom level:

webView.setZoom(1.25);  //zoom in 25%.

The setZoom() method takes a double value. A value of 1.0 means a zoom level of 100% which means no zoom. A value of 0.5 means a zoom level of 50%, which means zoom out to 50% of original size. In the example above, the value of 1.25 means a zoom level of 125%, meaning zoom in until a size of 125% of the original size.

WebView Font Scale

It also possible to only scale the text displayed inside a JavaFX WebView without scaling any of the non-text content (e.g. images) displayed inside the WebView. You set the font scaling property via the setFontScale() method. Here is an example of scaling up the text displayed in a JavaFX WebView by 25% (125% total):

webView.setFontScale(1.25);

The setFontScale() method takes a double parameter which specifies the font scale value. A scale value of 1.0 means no scaling up or down. A value of 0.5 means scaling down to half size, and a value of 2.0 means scaling up to double size.

Set User-Agent HTTP Header

You can set the User-Agent HTTP header sent to the web servers your WebView instance is loading web pages from. You set the User-Agent HTTP header via the WebEngine setUserAgent() method. Here is an example of setting the User-Agent HTTP header of a WebView:

webEngine.setUserAgent("MyApp Web Browser 1.0");

You do not need to set the User-Agent HTTP Header, but you might be interested in having your particular app show up as a separate browser. You might want to include the version of WebKit your application is using. This gives web servers a better chance of optimizing their website for their visitor browsers, including yours. Here is an example of including the JavaFX and WebKit version in the User-Agent:

webEngine.setUserAgent("MyApp Web Browser 1.0 - AppleWebKit/555.99 JavaFX 8.0");

Disable WebView Context Menu

A JavaFX WebView has a default context menu (right click menu) which is displayed when you right click (context click) on the WebView in the JavaFX application. You can disable the WebView context menu by calling the WebView setContextMenuEnabled() method with a parameter value of false. Here is an example of disabling the context menu of a JavaFX WebView:

webView.setContextMenuEnabled(false);

Browsing History

You can access the browsing history of a JavaFX WebView. The browsing history consists of the pages the user has visited while browsing inside the WebView. You access the browsing history of a JavaFX WebView via its WebEngine object. You call the WebEngine getHistory() method, and you get a WebHistory object back. Here is an example of obtaining the WebHistory object from a WebView WebEngine object:

WebEngine webEngine = webView.getEngine();
WebHistory history = webEngine.getHistory();

Once you have access to the WebHistory object, you can start inspecting and manipulating the browsing history. We will see how in the following sections.

Browsing History Entries

You can access the browsing history entries kept inside a WebHistory object by calling its getEntries() method. Here is an example of obtaining a list of the browsing history entries from a WebHistory object:

ObservableList<WebHistory.Entry> entries = history.getEntries();

The list returned is a list of WebHistory.Entry objects which can be inspected for information about each entry.

Iterate Browsing History Entries

You can access the browsing history entries (the pages visited) kept inside a WebHistory object. Here is an example of iterating through all the browsing history entries of a JavaFX WebHistory object:

Iterator<WebHistory.Entry> iterator = entries.iterator();
while(iterator.hasNext()){
    WebHistory.Entry entry = iterator.next();
}

You can also iterate the browsing history entries using a for-each loop, like this:

for(WebHistory.Entry entry : entries){
    //do something with the entry
}

WebHistory.Entry

A WebHistory.Entry contains the following information:

  • URL
  • Title
  • Last visited date

You can access the URL, title and last visited date from a WebHistory.Entry using the following methods:

String url           = entry.getUrl();
String title         = entry.getTitle();
Date lastVisitedDate = entry.getLastVisitedDate();

Go Forward and Backward in History

Once you have an instance of the WebHistory object you can actually manipulate the history. You can force the WebView to go forward and back in the browsing history. You do so by calling the WebHistory go() method. Here are two examples of going forward and backward in the browsing history:

history.go(-1);
history.go( 1);

If you pass a negative integer to the go() method the browser will move backward in the browsing history to the page (URL) visited just before the currently displayed page.

If you pass a positive integer to the go() method, you will make the WebView go one entry forward in the browsing history. That only works if the user has already visited at least 2 pages, and gone back from the first page.

Current History Entry Index

If you have moved back and forth a bit in the browsing history, you might be interested in seeing what index in the browsing history the current history entry has. You can see the index of the current browsing history entry via the method WebHistory getCurrentIndex() method. Here is an example of reading the index of the current browsing history entry:

int currentIndex = history.getCurrentIndex();

Listening for State Changes When Loading Document

When you tell the WebEngine to load a document, the document is loaded in the background via another thread. You can listen for changes in the document loading status, so you can be notified when the document has finished loading. Here is an example of listening for document load status changes of a WebView WebEngine:

webEngine.getLoadWorker().stateProperty().addListener(
    new ChangeListener() {
        @Override
        public void changed(ObservableValue observable, Object oldValue, Object newValue) {
            System.out.println("oldValue: " + oldValue);
            System.out.println("newValue: " + newValue);

            if (newValue == Worker.State.SUCCEEDED) {
                //document finished loading
            }
        }
    }
);

Execute JavaScript From Java

It is possible to execute JavaScript embedded in the HTML page displayed inside a JavaFX WebView from Java. You execute JavaScript in a WebView from Java via the WebEngine executeScript() method. Here is a simple example of executing JavaScript embedded in a WebView from Java code:

webEngine.executeScript("myFunction()");

The executeScript() method takes a Java String as parameter which contains the JavaScript to execute. The example above calls a JavaScript function named myFunction(). This function has to be defined inside the web page displayed in the WebView the above WebEngine to.

Executing From a WebEngine Listener

So far I have had some problems executing JavaScript functions from Java, unless I call executeScript() from within a WebEngine listener. Here is an example of executing JavaScript from Java from within a WebEngine listener:

webEngine.getLoadWorker().stateProperty().addListener(
    new ChangeListener() {
        @Override
        public void changed(ObservableValue observable, Object oldValue, Object newValue) {
            System.out.println("oldValue: " + oldValue);
            System.out.println("newValue: " + newValue);

            if (newValue != Worker.State.SUCCEEDED) {
                return;
            }
            System.out.println("Succeeded!");
            String hello = (String) webEngine.executeScript("myFunction()");
            System.out.println("hello: " + hello);
        }
    }
);

If you know what causes the problem, or why this "limitation" exists, I would appreciate an email explaining it :-)

JavaScript Return Values

If a JavaScript function returns a value, that value will be converted to a Java data type and returned from the executeScript() method. Imagine that the myFunction() JavaScript function returns a String. In that case, a Java String would be returned from the executeScript() method. Here is how catching that String would look:

String returnValue = (String) webEngine.executeScript("myFunction()");

The following table shows what Java types various JavaScript return types are converted to:

JavaScript TypeJava Type
nullnull
booleanBoolean
int32Integer
numberDouble
stringString
objectJSObject (netscape.javascript.JSObject)

Executing Java From JavaScript

It is also possible to call Java code from JavaScript running inside a JavaFX WebView. In order to do that you must make a Java object available to the JavaScript running inside the WebView. The easiest way to do that is to set the Java object as a member of the window object in the document displayed in the WebView . Here is how that is done:

webEngine.getLoadWorker().stateProperty().addListener(
    new ChangeListener() {
        @Override
        public void changed(ObservableValue observable, Object oldValue, Object newValue) {
            if (newValue != Worker.State.SUCCEEDED) { return; }

            JSObject window = (JSObject) webEngine.executeScript("window");
            window.setMember("myObject", new MyObject());
        }
    }
);

The example above first gets access to the window object via the WebEngine executeScript() method. Second, the example sets an instance of the MyObject class as member on the window object. JavaScript running inside the WebView can now call methods on this object, as if it was a JavaScript object.

The MyObject class looks like this:

public static class MyObject {

    public void doIt() {
        System.out.println("doIt() called");
    }
}

Once an object of this class has been exposed as a member of the window object named myObject, you can call its doIt() method like this:

window.myObject.doIt();

Please keep in mind that when the document first loads in the WebView, the myObject is not yet exposed on the window object. Therefore, if you try to call a method on it immediately, it may fail.

Access the DOM

You can access the DOM of the web page displayed inside a JavaFX WebView by calling the WebEngine getDocument() method. Here is an example of accessing the DOM of a WebView:

Document document = webEngine.getDocument();

The Document object returned is a org.w3c.dom.Document instance.

Web Page CSS Style Sheet

Normally a web page provides its own CSS style sheet. However, in case a web page has no CSS style sheet you can set a CSS style sheet for it using the WebEngine setUserStyleSheetLocation(). Here is an example of setting the CSS style sheet for a web page using WebEngine setUserStyleSheetLocation();

webEngine.setUserStyleSheetLocation("stylesheet.css");

The String passed as parameter to the setUserStyleSheetLocation() method should be the path in the file system to where the CSS style sheet file is located,

WebView CSS Styles

It is possible to style a JavaFX WebView component with CSS, just like you can style any other JavaFX component. You can set the following CSS properties for a JavaFX WebView:

CSS PropertyDescription
-fx-context-menu-enabled Accepts the value of true or false - which specifies whether or not the context menu (right click menu) is enabled or not.
-fx-font-smoothing-typeSpecifies the kind of font smoothing to apply.
-fx-font-scaleA decimal number (e.g. 1.4) setting the font scale of this WebView

More coming soon...

Jakob Jenkov




Copyright  Jenkov Aps
Close TOC