JCEF-tab形式展示浏览器(6)

当我们点击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<TabBrowser> tbList=new Vector<TabBrowser>();
    /**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的索引
     */
    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<tbList.size();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<tbList.size();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");
    }
}

本示例教程开源项目地址:
githubhttps://github.com/lieyanfeimao/JcefTest.git
码云https://gitee.com/edadmin/JcefTest.git

开源项目:

PowerOfLongedJcef【注:本项目在win10 64位系统上开发,不保证其他系统可以直接运行】

githubhttps://github.com/lieyanfeimao/PowerOfLongedJcef.git
码云https://gitee.com/edadmin/PowerOfLongedJcef.git

猜你喜欢

转载自blog.csdn.net/xymmwap/article/details/101199005