JavaFX WebView
- JavaFX WebView Example
- WebView WebEngine
- WebView Zoom
- WebView Font Scale
- Set User-Agent HTTP Header
- Disable WebView Context Menu
- Browsing History
- Listening for State Changes When Loading Document
- Execute JavaScript From Java
- Executing Java From JavaScript
- Access the DOM
- Web Page CSS Style Sheet
- WebView CSS Styles
Jakob Jenkov |
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 Type | Java Type |
---|---|
null | null |
boolean | Boolean |
int32 | Integer |
number | Double |
string | String |
object | JSObject (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 Property | Description |
---|---|
-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-type | Specifies the kind of font smoothing to apply. |
-fx-font-scale | A decimal number (e.g. 1.4 ) setting the font scale of this WebView |
More coming soon...
Tweet | |
Jakob Jenkov |