5 Processing JavaScript Commands
This chapter extends the WebViewSample application and explains how to call JavaScript commands from JavaFX code.
The WebEngine
class provides API to run a script within the context of the current HTML page.
Understanding the executeScript method
The executeScript
method of the WebEngine
class enables executing any JavaScript commands declared in the loaded HTML page. Use the following string to call this method on a web engine: webEngine.executeScript("<function name>");
.
The method execution result is converted to a java.lang.Object
instance by using the following rules:
-
JavaScript
Int32
is converted tojava.lang.Integer
-
JavaScript numbers are converted to
java.lang.Double
-
JavaScript string values are converted to
java.lang.String
-
JavaScript boolean values are converted to
java.lang.Boolean
Refer to the API documentation for the WebEngine
class for more information about the conversion results.
Calling JavaScript Commands from JavaFX Code
Extend the WebViewSample application to introduce a help file and execute a JavaScript command that toggles the list of topics in the help file. Create the Help toolbar item that leads to the help.html file, where a user can preview reference material about Oracle web sites.
Add the help.html file, shown in, to the WebViewSample application.
Example 5-1 help.html file
<html lang="en"> <head> <!-- Visibility toggle script --> <script type="text/javascript"> <!-- function toggle_visibility(id) { var e = document.getElementById(id); if (e.style.display == 'block') e.style.display = 'none'; else e.style.display = 'block'; } //--> </script> </head> <body> <h1>Online Help</h1> <p class="boxtitle"><a href="#" onclick="toggle_visibility('help_topics');" class="boxtitle">[+] Show/Hide Help Topics</a></p> <ul id="help_topics" style='display:none;'> <li>Products - Extensive overview of Oracle hardware and software products, and summary Oracle consulting, support, and educational services. </li> <li>Blogs - Oracle blogging community (use the Hide All and Show All buttons to collapse and expand the list of topics).</li> <li>Documentation - Landing page to start learning Java. The page contains links to the Java tutorials, developer guides, and API documentation.</li> <li>Partners - Oracle partner solutions and programs. Popular resources and membership opportunities.</li> </ul> </body> </html>
The modified application code shown in Example 5-2 creates the Help toolbar item and an additional button to hide and show help topics. The button is added to the toolbar only when the Help page is selected.
Example 5-2 Adding the Toggle Help Topics Button
import javafx.application.Application; import javafx.beans.value.ObservableValue; import javafx.concurrent.Worker.State; import javafx.event.ActionEvent; import javafx.geometry.HPos; import javafx.geometry.Pos; import javafx.geometry.VPos; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Hyperlink; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.Region; import javafx.scene.paint.Color; import javafx.scene.web.WebEngine; import javafx.scene.web.WebView; import javafx.stage.Stage; public class WebViewSample extends Application { private Scene scene; @Override public void start(Stage stage) { // create scene stage.setTitle("Web View Sample"); scene = new Scene(new Browser(stage), 900, 600, Color.web("#666970")); stage.setScene(scene); // apply CSS style scene.getStylesheets().add("webviewsample/BrowserToolbar.css"); // show stage stage.show(); } public static void main(String[] args) { launch(args); } } class Browser extends Region { private final HBox toolBar; final private static String[] imageFiles = new String[]{ "product.png", "blog.png", "documentation.png", "partners.png", "help.png" }; final private static String[] captions = new String[]{ "Products", "Blogs", "Documentation", "Partners", "Help" }; final private static String[] urls = new String[]{ "http://www.oracle.com/products/index.html", "http://blogs.oracle.com/", "http://docs.oracle.com/javase/index.html", "http://www.oracle.com/partners/index.html", WebViewSample.class.getResource("help.html").toExternalForm() }; final ImageView selectedImage = new ImageView(); final Hyperlink[] hpls = new Hyperlink[captions.length]; final Image[] images = new Image[imageFiles.length]; final WebView browser = new WebView(); final WebEngine webEngine = browser.getEngine(); final Button toggleHelpTopics = new Button("Toggle Help Topics"); private boolean needDocumentationButton = false; public Browser(final Stage stage) { //apply the styles getStyleClass().add("browser"); for (int i = 0; i < captions.length; i++) { // create hyperlinks Hyperlink hpl = hpls[i] = new Hyperlink(captions[i]); Image image = images[i] = new Image(getClass().getResourceAsStream(imageFiles[i])); hpl.setGraphic(new ImageView(image)); final String url = urls[i]; final boolean addButton = (hpl.getText().equals("Help")); // process event hpl.setOnAction((ActionEvent e) -> { needDocumentationButton = addButton; webEngine.load(url); }); } // create the toolbar toolBar = new HBox(); toolBar.setAlignment(Pos.CENTER); toolBar.getStyleClass().add("browser-toolbar"); toolBar.getChildren().addAll(hpls); toolBar.getChildren().add(createSpacer()); //set action for the button toggleHelpTopics.setOnAction((ActionEvent t) -> { webEngine.executeScript("toggle_visibility('help_topics')"); }); // process page loading webEngine.getLoadWorker().stateProperty().addListener( (ObservableValue<? extends State> ov, State oldState, State newState) -> { toolBar.getChildren().remove(toggleHelpTopics); if (newState == State.SUCCEEDED) { if (needDocumentationButton) { toolBar.getChildren().add(toggleHelpTopics); } } }); // load the home page webEngine.load("http://www.oracle.com/products/index.html"); //add components getChildren().add(toolBar); getChildren().add(browser); } private Node createSpacer() { Region spacer = new Region(); HBox.setHgrow(spacer, Priority.ALWAYS); return spacer; } @Override protected void layoutChildren() { double w = getWidth(); double h = getHeight(); double tbHeight = toolBar.prefHeight(w); layoutInArea(browser,0,0,w,h-tbHeight,0,HPos.CENTER,VPos.CENTER); layoutInArea(toolBar,0,h-tbHeight,w,tbHeight,0,HPos.CENTER,VPos.CENTER); } @Override protected double computePrefWidth(double height) { return 900; } @Override protected double computePrefHeight(double width) { return 600; } }
Loading always happens on a background thread. Methods that initiate loading return immediately after scheduling a background job. The getLoadWorker()
method provides an instance of the Worker
interface to track the loading progress. If the progress status of the Help page is SUCCEEDED
, the Toggle Help Topics button is added to the toolbar, as shown in Figure 5-1.
The setOnAction
method shown in Example 5-3 defines behavior for the Toggle Help Topics button.
Example 5-3 Executing a JavaScript Command
//set action for the button
toggleHelpTopics.setOnAction((ActionEvent t) -> {
webEngine.executeScript("toggle_visibility('help_topics')");
});
When the user clicks the Toggle Help Topics button, the executeScript
method runs the toggle_visibility
JavaScript function for the help.html page, and the help topics appear, as shown in Figure 5-2. When the user performs another click, the toggle_visibility
function hides the lists of the topics.