JCEF-tab形式展示浏览器
当我们点击target值为_blank的链接时,JCEF默认以弹出窗口的形式打开新页面,要实现tab栏形式,可参考以下步骤
1.创建一个实现CefLifeSpanHandlerAdapter的类,重写onBeforePopup方法:根据url创建一个CefBrowser对象,将CefBrowser的UI组件设置到JTabbedPane
2.设置onBeforePopup方法的返回值为true,取消弹出窗口
注意:因为JTabbedPane默认没有关闭按钮,需要自己使用JPanel之类的组件实现
设计思路:打开新窗口时,在JTabbedPane里新建一个Tab,利用CefClient创建一个CefBrowser对象,并将CefBrowser的UI添加到Tab,显示新创建的Tab
JTabbedPane默认没有关闭按钮,我们自定义一个JPanel来实现标题栏和关闭按钮。JPanel包含两个JLabel标题,一个显示页面标题,一个显示“X”。为“X”添加单击事件监听器,当点击“X”时,销毁Tab关联的CefBrowser对象,移除Tab
这里先写一个实体类,用来保存Tab关闭时要用到的数据
TabBrowser
public class TabBrowser {
/**索引,与关闭按钮关联*/
private int index;
/**浏览器对象*/
private CefBrowser browser;
/**浏览器标题*/
private JLabel title;
/**
* 获取 索引,与关闭按钮关联
* @return index
*/
public int getIndex() {
return index;
}
/**
* 设置 索引,与关闭按钮关联
* @param index 索引,与关闭按钮关联
*/
public void setIndex(int index) {
this.index = index;
}
/**
* 获取浏览器对象
* @return browser
*/
public CefBrowser getBrowser() {
return browser;
}
/**
* 设置 浏览器对象
* @param browser browser
*/
public void setBrowser(CefBrowser browser) {
this.browser = browser;
}
/**
* 设置浏览器标题
* @return title
*/
public JLabel getTitle() {
return title;
}
/**
* 设置 浏览器标题
* @param title 浏览器标题
*/
public void setTitle(JLabel title) {
this.title = title;
}
/**
* @param index
* @param browser
* @param title
*/
public TabBrowser(int index, CefBrowser browser, JLabel title) {
super();
this.index = index;
this.browser = browser;
this.title = title;
}
}
创建一个处理标题更新的Handler
DisplayHandler
public class DisplayHandler extends CefDisplayHandlerAdapter {
private TabbedPaneTestFrame frame;
public DisplayHandler(TabbedPaneTestFrame frame) {
this.frame=frame;
}
/* (non-Javadoc)
* @see org.cef.handler.CefDisplayHandlerAdapter#onTitleChange(org.cef.browser.CefBrowser, java.lang.String)
*/
@Override
public void onTitleChange(CefBrowser browser, String title) {
this.frame.updateTabTitle(browser, title);
// super.onTitleChange(arg0, arg1);
}
}
创建一个处理弹出窗口的Handler
LifeSpanHandler
public class LifeSpanHandler extends CefLifeSpanHandlerAdapter {
private TabbedPaneTestFrame frame;
public LifeSpanHandler(TabbedPaneTestFrame frame) {
this.frame=frame;
}
/* (non-Javadoc)
* @see org.cef.handler.CefLifeSpanHandlerAdapter#onBeforePopup(org.cef.browser.CefBrowser, org.cef.browser.CefFrame, java.lang.String, java.lang.String)
*/
@Override
public boolean onBeforePopup(CefBrowser browser, CefFrame frame, String target_url, String target_frame_name) {
this.frame.createBrowser(target_url);
//返回true表示取消弹出窗口
return true;
}
}
创建一个点击关闭按钮的监听器
TabCloseListener
public class TabCloseListener implements MouseListener{
private int index;
private TabbedPaneTestFrame frame;
public TabCloseListener(int index,TabbedPaneTestFrame frame) {
this.index=index;
this.frame=frame;
}
/* (non-Javadoc)
* @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
*/
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("点击了关闭事件...");
frame.removeTab(null, index);
}
/* (non-Javadoc)
* @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
*/
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
*/
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
*/
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
*/
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
主类代码
TabbedPaneTestFrame
public class TabbedPaneTestFrame extends JFrame{
/**
*
*/
private static final long serialVersionUID = 871314861019393323L;
private static CefApp cefApp;
private static CefClient cefClient;
private boolean useOSR;
private boolean isTransparent;
/**tabbedPane对象*/
private static JTabbedPane tabbedPane;
/**TabBrowser对象列表**/
private List tbList=new Vector();
/**tab使用的索引。此索引不是tab在tabbedpane中的索引,此索引用来移除tab栏**/
private int tbIndex=0;
/**默认的标题名*/
private final static String TITLE_INFO="正在载入...";
public TabbedPaneTestFrame(String url) {
//是否Linux系统
useOSR=OS.isLinux();
//是否透明
isTransparent=false;
//添加Handler,在CEFAPP状态为终止时退出程序
CefApp.addAppHandler(new CefAppHandlerAdapter(null) {
@Override
public void stateHasChanged(org.cef.CefApp.CefAppState state) {
// Shutdown the app if the native CEF part is terminated
if (state == CefAppState.TERMINATED) System.exit(0);
}
});
CefSettings settings = new CefSettings();
settings.windowless_rendering_enabled = useOSR;
//获取CefApp实例
cefApp=CefApp.getInstance(settings);
//创建客户端实例
cefClient = cefApp.createClient();
//添加鼠标右键菜单handler
cefClient.addContextMenuHandler(new MenuHandler());
//添加浏览器标题更改handler
cefClient.addDisplayHandler(new DisplayHandler(this));
//添加浏览器窗口弹出handler
cefClient.addLifeSpanHandler(new LifeSpanHandler(this));
tabbedPane=new JTabbedPane(JTabbedPane.TOP,JTabbedPane.SCROLL_TAB_LAYOUT);
getContentPane().add(tabbedPane, BorderLayout.CENTER);
pack();
setTitle("测试JCEF-Tab栏");
setSize(800, 600);
setVisible(true);
//添加一个窗口关闭监听事件
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
closeAllBrowser();
CefApp.getInstance().dispose();
dispose();
}
});
createBrowser("http://www.baidu.com");
}
/**
* 关闭所有浏览器
* @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的索引
*/无锡人流医院哪家好 http://www.bhnnkyy120.com/
public int createBrowser(String url) {
CefBrowser browser = cefClient.createBrowser(url, useOSR, isTransparent);
tabbedPane.addTab(".", browser.getUIComponent());
int lastIndex=tabbedPane.getTabCount()-1;
tbIndex++;
//创建自定义tab栏
JPanel jp=new JPanel();
JLabel ltitle=new JLabel(TITLE_INFO);
JLabel lclose=new JLabel("X");
jp.setOpaque(false);
ltitle.setHorizontalAlignment(JLabel.LEFT);
lclose.setHorizontalAlignment(JLabel.RIGHT);
jp.add(ltitle);
jp.add(lclose);
//添加关闭按钮监听事件
lclose.addMouseListener(new TabCloseListener(tbIndex,this));
//设置tab栏标题的关键句
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(title!=null && !"".equals(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
TabBrowser tb=tbList.get(i);
if(tb.getBrowser()==browser) {
tb.getBrowser().close(true);
tabbedPane.removeTabAt(i);
tbList.remove(i);
// System.out.println("移除索引为"+i+"的tab");
break;
}
}
}else {
for(int i=0;i
TabBrowser tb=tbList.get(i);
if(tb.getIndex()==index) {
tb.getBrowser().close(true);
tabbedPane.removeTabAt(i);
tbList.remove(i);
// System.out.println("移除索引为"+i+"的tab");
break;
}
}
}
}
public static void main(String[] args) {
new TabbedPaneTestFrame("http://www.baidu.com");
}
}
JCEF-tab形式展示浏览器的更多相关文章
- EasyNVR摄像机网页无插件直播方案H5前端构建之:使用BootstrapPagination以分页形式展示数据信息
背景介绍 EasyNVR核心在于摄像机的音视频流的获取.转换.转码与高性能分发,同时同步完成对实时直播流的录像存储,在客户端(PC浏览器.Android.iOS.微信)进行录像文件的检索.回放和下载. ...
- redis 一二事 - 设置过期时间,以文件夹形式展示key显示缓存数据
在使用redis时,有时回存在大量数据的时候,而且分类相同,ID相同 可以使用hset来设置,这样有一个大类和一个小分类和一个value组成 但是hset不能设置过期时间 过期时间只能在set上设置 ...
- Easyui 实现点击不同树节点打开不同tab页展示不同datagrid表数据设计
实现点击不同树节点打开不同tab页展示不同datagrid表数据设计 by:授客 QQ:1033553122 测试环境 jquery-easyui-1.5.3 需求描述 如上图, 1.点击左侧树,叶子 ...
- 获取url中的参数并以对象的形式展示出来
速记:获取url中的参数并以对象的形式展示出来 function getUrlData(){ let url=window.location.search;//url中?之后的部分 console.l ...
- javascript 如何打印、输出数组内容(将数组内容以字符串的形式展示出来)
1.情景展示 在实际开发过程中,为了调试,有时我们需要看数组中具体包含了哪些数据,但是, 如果我们直接打印该数组对象,显示的结果却不是我们想要的. 如何才能将数组内容打印出来呢?(将数组内容以 ...
- 以打字形式展示placeholder的插件
http://weber.pub/以打字形式展示placeholder的插件/197.html
- EasyNVR RTSP转RTMP-HLS流媒体服务器前端构建之:使用BootstrapPagination以分页形式展示数据信息
上一篇介绍通过接口来获取数据,本篇将介绍如何以分页形式展示出接口获取到的数据 获取到的数据往往会很多,为了追去页面的美观和方便用户的检索,需要进行分页的展示: EasyNVR可接如多通道,当我们的通道 ...
- 查询表格——建立动态表格,使用ajax输入查询条件将后台数据查询出来以表格的形式展示出来
建立动态表格,使用ajax将前台查询条件传给后台,并将查询结果以表格的形式展示出来. 页面的展示效果如下图所示: 第一步:查询条件的部分: 代码如下: <div class="text ...
- 基于Vue、Bootstrap的Tab形式的进度展示
最近基于Vue.Bootstrap做了一个箭头样式的进度展示的单页应用,并且支持了对于一个本地JS文件的检索,通过这个单页应用,对于Vue的理解又深入了一些.在这里把主要的代码分享出来. 本单页应用实 ...
随机推荐
- POJ2536-Gopher II-(匈牙利算法)
题意:n只老鼠,m个洞,s秒逃命,逃命速度为v,一个洞只能保住一只老鼠,最少多少只老鼠会被老鹰抓到. 题解:找出每只老鼠有哪些洞可以保命,建立二分图,算出最大匹配,不是求保住命的老鼠,而是求被抓住的老 ...
- NetworkManager需要与不需要
需要: 1.nmcli配置网络 不需要: 1. ifcfg-eth1:0(网卡的子接口配置文件)生效
- 洛谷 P1807 最长路_NOI导刊2010提高(07)题解
相当与一个拓扑排序的模板题吧 蒟蒻的辛酸史 题目大意:给你一个有向无环图,让你求出1到n的最长路,如果没有路径,就输出-1 思路:一开始以为是一个很裸的拓扑排序 就不看题目,直接打了一遍拓扑排序 然后 ...
- Google Spreadsheet Add-on Links Extractor 谷歌表格插件链接提取器的制作与发布(附源码)
引言 为什么想到制作这么一个插件呢,是因为博主在更新微信公众号[刷尽天下]的后台数据库时,需要有博客园题目帖子的链接,那么就要从这篇帖子 LeetCode All in One 题目讲解汇总(持续更新 ...
- 在eclipse中新建java问题报错:The type XXX cannot be resolved. It is indirectly referenced from required .class files
在Eclipse中遇到The type XXX cannot be resolved. It is indirectly referenced from required .class files错误 ...
- 常用STL使用指北
常用STL使用指北 set和multiset set和multiset都是基于红黑树(显然是一个二叉搜索树)的STL. 定义 我们可以使用(multi)set<元素类型>名称来定义一个(m ...
- 分布式系统全局唯一ID生成
一 什么是分布式系统唯一ID 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识. 如在金融.电商.支付.等产品的系统中,数据日渐增长,对数据分库分表后需要有一个唯一ID来标识一条数据或消息, ...
- [Gamma] 发布说明
[Gamma] 发布说明 发布网址为http://60.205.230.0 新功能前瞻 团队合作:支持多人合作完成项目 项目进度管理:便于监控项目进度 站内信系统:团队合作与审核需要 已知BUG修复 ...
- Hyperledger Fabric 1.4 快速环境搭建
自己的硕士研究方向和区块链有关,工程上一直以IBM的Hyperledger Fabric为基础进行开发,对该项目关注也有两年了.目前迎来了Hyperledger Fabric v1.4,这也是Fabr ...
- Python 2 代码转 Python 3的一些转化
Python 2 代码转 Python 3的一些转化 1.“print X” 更改为“print(X)” 2.xrange改为range 3.m.itervalues() 改为 m.values() ...