基于JxBrowser的浏览器控件封装实现Java Swing的浏览器集成

  • 背景
  • 实现目标
  • 实现代码
  • 运行效果
  • 完整的代码及依赖jar文件下载

背景

进期客户提出在一个Java Swing项目要集成另外2个系统:
1、集成Fine Report(基于Java Web发布的)要能打印、另存pdf|Excel。
2、集成质检报告系统,主要都是基于Web的图片,要能缩放查看。
基于以上2个要求,我们首先想到的是在JavaSwing中的JFrame中能嵌入一个浏览器控件,再通过浏览器加载Web url实现以上2个需求。经过一番搜索,了解到Java FX有Web View实现了浏览器的基本功能,而Java FX的控件需要以交互模式集成到Java Swing中,经过一番努力终于完成。进行测试才发现Java FX的WebView控件功能太弱了,首先在嵌入Fine Report的报表后能正常显示,但是另存、下载、打印都失效了,而且也不能缩放查看图片。最终智能放弃此方案。又重新从网上搜索发现一个控件JxBrowser(付费的),经过一番集成测试,终于在6.5.1版本上实现了以上2个目标,再高的版本是有问题。下面就把封装实现代码分享一下。

实现目标

1、基于JxBrowser6.5.1封装的浏览器控件(内置破解,仅用于个人学习)。
2、适用于在Java Swing应用中嵌入Web页面,并实现java与javascript的交互。
3、支持嵌入服务器页面,支持页面中的附件下载、报表打印、另存等功能。
4、支持嵌入帆软报表。
5、支持Ctrl+鼠标滚轮实现页面缩放

实现代码

1、破解文件(src/META-INF/teamdev.licenses),仅供个人学习,力所能及请付费购买(https://www.teamdev.com/jxbrowser)

Product: JxBrowser
Version: 6.x
Licensed to:
License type: Enterprise
License info: JxBrowser License
Expiration date: 01-01-9999
Support expiration date: NO SUPPORT
Generation date: 01-01-1970
Platforms: win32/x86;win32/x64;mac/x86;mac/x64;linux/x86;linux/x64
Company name: TeamDev Ltd.
SigB: 1
SigA: 1

2、封装号的浏览器控件(com.controls.WebBrowser.java)

package com.controls;import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigInteger;import javax.swing.JOptionPane;
import javax.swing.JPanel;import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.CloseStatus;
import com.teamdev.jxbrowser.chromium.UnloadDialogParams;
import com.teamdev.jxbrowser.chromium.swing.BrowserView;
import com.teamdev.jxbrowser.chromium.swing.DefaultDialogHandler;/*** 功能说明:基于jxBrowser的自定义浏览器控件 修改说明:* * @author zhenglibing* @date 2019年7月5日 下午1:58:32* @version 0.1*/
public class WebBrowser extends JPanel {private static final long serialVersionUID = 1L;private String url = "http://www.baidu.com";private boolean ZoomingFlag = false; // 是否正在缩放,按下Ctrl键变为true,释放Ctrl键变为false// 25% : "default_zoom_level": -7.6035680338478615,// 33% : "default_zoom_level": -6.0311726618503405,// 50% : "default_zoom_level": -3.8017840169239308,// 67% : "default_zoom_level": -2.2293886449264093,// 75% : "default_zoom_level": -1.5778829311823859,// 90% : "default_zoom_level": -0.5778829311823857,// 100% : "default_zoom_level": 0.0,// 110% : "default_zoom_level": 0.5227586988632231,// 125% : "default_zoom_level": 1.2239010857415449,// 150% : "default_zoom_level": 2.223901085741545,// 175% : "default_zoom_level": 3.069389038663465,// 200% : "default_zoom_level": 3.8017840169239308,// 250% : "default_zoom_level": 5.025685102665476,// 300% : "default_zoom_level": 6.025685102665476,// 400% : "default_zoom_level": 7.6035680338478615,// 500% : "default_zoom_level": 8.827469119589406// 定义缩放级别值数组private double[] levels = { -7.6035680338478615, -6.0311726618503405, -3.8017840169239308, -2.2293886449264093,-1.5778829311823859, -0.5778829311823857, 0.0, 0.5227586988632231, 1.2239010857415449, 2.223901085741545,3.069389038663465, 3.8017840169239308, 5.025685102665476, 6.025685102665476, 7.6035680338478615,8.827469119589406 };private String[] strLevels = { "25%", "33%", "50%", "67%", "75%", "90%", "100%", "110%", "125%", "150%", "175%","200%", "250%", "300%", "400%", "500%" };private long lastWheelTime = 0; // 最后滚动鼠标滚轮的时间private Browser browser; // 浏览器对象,需引用jxbrowserprivate BrowserView view; // 浏览器视图对象,需引擎jxbrowser// 以下代码用于破解jxbrowserstatic {try {Class claz = null;//6.5.1版本破解 兼容xpclaz = Class.forName("com.teamdev.jxbrowser.chromium.aq");// 6.21版本破解 默认使用最新的6.21版本// claz = Class.forName("com.teamdev.jxbrowser.chromium.ba");// 6.23版本破解//claz = Class.forName("com.teamdev.jxbrowser.chromium.bb");Field e = claz.getDeclaredField("e");Field f = claz.getDeclaredField("f");e.setAccessible(true);f.setAccessible(true);Field modifersField = Field.class.getDeclaredField("modifiers");modifersField.setAccessible(true);modifersField.setInt(e, e.getModifiers() & ~Modifier.FINAL);modifersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);e.set(null, new BigInteger("1"));f.set(null, new BigInteger("1"));modifersField.setAccessible(false);} catch (Exception e) {e.printStackTrace();System.out.println("执行jxbrowser破解程序时出现异常" + e.getMessage());}}/*** 默认构造方法*/public WebBrowser() {this.init();}/*** 构造方法重载* * @param url*            浏览器默认加载的url地址*/public WebBrowser(String url) {this.url = url.startsWith("http://") ? url : "http://" + url;this.init();}/*** 功能说明:初始化jxBrowser 修改说明:* * @author zhenglibing* @date 2019年7月5日 下午2:28:27*/private void init() {this.browser = new Browser();this.view = new BrowserView(browser);this.setLayout(new BorderLayout());this.add(view, BorderLayout.CENTER);this.browser.loadURL(this.url);// 以下代码支持鼠标拖拽超链接内容this.browser.setDialogHandler(new DefaultDialogHandler(view) {@Overridepublic CloseStatus onBeforeUnload(UnloadDialogParams params) {String title = "Confirm Navigation";String message = params.getMessage();int returnValue = JOptionPane.showConfirmDialog(view, message, title, JOptionPane.OK_CANCEL_OPTION);if (returnValue == JOptionPane.OK_OPTION) {return CloseStatus.OK;} else {return CloseStatus.CANCEL;}}});this.browser.loadHTML("<html><body οnbefοreunlοad='return myFunction()'>"+ "<a href='http://www.baidu.com'>Click here to leave</a>"+ "<script>function myFunction() { return 'Leave this web page?'; }" + "</script></body></html>");// 以下代码支持Ctrl + 鼠标滚轮实现页面放大缩小// 注册键盘按下事件this.view.addKeyListener(new KeyListener() {@Overridepublic void keyTyped(KeyEvent e) {// TODO Auto-generated method stub}/*** 键盘按下*/@Overridepublic void keyPressed(KeyEvent e) {// TODO Auto-generated method stubif (e.getKeyCode() == 17) {ZoomingFlag = true;}}/*** 键盘释放*/@Overridepublic void keyReleased(KeyEvent e) {// TODO Auto-generated method stubSystem.out.println("keyReleased");ZoomingFlag = false;}});// 注册鼠标滚轮事件this.view.addMouseWheelListener(new MouseWheelListener() {@Overridepublic void mouseWheelMoved(MouseWheelEvent e) {//              System.out.println(e.getScrollAmount());if (e.getScrollAmount() != 3 || e.getWhen() - lastWheelTime < 20) {// 滚动太快则过滤一下// System.out.println("过滤...");return;}
//              System.out.println("getWhen = " + e.getWhen());
//              System.out.println("lastWheelTime = " + lastWheelTime);if (e.getScrollAmount() == 3 && ZoomingFlag) {double currZoomLevel = browser.getZoomLevel();if (e.getWheelRotation() == -1) {// 加for (int i = 0; i < levels.length; i++) {if (currZoomLevel == levels[i]) {if (i < levels.length - 1) {browser.setZoomLevel(levels[i + 1]);System.out.println("当前缩放级别:" + strLevels[i + 1]);}break;}}System.out.println("放大");} else if (e.getWheelRotation() == 1) {// 减for (int i = 1; i < levels.length; i++) {if (currZoomLevel == levels[i]) {if (i > 0) {browser.setZoomLevel(levels[i - 1]);System.out.println("当前缩放级别:" + strLevels[i - 1]);}break;}}System.out.println("缩小");}// 记录最后一次滚轮时间if (lastWheelTime != e.getWhen()) {lastWheelTime = e.getWhen();}}}});}/*** 功能说明:获取浏览器访问的url地址* 修改说明:* @author zhenglibing* @date 2019年7月9日 下午2:32:39* @return*/public String getURL() {if (null != this.browser) {return this.browser.getURL();}else{return "";}}/*** 功能说明:swing方法,设置浏览器访问的url地址 修改说明:* * @author zhenglibing* @date 2019年7月5日 下午2:30:13* @param urlString*/public void setURL(final String urlString) {if (null == urlString || "".equals(urlString)) {this.browser.loadURL("");this.browser.loadHTML("");} else {String oldUrl = this.browser.getURL();if (!urlString.equals(oldUrl)) {this.browser.loadURL(urlString);} else {this.browser.reload();}}}/*** 功能说明:swing方法,设置浏览器的html内容 修改说明:* * @author zhenglibing* @date 2019年7月5日 下午5:34:12* @param htmlContent*/public void setContent(final String htmlContent) {this.browser.loadHTML(htmlContent);}/*** 功能说明:swing方法,清空浏览器的内容 修改说明:* * @author zhenglibing* @date 2019年7月5日 下午5:33:42*/public void clear() {this.setURL("");}/*** 功能说明:获取浏览器类型信息 修改说明:* * @author zhenglibing* @date 2019年7月5日 下午5:32:54* @return*/public String getBrowserType() {return "jxBrowser" + "v6.23.1";}/*** 功能说明:资源释放方法 修改说明:* * @author zhenglibing* @date 2019年7月5日 下午5:33:21*/public void dispose() {}
}

3、测试启动类(com.controls.Start.java)

package com.controls;import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;import javax.swing.JButton;
import javax.swing.JFrame;public class Start {private static String title = "浏览器测试";private static String url = "https://www.baidu.com";public static void main(String[] args) {if (args.length >= 2) {title = args[0];url = args[1];}else if (args.length == 1) {url = args[0];}JFrame frm = new JFrame(title);frm.setSize(800,600);frm.setExtendedState(JFrame.MAXIMIZED_BOTH);WebBrowser browser = new WebBrowser();browser.setSize(800, 600);browser.setVisible(true);frm.add(browser, BorderLayout.CENTER);frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frm.setVisible(true);browser.setURL(url);}}

运行效果

完整的代码及依赖jar文件下载

完整的代码及依赖jar文件下载

基于JxBrowser的浏览器控件封装实现Java Swing的浏览器集成相关推荐

  1. java程序获取外部java程序的控件,将 Java 小程序迁移到 Microsoft J# 浏览器控件-JSP教程,Java技巧及代码...

    visual j# .net 小组 microsoft corporation 摘要:通过 microsoft j# 浏览器控件,开发人员可以将所编写的在 java 虚拟机上运行的 java 小程序迁 ...

  2. java浏览器下载_Java浏览器控件下载-JxBrowser(Java浏览器控件)官方下载[Java控件]-天极下载...

    用于Windows的Chromium 64位二进制文件仅支持Windows 64位环境,无法在Windows 32位上使用.哪一个被使用? 它取决于Windows体系结构和Java应用程序类路径. j ...

  3. C# .NET 6.0已经取消了Framework 4.8的WebBrowser控件,几款NuGet中的浏览器控件介绍

    即使在C# .NET 6.0..NET 7.0在选择工具箱项COM组件添加Microsoft Web Browser,工具箱也没有WebBrowser控件. WebBrowser控件: WebBrow ...

  4. python webkit内核_Winform调用WebKitBrowser,基于chrome内核WebKit的浏览器控件

    在C#中,默认的WebBrowser控件默认使用的是IE的core,而IE的种种遭人吐槽的诟病使我不敢轻易使用WebBrowser,因此,打算使用Chrome的内核替换IE.Chrome的内核使用的是 ...

  5. 基于 next.js + mdx 搭建组件库文档项目(二) -- mdx 控件封装实现组件的演示与 Props 列表

    说明 经过上阶段的配置虽然可以在项目中使用 mdx 语法 来创建页面了,但是我们的组件库有一些定制化的需求:交互式的组件演示.组件 Props 列表展示.这些功能如果可以通过封装来实现,会大大提升开发 ...

  6. java浏览器fx,浏览器控件JxBrowser JavaFX开发快速入门指南

    要求:JDK 1.8及更高版本. 1.下载JxBrowser库 下载JxBrowser 将下载的归档文件解压到某个目录(例如D:\ Projects \ MyProject \)中. 当你解压缩档案时 ...

  7. 属性浏览器控件QtTreePropertyBrowser编译成动态库(设计师插件)

    文章目录 一.回顾 二.动态库编译 1.命令行编译动态库和测试程序 2.vs工具编译动态库和测试程序 3.安装文档 4.测试文档 三.设计师插件编译 1.重写QDesignerCustomWidget ...

  8. Silverlight4.0教程之WebBrowser控件(Silverlight内置HTML浏览器控件)

    微软于PDC2009上发布Silverlight 4 Beta版,微软在Silverlight 4版本中处理了约8000个的Silverlight终端用户的请求,加入了一系列另开发人员兴奋的新特性,最 ...

  9. CEF中文教程(google chrome浏览器控件) -- CEF简介

    官方主页:  点击打开链接 CEF简介: 嵌入式Chromium框架(简称CEF) 是一个由Marshall Greenblatt在2008建立的开源项目,它主要目的是开发一个基于Google Chr ...

最新文章

  1. python界面是什么样子的图片_如何在python界面显示图片
  2. java 集成grizzly_java – 在Grizzly上使用JaaS和Jersey
  3. Redis 命令参考
  4. Java String类型变量的比较问题
  5. C和汇编混合编程----实现浮点数的加减乘除
  6. SpringBoot2 整合 ClickHouse数据库,实现高性能数据查询分析
  7. [导入]如何动态生成table(javascript)
  8. linux查看服务状态
  9. c语言中L''作用,L/C问题: 请问L/C上的49:Confirmation Instruction 有什么作用啊[1]
  10. WPF 图片splashScreen效果
  11. 《腾讯Android自动化测试实战》— Android 书籍
  12. Integrity数据库简介
  13. Facebook想要成为下一个微信,难! 1
  14. 搜狗2016年校招笔试编程题记录+总结
  15. 小 tips:删除word表格下面多余的空白页
  16. android端向后台传图片,Android前台从后台下载一张图片 以及 Android前台上传一张图片到后台...
  17. 想用自己电脑做服务器并且绑定域名建一个个人网站应该怎么做
  18. OpenLayers 加载天地图模糊的问题 OpenLayers 地图缩放模糊
  19. RabbitMQ Topic模式
  20. boss直聘__zp_stoken__逆向分析2021.10版

热门文章

  1. 《合约星期五》OKEx季度0906期合约周报:多军空军大单换手吸筹三日迅速拉升突破10000美金大关
  2. oracle大写数字转小写,oracle数据库使用游标实现大写数字转换成小写数字
  3. 中国汽车市场年鉴(1995-2021)
  4. python 处理服务器响应数据包,Python如何解析RADIUS服务器数据包?
  5. 微信H5支付功能小结
  6. telnet 工具linux下载,alpine安装telnet等工具,
  7. 每次开机弹出 startUp Application的解决方法
  8. Linux查看版本当前操作系统信息
  9. js内存释放和作用域销毁
  10. 递归删除带内容的目录