JavaFX WebView调用系统浏览器打开网页

目前人有点懒散了,所以之前的《从零开始学习JavaFX》也好久没更新了。因为有访问这个博客的朋友发邮件问问题,就准备顺带着写一下。

这个朋友的需求是用WebView嵌入网页,然后在点击网页内部的链接时,使用外部浏览器来打开网页。

其实我之前也提到过很多次,JavaFX最重要的技术要点是属性绑定机制,几乎在国外网站或者Java官方开发程序中,属性绑定也必用的优秀机制。任何涉及到属性的事件等都可以从这方面下手。

同样的,我们如何通过点击WebView链接调用系统浏览器也可以从这方面下手。

仔细观察,可以发现在JavaFX的WebView的WebEngine中有location属性,根据官方说明,代表的是当前Web页面的URL。

这样一来,我们通过监听location属性的改变,然后调用系统浏览器打开改变后的链接即可。

代码如下:

import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.AnchorPane;
import javafx.scene.web.WebView;


public class Main extends Application {
	private String mInitUrl = "https://www.baidu.com";
	@Override
	public void start(Stage primaryStage) {
		try {
			AnchorPane root = new AnchorPane();
			Scene scene = new Scene(root,400,400);
			scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
			WebView mWebView = new WebView();
			ScrollPane scrollPane = new ScrollPane(mWebView);
			scrollPane.setPrefSize(scene.getWidth(), scene.getHeight());
			root.getChildren().add(scrollPane);
			mWebView.autosize();
			mWebView.getEngine().load(mInitUrl);
			
			mWebView.getEngine().locationProperty().addListener(new ChangeListener() {
			    @Override
			    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue)
			    {
			        Desktop d = Desktop.getDesktop();
			        URI address;
					try {
					   if(!observable.getValue().contentEquals(mInitUrl)){
						address = new URI(observable.getValue());
				        d.browse(address);
					   }
					} catch (URISyntaxException | IOException e) {
						e.printStackTrace();
					}
			    }
			});
			primaryStage.setScene(scene);
			primaryStage.show();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}

其实对于目前的JavaFX来说,熟悉和使用属性绑定机制,是对JavaFX进阶开发的一个很大的帮助,大家可以多试试。

但是对于上面的实现方式来说,WebView里面的页面也同样的改变了,通常我们使用的时候,希望点击WebView使用默认浏览器跳转,而原页面不变,例如帮助文档等内容。

这里我们可以使用一个开源项目LibFX,里面提供了监听JavaFX的WebView链接的工具类。

代码如下:

WebViews.addHyperlinkListener(mWebView, new WebViewHyperlinkListener() {
				
				@Override
				public boolean hyperlinkUpdate(HyperlinkEvent event) {
					System.out.println(event.getURL());
					Desktop d = Desktop.getDesktop();
					try {
				        d.browse(event.getURL().toURI());
					} catch (URISyntaxException | IOException e) {
						e.printStackTrace();
					}
					return true;
				}
			},EventType.ACTIVATED);

这样一来就能够点击WebView内部链接,使用浏览器打开,并且原WebView页面不变了。

发表评论

电子邮件地址不会被公开。