关于使用JCEF

您所在的位置:网站首页 java嵌入网页 关于使用JCEF

关于使用JCEF

2024-02-11 23:43| 来源: 网络整理| 查看: 265

为什么要使用JCEF了?因为我们发现有些基于Web的应用不是很稳定,在业务连续性方面还是有些缺陷,如果不想耗费精力和时间以及成本。使用基于Java应用的嵌入浏览器的方式反而是一种比较好的解决方案,可以通过集成Java应用以及websocket跟Web页面交互。

这篇文章主要是给大家开个头,个人精力有限,也借助了一些牛人开源的项目进行演练,本人主要还是起到抛砖引玉的作用,想要这篇文章达到技术水平至高的作业,请不要再继续浏览。

1.JCEF介绍(翻译来自xuanyimao)

Java Chromium嵌入式框架(JCEF)。 一个简单的框架,用于使用Java编程语言在其他应用程序中嵌入基于Chromium的浏览器

使用JCEF是为了用它开发自己的桌面应用程序。相对于vc,vb,swing这些,使用浏览器外壳,利用网络上众多流行的Web UI开源框架(如Easyui)做界面无疑是最快的,这可以让我们有更多的时间去实现业务逻辑,而不用被那些该死的UI控件折磨。想一想,原先做个表格,一整套界面做完大半天过去了,现在,引入JS、CSS,一瞬间做出一个高大上的界面,效率不言而喻。

初次接触JCEF,光是编译就花了一天时间。接着发现在网上找不到什么中文资料,利用空闲时间靠不断的网络搜索加翻译英文帮助文档了解它。断断续续到现在,终于做出了自己想要的软件。

https://github.com/chromiumembedded/java-cef

帮助文档

http://www.xuanyimao.com/jcef/index.html#pol

2.JCEF实战 2.1导入xuanyimao作者的源码到idea

https://gitee.com/edadmin/PowerOfLongedJcef

导入完后,设置JVM

在启动程序StartupApp设置JVM启动参数,加入-Djava.library.path=E:\learn\jcef\JcefTest\binary_win64(这个是binary_win64.zip解压后的目录,这个zip包含在gitee下载源码里面,也可以下载最新的zip包https://github.com/jcefbuild/jcefbuild/releases)

修改https://gitee.com/edadmin/PowerOfLongedJcef 这个项目的源码,主要修改下面两个:

MainFrame.java

package com.xuanyimao.polj.index; import java.awt.*; import java.io.File; import javax.swing.*; import org.cef.OS; import com.xuanyimao.polj.index.anno.JsClass; import com.xuanyimao.polj.index.bean.DevRepertory; /** * @Description: 启动窗口 * @author liuming */ @JsClass public class MainFrame extends JFrame { /** * */ private static final long serialVersionUID = -5550525843316817638L; private JButton[] jb = new JButton[9]; private JPanel jp1, jp2; public MainFrame() { jp1 = new JPanel(); jp2 = new JPanel(); jp1.setLayout(new FlowLayout()); Font font=new Font("宋体",Font.BOLD,60); jp1.setFont(font); jp2.setLayout(new BorderLayout()); jp2.setFont(font); jb[0] = new JButton("诸葛亮"); jb[0].setFont(font); jb[1] = new JButton("刘备"); jb[1].setFont(font); jb[2] = new JButton("关羽"); jb[2].setFont(font); jb[3] = new JButton("张飞"); jb[3].setFont(font); jb[4] = new JButton("赵云"); jb[4].setFont(font); jb[5] = new JButton("黄忠"); jb[5].setFont(font); jb[6] = new JButton("马超"); jb[6].setFont(font); jb[7] = new JButton("典韦"); jb[7].setFont(font); jb[8] = new JButton("许褚"); jb[8].setFont(font); jp1.add(jb[0]); jp1.add(jb[1]); jp1.add(jb[2]); jp1.add(jb[3]); jp1.add(jb[4]); jp2.add(jb[5], BorderLayout.CENTER); jp2.add(jb[6], BorderLayout.NORTH); jp2.add(jb[7], BorderLayout.WEST); jp2.add(jb[8], BorderLayout.EAST); this.setLayout(new BorderLayout()); this.add(jp1, BorderLayout.EAST); this.add(jp2, BorderLayout.SOUTH); //this.setTitle("你好啊!"); this.setSize(300, 600); this.setLocation(300, 600); //this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setResizable(false); this.setVisible(true); CefManager cmg=CefManager.getInstance(OS.isLinux(), false, this); cmg.createBrowser("file:///"+DevRepertory.getInstance().getAppPath()+"/index.html"); this.setExtendedState(JFrame.MAXIMIZED_BOTH); this.setTitle("PowerOfLongedJcef-玄翼猫-V1.0"); ImageIcon icon=new ImageIcon(DevRepertory.getInstance().getAppPath()+File.separator+"logo.png"); this.setIconImage(icon.getImage()); } }

CelManager.java

/** * http://www.xuanyimao.com * @author:liuming * @date: 2019年9月4日 * @version V1.0 */ package com.xuanyimao.polj.index; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.List; import java.util.Vector; import javax.swing.*; import org.apache.commons.lang.StringUtils; import org.cef.CefApp; import org.cef.CefApp.CefAppState; import org.cef.CefClient; import org.cef.CefSettings; import org.cef.browser.CefBrowser; import org.cef.browser.CefFrame; import org.cef.browser.CefMessageRouter; import org.cef.browser.CefMessageRouter.CefMessageRouterConfig; import org.cef.callback.CefQueryCallback; import org.cef.handler.CefAppHandlerAdapter; import org.cef.handler.CefMessageRouterHandler; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.xuanyimao.polj.index.bean.HandlerObject; import com.xuanyimao.polj.index.bean.TabBrowser; import com.xuanyimao.polj.index.handler.ContextMenuHandler; import com.xuanyimao.polj.index.handler.DisplayHandler; import com.xuanyimao.polj.index.handler.FileDownloadHandler; import com.xuanyimao.polj.index.handler.LifeSpanHandler; import com.xuanyimao.polj.index.handler.LoadHandler; import com.xuanyimao.polj.index.listener.TabCloseListener; import com.xuanyimao.polj.index.scanner.AnnotationScanner; /** * @Description: cef对象管理类 * “做人一定要脚踏实地,不要老想着和别人攀比,比来比去又得到了什么,让自己白白受累。百年后不过是一坯黄土,自己踏踏实实过好自己就行了。” * “还是你心态好啊~” * “也不是,主要是比不过。” * @author liuming */ public class CefManager{ private static CefManager mg; private CefManager(boolean useOSR,boolean isTransparent,JFrame frame) { String[] args=new String[] { "--enable-system-flash=true"//启用flash ,"--disable-web-security"//开启跨域 }; CefApp.addAppHandler(new CefAppHandlerAdapter(args) { @Override public void stateHasChanged(org.cef.CefApp.CefAppState state) { if (state == CefAppState.TERMINATED) System.exit(0); } }); this.useOSR=useOSR; this.isTransparent=isTransparent; CefSettings settings = new CefSettings(); settings.windowless_rendering_enabled = useOSR; //模拟手机 // settings.user_agent="Mozilla/5.0 & #40;Linux; U; Android 8.0.0; zh-CN; MI 6 Build/OPR1.170623.027& #41; AppleWebKit/537.36 & #40;KHTML, like Gecko& #41; Version/4.0 Chrome/69.0.3497.100 UWS/3.20.0.31 Mobile Safari/537.36 UCBS/3.20.0.31_190923233723 NebulaSDK/1.8.100112 Nebula AlipayDefined& #40;nt:WIFI,ws:360|0|3.0& #41; AliApp& #40;AP/10.1.75.7000& #41;"; cefApp= CefApp.getInstance(args,settings); client = cefApp.createClient(); //注册一些handler client.addLoadHandler(new LoadHandler()); client.addLifeSpanHandler(new LifeSpanHandler()); client.addDisplayHandler(new DisplayHandler()); client.addContextMenuHandler(new ContextMenuHandler()); client.addDownloadHandler(new FileDownloadHandler()); //添加js交互 jsActive(); tabbedPane=new JTabbedPane(JTabbedPane.TOP,JTabbedPane.SCROLL_TAB_LAYOUT); this.frame=frame; this.frame.getContentPane().add(tabbedPane, BorderLayout.CENTER); this.frame.pack(); this.frame.setSize(800, 600); this.frame.setVisible(true); this.frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); this.frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { JLabel label = new JLabel("确定退出系统?"); label.setFont(new Font("宋体", Font.BOLD, 40)); // 确定按钮 JButton btnYes = new JButton("可以了哦"); btnYes.setFont(new Font("宋体", Font.BOLD, 40)); btnYes.setForeground(Color.MAGENTA); // 否定按钮 JButton btnNo = new JButton("不行不行"); btnNo.setFont(new Font("宋体", Font.ITALIC, 40)); btnNo.setForeground(Color.PINK); // 按钮选项加入数组 Object[] options = { btnYes, btnNo }; //JOptionPane int option= JOptionPane.showConfirmDialog( frame, label, "提示 ",JOptionPane.YES_NO_OPTION); /* int option= JOptionPane.showOptionDialog(frame, label, "提示 ",JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); System.out.println("当前options是"+option);*/ if(option==JOptionPane.YES_OPTION) { closeAllBrowser(); CefApp.getInstance().dispose(); frame.dispose(); }else { return; } } }); } private CefManager() {} /** * 获取CefManager对象实例 * @author:liuming * @param useOSR * @param isTransparent * @param frame * @return */ public static CefManager getInstance(boolean useOSR,boolean isTransparent,JFrame frame) { if(mg==null) { mg=new CefManager( useOSR, isTransparent,frame); } return mg; } /** * 获取CefManager对象实例,在此方法之前必须在任意位置调用过getInstance(boolean useOSR,boolean isTransparent,JFrame frame) * @author:liuming * @return */ public static CefManager getInstance() { return mg; } private static CefApp cefApp; private static CefClient client; private JFrame frame; private boolean useOSR; private boolean isTransparent; private static JTabbedPane tabbedPane; private List tbList=new Vector(); private int tbIndex=0; private final static String TITLE_INFO="正在载入..."; /** * 获取CefClient对象 * @return client */ public static CefClient getClient() { return client; } /** * 获取Frame窗口对象 * @return frame */ public JFrame getFrame() { return frame; } /** * 获取TabBrowser对象集合 * @return tbList */ public List getTbList() { return tbList; } /** * 关闭所有浏览器窗口 * @author:liuming */ public void closeAllBrowser() { for(int i=tbList.size()-1;i>=0;i--) { TabBrowser tb=tbList.get(i); tb.getBrowser().close(true); tabbedPane.removeTabAt(i); System.out.println("移除索引为"+i+"的tab..."); } } /** * 根据url创建一个新的tab页 * @author:liuming * @param url * @return 最后一个tab的索引 */ public int createBrowser(String url) { CefBrowser browser = client.createBrowser(url, useOSR, isTransparent); tabbedPane.addTab(".", browser.getUIComponent()); int lastIndex=tabbedPane.getTabCount()-1; tbIndex++; //创建自定义tab栏 JPanel jp=new JPanel(); //设置panel为卡片布局 // jp.setLayout(new GridLayout(1, 1, 10, 0)); Font font=new Font("宋体",Font.BOLD,60); JLabel ltitle=new JLabel(TITLE_INFO); ltitle.setFont(font); JLabel lclose=new JLabel("X"); lclose.setFont(font); jp.setOpaque(false); ltitle.setHorizontalAlignment(JLabel.LEFT); lclose.setHorizontalAlignment(JLabel.RIGHT); jp.add(ltitle); jp.add(lclose); lclose.addMouseListener(new TabCloseListener(tbIndex)); tabbedPane.setTabComponentAt(lastIndex, jp); TabBrowser tb=new TabBrowser(tbIndex, browser, ltitle); tbList.add(tb); tabbedPane.setSelectedIndex(lastIndex); return lastIndex; } /** * 修改标题 * @author:liuming * @param browser * @param title */ public void updateTabTitle(CefBrowser browser,String title) { if(StringUtils.isNotBlank(title)) { if(title.length()>12) title=title.substring(0, 12)+"..."; for(TabBrowser tb:tbList) { if(tb.getBrowser()==browser) { tb.getTitle().setText(title); break; } } } } /** * 移除tab * @author:liuming * @param browser * @param index */ public void removeTab(CefBrowser browser,int index) { if(browser!=null) { for(int i=0;i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3