目錄 ★☆★ 寫在前面 ★☆★ ★☆★ 本系列文章 ★☆★ ★☆★ 開源網址 ★☆★ 〇、寫本文章的目的 一、項目簡介 二、想法沖突 三、為新架構而做的前期努力 0、前言 1、java 客戶端內嵌瀏覽器之 Swing 2、java 客戶端內嵌瀏覽器之 SWT 3、java 客戶端內嵌瀏覽器之 Swing + SWT + DJNativeSwing 4、java 客戶端內嵌瀏覽器之 javaFX
★☆★ 寫在前面 ★☆★
請通過目錄,選擇感興趣的部分閱讀。
★☆★ 本系列文章 ★☆★
【java】本地客戶端內嵌瀏覽器1 - Swing、SWT、DJNativeSwing、javaFX 【java】本地客戶端內嵌瀏覽器2 - chrome/chromium/cef/jcef 【java】本地客戶端內嵌瀏覽器3 - Swing 使用 Spring 框架 + 打包項目 + 轉exe + 源碼
★☆★ 開源網址 ★☆★
https://github.com/supsunc/swing-jcef-spring
〇、寫本文章的目的
本人正在做的項目,本人想修改其架構,并付諸實現,但最后被否定,不想因為修改架構的努力付諸東流,遂寫本文。
一、項目簡介
為一個儀器開發可視化操控軟件,儀器方提供 C# 語言編寫的 dll,通過儀器方提供的接口進行操控。 本項目在最初設計架構時,本人并沒有參與,本人介入該項目時,已確定采用 B/S 架構。 Server 端用 Tomcat 做后臺,用 java 做開發語言。 通過 jni4net 對儀器方提供的 dll 進行二次封裝,進而得到后臺可以使用的 jar 包,進而操控儀器。 后臺使用的是 SpringMVC 框架。
服務器電腦安裝 jdk、Tomcat,服務器電腦安裝 Chrome 使用該軟件
用戶電腦安裝 jdk、Tomcat、chrome 使用該軟件
二、想法沖突
1、起因
軟件一階段測試時,提供給甲方一套文件,包括 32 位和 64 位的 jdk、Tomcat、Chrome,大約 600 MB 左右大小。我這邊領導居然要求提供一個 一鍵安裝 的那種文件,最后寫了兩個 .bat 文件,用一些 xcopy、setx 等方法。
這就導致了我認為儀器需要和用戶電腦相連,而操控儀器這種數據交互就要通過 Tomcat,走 http 協議。這樣不但作為開發者調用相關接口會很麻煩,對于用戶,安裝一堆軟件也很麻煩,且儀器必須和服務端在一起,而不能獨立出來。采用 B/S 架構,
2、構思新架構
主體架構還是 B/S 架構,但是開發一個 Client,內嵌 Chromium 內核瀏覽器,由本地和儀器進行交互。
三、為新架構而做的前期努力
0、前言
項目 B/S 架構的 Browser 部分以 Chrome 的 Webkit 內核做定制開發,采用了 ES6、ES2016、ES2017、ES2018 相關語法,使用了一些 Webkit/Blink 內核才支持的一些語法、方法等,所以開發的客戶端必須 內置 Chromium 內核。 由于調用 dll 已用 jni4net 生成相關 jar 包,且制作的客戶端要求可移植,那么 使用 java 開發客戶端 是再好不過的了。 經過前期探索發現 Java 應用程序用戶界面的開發工具包 Swing 好像不自帶 Browser 組件。
1、java 客戶端內嵌瀏覽器之 Swing
參考鏈接:Swing 簡單的WEB瀏覽器
不具體操作講解了,代碼很簡單,將其網址改為 https://www.baidu.com/,并啟動程序,我整個人都傻了。
最大化窗口后,嘗試搜索點什么東西,點擊“百度一下”。 ???空白頁了?
2、java 客戶端內嵌瀏覽器之 SWT
SWT.jar 包下載步驟,請參考【java】(org.eclipse.swt)SWT.jar 的下載步驟
新建項目,導入 jar 包,Add as Library,新建個 Main 方法。
直接分享源代碼,此處參考鏈接:java SWT Browser實現瀏覽器功能并運行JavaScript代碼
package swt
. browser
; import org
. eclipse
. swt
. *
;
import org
. eclipse
. swt
. browser
. *
;
import org
. eclipse
. swt
. layout
. *
;
import org
. eclipse
. swt
. widgets
. *
; public class Main { public static void main ( String
[ ] args
) { Display display
= new Display ( ) ; final Shell shell
= new Shell ( display
) ; shell
. setLayout ( new FillLayout ( ) ) ; final Browser browser
; try { browser
= new Browser ( shell
, SWT
. NONE
) ; } catch ( SWTError e
) { System
. out
. println ( "Could not instantiate Browser: " + e
. getMessage ( ) ) ; display
. dispose ( ) ; return ; } browser
. setUrl ( "www.baidu.com" ) ; shell
. open ( ) ; while ( ! shell
. isDisposed ( ) ) { if ( ! display
. readAndDispatch ( ) ) display
. sleep ( ) ; } display
. dispose ( ) ; }
}
運行之后,右鍵單擊彈出菜單,感覺像是 IE 內核(哈哈,憑借這個右鍵菜單來判斷顯然是不現實的),我們的項目直接崩掉了。
其實是在實例化 Browser 對象時的入參控制了使用的內核。
Browser browser
= new Browser ( shell
, SWT
. NONE
) ;
Browser browser
= new Browser ( shell
, SWT
. MOZILLA
) ;
Browser browser
= new Browser ( shell
, SWT
. WEBKIT
) ;
使用 MOZILLA 內核啟動程序的時候,控制臺會提示 Unsupported Browser Type: SWT.MOZILLA style is deprecated. It'll be removed from the user specified style. Browser will be created with the modified style and if no other style bit is specified, browser with SWT.NONE style will be created。
使用 WEBKIT 內核啟動程序的時候,哈哈,控制臺提示 Could not instantiate Browser: No more handles [Safari must be installed to use a SWT.WEBKIT-style Browser]。要求 必須安裝 Safari 瀏覽器,安裝 Chrome 是沒有用的 ,因為 webkit 內核可以從 Safari 瀏覽器中剝離出來,從 Chrome 中剝離不出來。還有一點是 Windows 上的 Safari 瀏覽器好像是好久沒有更新了,其 Webkit 內核版本也很低。
3、java 客戶端內嵌瀏覽器之 Swing + SWT + DJNativeSwing
此部分參考鏈接:java使用swing實現內嵌瀏覽器 DJNativeSwing 項目官網:Native Swing DJNativeSwing 項目開發者日志:News Log DJNativeSwing 項目下載地址:The DJ Project DJNativeSwing 相關 jar 包下載地址:DJNativeSwing-SWT-1-0-3-20140708.zip
主要使用這兩個 jar 包。
新建項目,導入 jar 包,Add as Library,新建個 Main 方法。
新建一個 package 叫做 browser,在里面新建一個 class 叫做 MyBrowser,直接分享源代碼,此處參考鏈接:java使用swing實現內嵌瀏覽器
package dj
. nativeSwing
. browser
; import chrriis
. dj
. nativeswing
. swtimpl
. components
. JWebBrowser
; import javax
. swing
. *
;
import java
. awt
. *
; public class MyBrowser extends JPanel { public MyBrowser ( String url
) { super ( new BorderLayout ( ) ) ; JPanel webBrowserPanel
= new JPanel ( new BorderLayout ( ) ) ; JWebBrowser webBrowser
= new JWebBrowser ( ) ; webBrowser
. navigate ( url
) ; webBrowser
. setButtonBarVisible ( false ) ; webBrowser
. setMenuBarVisible ( false ) ; webBrowser
. setBarsVisible ( false ) ; webBrowser
. setStatusBarVisible ( false ) ; webBrowserPanel
. add ( webBrowser
, BorderLayout
. CENTER
) ; add ( webBrowserPanel
, BorderLayout
. CENTER
) ; webBrowser
. executeJavascript ( "alert('hello swing')" ) ; }
}
在 Main 類中新增方法 openForm,直接分享源代碼,此處參考鏈接:java使用swing實現內嵌瀏覽器
package dj
. nativeSwing
; import chrriis
. common
. UIUtils
;
import chrriis
. dj
. nativeswing
. swtimpl
. NativeInterface
;
import dj
. nativeSwing
. browser
. MyBrowser
; import javax
. swing
. *
;
import java
. awt
. *
; public class Main { public static void main ( String
[ ] args
) { String url
= "http://www.baidu.com" ; String title
= "hello swing" ; openForm ( url
, title
) ; } private static void openForm ( String url
, String title
) { UIUtils
. setPreferredLookAndFeel ( ) ; NativeInterface
. open ( ) ; SwingUtilities
. invokeLater ( new Runnable ( ) { public void run ( ) { JFrame frame
= new JFrame ( title
) ; frame
. setDefaultCloseOperation ( JFrame
. DISPOSE_ON_CLOSE
) ; frame
. getContentPane ( ) . add ( new MyBrowser ( url
) , BorderLayout
. CENTER
) ; frame
. setExtendedState ( JFrame
. MAXIMIZED_BOTH
) ; frame
. setLocationByPlatform ( true ) ; frame
. setVisible ( true ) ; frame
. setResizable ( true ) ; frame
. setSize ( 1400 , 700 ) ; frame
. setLocationRelativeTo ( frame
. getOwner ( ) ) ; } } ) ; NativeInterface
. runEventPump ( ) ; }
}
進入到 JWebBrowser 的構造方法中,可以發現,其中第二行 WebBrowserRuntime runtime = WebBrowserRuntime.DEFAULT;規定了默認的內核,如果無參構造對象,則使用默認的內核,應該就是 IE 內核。 和 SWT 一樣,是在實例化 JWebBrowser 對象時的入參控制了使用的內核。
JWebBrowser webBrowser
= new JWebBrowser ( ) ;
JWebBrowser webBrowser
= new JWebBrowser ( JWebBrowser
. useXULRunnerRuntime ( ) ) ;
JWebBrowser webBrowser
= new JWebBrowser ( JWebBrowser
. useWebkitRuntime ( ) ) ;
使用 MOZILLA 內核啟動程序的時候,哈哈,這底層用的不還是 SWT 的么,控制臺提示 Unsupported Browser Type: SWT.MOZILLA style is deprecated. It'll be removed from the user specified style. Browser will be created with the modified style and if no other style bit is specified, browser with SWT.NONE style will be created。
使用 WEBKIT 內核啟動程序的時候,哈哈,實錘底層用的是 SWT ,注意看控制臺提示 No more handles [Safari must be installed to use a SWT.WEBKIT-style Browser]。要求 必須安裝 Safari 瀏覽器,安裝 Chrome 是沒有用的 ,原因在上面說過了。
4、java 客戶端內嵌瀏覽器之 javaFX
能支撐我到現在還沒有放棄的原因是我在網上搜索到了,jdk1.8 自帶 javaFX ,而 javaFX 自帶瀏覽器組件,而且使用的是 WebKit HTML 技術的Web組件(請參考 JavaFX WebView概述,很強大,內置了類似Electron的功能 ),且搜索到了很多關于 javafx 的很多文章和觀點,全都在 diss Swing,擁護 javaFX。
javaFX的幾個新特性,讓swing徹底過時
現在用Java寫UI,該用Swing還是JavaFX?
Swing那么受歡迎,為啥JavaFX屢被唱衰?
JavaFX與Swing框架相比,有哪些特點?
JavaFX實戰 -- 00. 為什么選擇JavaFX?
新建項目,新建個 Main 方法,繼承自 Application。
直接分享源代碼,此處參考鏈接:用javafx webview 打造自己的瀏覽器
package javafx
; import javafx
. application
. Application
;
import javafx
. beans
. value
. ChangeListener
;
import javafx
. beans
. value
. ObservableValue
;
import javafx
. concurrent
. Worker
;
import javafx
. concurrent
. Worker
. State
;
import javafx
. scene
. Group
;
import javafx
. scene
. Scene
;
import javafx
. scene
. control
. ScrollPane
;
import javafx
. scene
. web
. WebEngine
;
import javafx
. scene
. web
. WebView
;
import javafx
. stage
. Stage
; public class Main extends Application { public static void main ( String
[ ] args
) { launch ( args
) ; } @Override public void start ( Stage stage
) throws Exception
{ stage
. setWidth ( 400 ) ; stage
. setHeight ( 500 ) ; Scene scene
= new Scene ( new Group ( ) ) ; final WebView browser
= new WebView ( ) ; final WebEngine webEngine
= browser
. getEngine ( ) ; ScrollPane scrollPane
= new ScrollPane ( ) ; scrollPane
. setContent ( browser
) ; webEngine
. getLoadWorker ( ) . stateProperty ( ) . addListener ( new ChangeListener < State> ( ) { @Override public void changed ( ObservableValue ov
, State oldState
, State newState
) { if ( newState
== Worker
. State
. SUCCEEDED
) { stage
. setTitle ( webEngine
. getLocation ( ) ) ; } } } ) ; webEngine
. load ( "http://www.baidu.com" ) ; scene
. setRoot ( scrollPane
) ; stage
. setScene ( scene
) ; stage
. show ( ) ; }
}
將網址改成我們的項目網址,哇哇哇,沒崩,打開了。但是。。。 ???不大對勁啊。
正常 Chrome 這樣顯示:
javafx 內嵌瀏覽器這樣顯示:
探查差異,在程序中打印 UserAgent
System
. out
. println ( webEngine
. getUserAgent ( ) ) ;
原來沒用 Chrome 的 Webkit 內核,用的 Safari 的 Webkit 內核,而且版本還挺高?
我看了一下,我電腦上最新版Chrome: Chrome 78.0.3904.70 版本的 UserAgent里寫著 Safari/537.36
然而我們的項目必須用 Chrome 的 Webkit 內核,還得是高版本的。
總結
以上是生活随笔 為你收集整理的【java】本地客户端内嵌浏览器1 - Swing、SWT、DJNativeSwing、javaFX 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。