DOC-04-05 处理JavaScript指令
本章进一步扩展了WebViewSample程序并解释如何在JavaFX代码中调用JavaScript指令。
WebEngine类提供了在当前HTML页面的上下文中执行脚本的API。
5.1 理解executeScript方法
WebEngine类的executeScript方法能够执行在加载的HTML页面声明的任何JavaScript指令。使用下面的代码在调用网页引擎上的这个方法:webEngine.executeScript(“<function name>”);。
该方法的执行结果会按下面的规则转化为java.lang.Object实例:
● JavaScript的Int32会被转化为lang.Integer
● JavaScript的number会被转化为lang.Double
● JavaScript的string会被转化为lang.String
● JavaScript的boolean会被转化为lang.Boolean
参考WebEngine类的API文档来了解更多关于转化结果的信息。
5.2 在JavaFX代码中调用JavaScript指令
扩展WebViewSample程序用来介绍一个帮助文件并执行一句JavaScript指令,该指令负责切换帮助文档中的主题列表。创建Help工具栏项并指向help.html文件,用户可以预览关于Oracle网站的的参考资料。
将如下所示的help.html文件添加到WebViewSample程序中。
例5-1 help.html文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<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> |
例5-2中展示了修改后的程序代码,在该代码中创建了Help工具栏项和一个附加的按钮来隐藏/显示帮助主题。只有当选择了Help页面时该按钮才会加到工具栏中。
例5-2 添加切换帮助主题按钮
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
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; } } |
加载过程总是在后台线程中完成。初始化加载过程的方法会在调度了后台线程之后马上返回。getLoadWorker()方法提供了Worker接口的一个实例,可以用来跟踪加载过程。如果帮助页面的进度状态是SUCCEEDED,Toggle Help Topics按钮会被添加到工具栏,如图5-1所示。
图5-1 切换帮助主题按钮
例5-3中展示的setOnAction方法为Toggle Help Topics按钮定义了行为。
例5-3 执行JavaScript指令
1 2 3 4 |
//set action for the button toggleHelpTopics.setOnAction((ActionEvent t) -> { webEngine.executeScript("toggle_visibility('help_topics')"); }); |
当用户点击Toggle Help Topics按钮时,executeScript方法会为help.html页面执行名为toggle_visibilety的JavaScript函数,然后帮助主题就会出现,如图5-2所示。用户再点击一次,toggle_visibility函数会隐藏掉主题列表。
图5-2 展示帮助主题

