5.7.6 Web引擎与网页显示

JavaFX提供了用户界面组件来显示Web页面及对页面的内容进行操纵。JavaFX使用的网页显示引擎基于Webkit内核,支持HTML5的新特性。在JavaFX程序中可以访问Web引擎组件中显示的网页的DOM结构和执行JavaScript代码。这个组件相当于一个内嵌的浏览器,它使一种新的结合Java和HTML的部署方式成为可能。具体的做法是:程序的主体内容是使用HTML、JavaScript和CSS来编写的Web页面,并且可以利用HTML5的新特性。程序的外层由JavaFX来编写,通过一个Web引擎组件来显示作为主体的Web页面。用户在使用时运行的是JavaFX程序。这样的好处是在编写Web应用时限制了用户使用的浏览器类型,不需要过多考虑浏览器兼容性问题,同时可以利用Webkit内核的新特性。越来越多的Web应用使用了HTML5的新特性。如果用户直接通过浏览器来访问,此时的浏览器可能并不支持这些新特性。这一方面会影响用户体验,另外一方面也使程序的实现变得更加复杂。采用这种JavaFX与HTML集成的部署方式之后,用户只需要运行JavaFX程序即可,不需要考虑浏览器相关的问题。

Web引擎组件由javafx.scene.web.WebEngine和javafx.scene.web.WebView类来表示。WebEngine类负责管理网页以及与网页中的内容进行交互;WebView类则负责显示网页的内容,可以被当做场景上的普通节点来使用。代码清单5-23给出了使用Web引擎组件进行网页自动化测试的一个示例。待测试的网页是一个用户登录页面。用户输入用户名和密码之后,如果验证成功,会跳转到相应的页面。通过Web引擎组件可以对这个测试过程进行自动化。先创建一个WebView类的对象,并将其添加到界面场景中。然后通过WebView类的对象的getEngine方法可以获取所关联的WebEngine类的对象。WebEngine类的load方法可以用来加载一个网页并显示。网页的加载过程是异步执行的。通过WebEngine类的getLoadWorker方法可以获取到一个用来监视加载过程进度的javafx.concurrent.Worker接口的实现对象。Worker接口的workDone属性表示当前的加载进度。在该属性上添加一个变化监听器,可以监视当前的网页加载进度。网页加载完成之后,通过WebEngine类的getDocument方法可以获取表示当前页面DOM结构的org.w3c.dom.Document接口的实现对象。可以使用该Document接口的实现对象对网页内容进行操作。在代码清单5-23中设置了登录页面上两个<input>元素的值,用来模拟输入用户名和密码。WebEngine类的executeScript方法可以用来执行一段JavaScript代码。代码清单5-23通过JavaScript代码的方式来提交表单。如果用户验证正确,提交表单后,应该跳转到一个新的页面。WebEngine类的location属性可以用来监视内嵌浏览器中网页地址的变化。可以通过这种方式来验证网页是否发生了跳转。

代码清单5-23 使用Web引擎组件进行网页自动化测试的示例


public class JavafxWeb extends Application{

public static void main(String[]args){

launch(args);

}

public void start(Stage primaryStage){

primaryStage.setTitle("Web Test");

WebView view=new WebView();

primaryStage.setScene(new Scene(view,800,600));

primaryStage.show();

final WebEngine engine=view.getEngine();

String url="http://localhost/test.html";

engine.load(url);

final Worker worker=engine.getLoadWorker();

worker.workDoneProperty().addListener(new ChangeListener<Number>(){

public void changed(ObservableValue<?extends Number>observable, Number oldValue, Number newValue){

if(newValue.intValue()==100){

worker.workDoneProperty().removeListener(this);

engine.locationProperty().addListener(new ChangeListener-<String>(){

public void changed(ObservableValue<?extends String>observable, String oldValue, String newValue){

System.out.println(newValue);//检查地址是否正确

}

});

Document doc=engine.getDocument();

Element nameElem=doc.getElementById("name");

nameElem.setAttribute("value","alex");

Element passwordElem=doc.getElementById("password");

passwordElem.setAttribute("value","password");

String script="document.getElementById('form').submit();";

engine.executeScript(script);

}

}

});

}

}