【java】本地客户端内嵌浏览器1 - Swing、SWT、DJNativeSwing、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

〇、写本文章的目的

本人正在做的项目,本人想修改其架构,并付诸实现,但最后被否定,不想因为修改架构的努力付诸东流,遂写本文。

一、项目简介

  1. 为一个仪器开发可视化操控软件,仪器方提供 C# 语言编写的 dll,通过仪器方提供的接口进行操控。
  2. 本项目在最初设计架构时,本人并没有参与,本人介入该项目时,已确定采用 B/S 架构。
  3. Server 端用 Tomcat 做后台,用 java 做开发语言。
  4. 通过 jni4net 对仪器方提供的 dll 进行二次封装,进而得到后台可以使用的 jar 包,进而操控仪器。
  5. 后台使用的是 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、前言
  1. 项目 B/S 架构的 Browser 部分以 Chrome 的 Webkit 内核做定制开发,采用了 ES6、ES2016、ES2017、ES2018 相关语法,使用了一些 Webkit/Blink 内核才支持的一些语法、方法等,所以开发的客户端必须 内置 Chromium 内核
  2. 由于调用 dll 已用 jni4net 生成相关 jar 包,且制作的客户端要求可移植,那么 使用 java 开发客户端 是再好不过的了。
  3. 经过前期探索发现 Java 应用程序用户界面的开发工具包 Swing 好像不自带 Browser 组件。
1、java 客户端内嵌浏览器之 Swing

参考链接:Swing 简单的WEB浏览器

不具体操作讲解了,代码很简单,将其网址改为 https://www.baidu.com/,并启动程序,我整个人都傻了。

???怎么酱紫

最大化窗口后,尝试搜索点什么东西,点击“百度一下”。
???空白页了?

整个人都傻了

2、java 客户端内嵌浏览器之 SWT

SWT.jar 包下载步骤,请参考【java】(org.eclipse.swt)SWT.jar 的下载步骤

  1. 新建项目,导入 jar 包,Add as Library,新建个 Main 方法。

SWT 之“新建个 Main 方法”

  1. 直接分享源代码,此处参考链接: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();
    }
}
  1. 运行之后,右键单击弹出菜单,感觉像是 IE 内核(哈哈,凭借这个右键菜单来判断显然是不现实的),我们的项目直接崩掉了。

SWT 内嵌浏览器好像是 IE 内核

  1. 其实是在实例化 Browser 对象时的入参控制了使用的内核。
Browser browser = new Browser(shell, SWT.NONE);	// 这应该是 IE 内核。
Browser browser = new Browser(shell, SWT.MOZILLA);	// 这应该是 MOZILLA 内核。
Browser browser = new Browser(shell, SWT.WEBKIT);	// 这应该是 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

MOZILLA  内核启动红字提示

  • 使用 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 内核版本也很低。

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

  1. 主要使用这两个 jar 包。

DJNativeSwing 相关 jar 包

  1. 新建项目,导入 jar 包,Add as Library,新建个 Main 方法。

DJNativeSwing 之“新建个 Main 方法”

  1. 新建一个 package 叫做 browser,在里面新建一个 class 叫做 MyBrowser,直接分享源代码,此处参考链接:java使用swing实现内嵌浏览器

DJNativeSwing 之 MyBrowser 类

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);
        //执行Js代码
        webBrowser.executeJavascript("alert('hello swing')");
    }
}
  1. 在 Main 类中新增方法 openForm,直接分享源代码,此处参考链接:java使用swing实现内嵌浏览器

DJNativeSwing 之 Main 方法

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);
    }

    /**
     * 在swing里内嵌浏览器
     *
     * @param url   要访问的url
     * @param 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();
    }
}
  1. 进入到 JWebBrowser 的构造方法中,可以发现,其中第二行 WebBrowserRuntime runtime = WebBrowserRuntime.DEFAULT;规定了默认的内核,如果无参构造对象,则使用默认的内核,应该就是 IE 内核。
  2. 和 SWT 一样,是在实例化 JWebBrowser 对象时的入参控制了使用的内核。
JWebBrowser webBrowser = new JWebBrowser();	// 这应该是 IE 内核。
JWebBrowser webBrowser = new JWebBrowser(JWebBrowser.useXULRunnerRuntime());	// 这应该是 MOZILLA 内核。
JWebBrowser webBrowser = new JWebBrowser(JWebBrowser.useWebkitRuntime());	// 这应该是 WEBKIT 内核。
  • 使用 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 是没有用的,原因在上面说过了。

WEBKIT 内核启动红字报错

4、java 客户端内嵌浏览器之 javaFX

能支撑我到现在还没有放弃的原因是我在网上搜索到了,jdk1.8 自带 javaFX ,而 javaFX 自带浏览器组件,而且使用的是 WebKit HTML 技术的Web组件(请参考 JavaFX WebView概述,很强大,内置了类似Electron的功能,且搜索到了很多关于 javafx 的很多文章和观点,全都在 diss Swing,拥护 javaFX。

  1. javaFX的几个新特性,让swing彻底过时

  2. 现在用Java写UI,该用Swing还是JavaFX?
    在这里插入图片描述

  3. Swing那么受欢迎,为啥JavaFX屡被唱衰?
    在这里插入图片描述

  4. JavaFX与Swing框架相比,有哪些特点?
    在这里插入图片描述

  5. JavaFX实战 -- 00. 为什么选择JavaFX?
    https://blog.csdn.net/chineseboytom/article/details/82557587

  1. 新建项目,新建个 Main 方法,继承自 Application。

javafx 之“新建个 Main 方法”

  1. 直接分享源代码,此处参考链接:用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();
    }
}
  1. 将网址改成我们的项目网址,哇哇哇,没崩,打开了。但是。。。 ???不大对劲啊。

正常 Chrome 这样显示:
正常 Chrome


javafx 内嵌浏览器这样显示:
javafx 内嵌浏览器

  1. 探查差异,在程序中打印 UserAgent
System.out.println(webEngine.getUserAgent());
// 打印结果如下(应该是一行显示,以空格分隔,我给它手动换行写在这里了)
// Mozilla/5.0 (Windows NT 10.0; Win64; x64)
// AppleWebKit/606.1 (KHTML, like Gecko)
// JavaFX/8.0
// Safari/606.1

原来没用 Chrome 的 Webkit 内核,用的 Safari 的 Webkit 内核,而且版本还挺高?

我看了一下,我电脑上最新版Chrome: Chrome 78.0.3904.70 版本的 UserAgent里写着 Safari/537.36
在这里插入图片描述

然而我们的项目必须用 Chrome 的 Webkit 内核,还得是高版本的。

  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值