当我们点击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.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");
  }
  }