目錄 ★☆★ 寫在前面 ★☆★ ★☆★ 本系列文章 ★☆★ ★☆★ 開源網(wǎng)址 ★☆★ 〇、寫本文章的目的 一、項目簡介 二、想法沖突 三、為新架構(gòu)而做的前期努力 0、前言 1、java 客戶端內(nèi)嵌瀏覽器之 Swing 2、java 客戶端內(nèi)嵌瀏覽器之 SWT 3、java 客戶端內(nèi)嵌瀏覽器之 Swing + SWT + DJNativeSwing 4、java 客戶端內(nèi)嵌瀏覽器之 javaFX
★☆★ 寫在前面 ★☆★
請通過目錄,選擇感興趣的部分閱讀。
★☆★ 本系列文章 ★☆★
【java】本地客戶端內(nèi)嵌瀏覽器1 - Swing、SWT、DJNativeSwing、javaFX 【java】本地客戶端內(nèi)嵌瀏覽器2 - chrome/chromium/cef/jcef 【java】本地客戶端內(nèi)嵌瀏覽器3 - Swing 使用 Spring 框架 + 打包項目 + 轉(zhuǎn)exe + 源碼
★☆★ 開源網(wǎng)址 ★☆★
https://github.com/supsunc/swing-jcef-spring
〇、寫本文章的目的
本人正在做的項目,本人想修改其架構(gòu),并付諸實現(xiàn),但最后被否定,不想因為修改架構(gòu)的努力付諸東流,遂寫本文。
一、項目簡介
為一個儀器開發(fā)可視化操控軟件,儀器方提供 C# 語言編寫的 dll,通過儀器方提供的接口進行操控。 本項目在最初設(shè)計架構(gòu)時,本人并沒有參與,本人介入該項目時,已確定采用 B/S 架構(gòu)。 Server 端用 Tomcat 做后臺,用 java 做開發(fā)語言。 通過 jni4net 對儀器方提供的 dll 進行二次封裝,進而得到后臺可以使用的 jar 包,進而操控儀器。 后臺使用的是 SpringMVC 框架。
服務(wù)器電腦安裝 jdk、Tomcat,服務(wù)器電腦安裝 Chrome 使用該軟件
用戶電腦安裝 jdk、Tomcat、chrome 使用該軟件
二、想法沖突
1、起因
軟件一階段測試時,提供給甲方一套文件,包括 32 位和 64 位的 jdk、Tomcat、Chrome,大約 600 MB 左右大小。我這邊領(lǐng)導(dǎo)居然要求提供一個 一鍵安裝 的那種文件,最后寫了兩個 .bat 文件,用一些 xcopy、setx 等方法。
這就導(dǎo)致了我認為儀器需要和用戶電腦相連,而操控儀器這種數(shù)據(jù)交互就要通過 Tomcat,走 http 協(xié)議。這樣不但作為開發(fā)者調(diào)用相關(guān)接口會很麻煩,對于用戶,安裝一堆軟件也很麻煩,且儀器必須和服務(wù)端在一起,而不能獨立出來。采用 B/S 架構(gòu),
2、構(gòu)思新架構(gòu)
主體架構(gòu)還是 B/S 架構(gòu),但是開發(fā)一個 Client,內(nèi)嵌 Chromium 內(nèi)核瀏覽器,由本地和儀器進行交互。
三、為新架構(gòu)而做的前期努力
0、前言
項目 B/S 架構(gòu)的 Browser 部分以 Chrome 的 Webkit 內(nèi)核做定制開發(fā),采用了 ES6、ES2016、ES2017、ES2018 相關(guān)語法,使用了一些 Webkit/Blink 內(nèi)核才支持的一些語法、方法等,所以開發(fā)的客戶端必須 內(nèi)置 Chromium 內(nèi)核。 由于調(diào)用 dll 已用 jni4net 生成相關(guān) jar 包,且制作的客戶端要求可移植,那么 使用 java 開發(fā)客戶端 是再好不過的了。 經(jīng)過前期探索發(fā)現(xiàn) Java 應(yīng)用程序用戶界面的開發(fā)工具包 Swing 好像不自帶 Browser 組件。
1、java 客戶端內(nèi)嵌瀏覽器之 Swing
參考鏈接:Swing 簡單的WEB瀏覽器
不具體操作講解了,代碼很簡單,將其網(wǎng)址改為 https://www.baidu.com/,并啟動程序,我整個人都傻了。
最大化窗口后,嘗試搜索點什么東西,點擊“百度一下”。 ???空白頁了?
2、java 客戶端內(nèi)嵌瀏覽器之 SWT
SWT.jar 包下載步驟,請參考【java】(org.eclipse.swt)SWT.jar 的下載步驟
新建項目,導(dǎo)入 jar 包,Add as Library,新建個 Main 方法。
直接分享源代碼,此處參考鏈接:java SWT Browser實現(xiàn)瀏覽器功能并運行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 內(nèi)核(哈哈,憑借這個右鍵菜單來判斷顯然是不現(xiàn)實的),我們的項目直接崩掉了。
其實是在實例化 Browser 對象時的入?yún)⒖刂屏耸褂玫膬?nèi)核。
Browser browser
= new Browser ( shell
, SWT
. NONE
) ;
Browser browser
= new Browser ( shell
, SWT
. MOZILLA
) ;
Browser browser
= new Browser ( shell
, SWT
. WEBKIT
) ;
使用 MOZILLA 內(nèi)核啟動程序的時候,控制臺會提示 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 內(nèi)核啟動程序的時候,哈哈,控制臺提示 Could not instantiate Browser: No more handles [Safari must be installed to use a SWT.WEBKIT-style Browser]。要求 必須安裝 Safari 瀏覽器,安裝 Chrome 是沒有用的 ,因為 webkit 內(nèi)核可以從 Safari 瀏覽器中剝離出來,從 Chrome 中剝離不出來。還有一點是 Windows 上的 Safari 瀏覽器好像是好久沒有更新了,其 Webkit 內(nèi)核版本也很低。
3、java 客戶端內(nèi)嵌瀏覽器之 Swing + SWT + DJNativeSwing
此部分參考鏈接:java使用swing實現(xiàn)內(nèi)嵌瀏覽器 DJNativeSwing 項目官網(wǎng):Native Swing DJNativeSwing 項目開發(fā)者日志:News Log DJNativeSwing 項目下載地址:The DJ Project DJNativeSwing 相關(guān) jar 包下載地址:DJNativeSwing-SWT-1-0-3-20140708.zip
主要使用這兩個 jar 包。
新建項目,導(dǎo)入 jar 包,Add as Library,新建個 Main 方法。
新建一個 package 叫做 browser,在里面新建一個 class 叫做 MyBrowser,直接分享源代碼,此處參考鏈接:java使用swing實現(xiàn)內(nèi)嵌瀏覽器
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實現(xiàn)內(nèi)嵌瀏覽器
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 的構(gòu)造方法中,可以發(fā)現(xiàn),其中第二行 WebBrowserRuntime runtime = WebBrowserRuntime.DEFAULT;規(guī)定了默認的內(nèi)核,如果無參構(gòu)造對象,則使用默認的內(nèi)核,應(yīng)該就是 IE 內(nèi)核。 和 SWT 一樣,是在實例化 JWebBrowser 對象時的入?yún)⒖刂屏耸褂玫膬?nèi)核。
JWebBrowser webBrowser
= new JWebBrowser ( ) ;
JWebBrowser webBrowser
= new JWebBrowser ( JWebBrowser
. useXULRunnerRuntime ( ) ) ;
JWebBrowser webBrowser
= new JWebBrowser ( JWebBrowser
. useWebkitRuntime ( ) ) ;
使用 MOZILLA 內(nèi)核啟動程序的時候,哈哈,這底層用的不還是 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 內(nèi)核啟動程序的時候,哈哈,實錘底層用的是 SWT ,注意看控制臺提示 No more handles [Safari must be installed to use a SWT.WEBKIT-style Browser]。要求 必須安裝 Safari 瀏覽器,安裝 Chrome 是沒有用的 ,原因在上面說過了。
4、java 客戶端內(nèi)嵌瀏覽器之 javaFX
能支撐我到現(xiàn)在還沒有放棄的原因是我在網(wǎng)上搜索到了,jdk1.8 自帶 javaFX ,而 javaFX 自帶瀏覽器組件,而且使用的是 WebKit HTML 技術(shù)的Web組件(請參考 JavaFX WebView概述,很強大,內(nèi)置了類似Electron的功能 ),且搜索到了很多關(guān)于 javafx 的很多文章和觀點,全都在 diss Swing,擁護 javaFX。
javaFX的幾個新特性,讓swing徹底過時
現(xiàn)在用Java寫UI,該用Swing還是JavaFX?
Swing那么受歡迎,為啥JavaFX屢被唱衰?
JavaFX與Swing框架相比,有哪些特點?
JavaFX實戰(zhàn) -- 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 ( ) ; }
}
將網(wǎng)址改成我們的項目網(wǎng)址,哇哇哇,沒崩,打開了。但是。。。 ???不大對勁啊。
正常 Chrome 這樣顯示:
javafx 內(nèi)嵌瀏覽器這樣顯示:
探查差異,在程序中打印 UserAgent
System
. out
. println ( webEngine
. getUserAgent ( ) ) ;
原來沒用 Chrome 的 Webkit 內(nèi)核,用的 Safari 的 Webkit 內(nèi)核,而且版本還挺高?
我看了一下,我電腦上最新版Chrome: Chrome 78.0.3904.70 版本的 UserAgent里寫著 Safari/537.36
然而我們的項目必須用 Chrome 的 Webkit 內(nèi)核,還得是高版本的。
總結(jié)
以上是生活随笔 為你收集整理的【java】本地客户端内嵌浏览器1 - Swing、SWT、DJNativeSwing、javaFX 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。