JCEF 初体验一,快捷键打开开发者工具

前言

由于本人接触项目需要开发客户端程序,同时前端页面通过VUE编写,还需要对接第三方的厂家的相关接口;之前采用的是C#+VUE来实现,现在想更改技术方案,所以选择了Java和VUE来实现,通过JCEF框架来显示页面。

准备工作

JCEF编译jar包

此仓库中含有windows32位和64位的编译jar包,需要的可自行下载
https://gitee.com/liangmengcheng/jcef

一个spring项目

主要是红框中的四个
image

添加库文件

将jcef相关的jar包添加为库文件

可以直接在jcefx86文件夹上右击,添加为库
image

将jcef中的win32文件夹或win64文件夹添加到库中

1、进入项目结构,左侧选择库
2、中间项选中添加的jcefx86,如果没有,可以点击上方加号进行添加
3、在弹窗中选择jcefx86->lib->win32文件夹,点击确定
image
4、在右侧出现此项及为完成
image

代码编写

添加 jcef 浏览器对象关键代码

打开MyBrowser文件,加入以下代码,代码已添加相关注释

点击查看代码
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.handler.CefAppHandlerAdapter;
import org.cef.handler.CefDisplayHandlerAdapter;
import org.cef.handler.CefFocusHandlerAdapter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import top.whitelies_7.handler.KeyboardHandler;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


public class MyBrowser extends JFrame {

    // CEF 程序的全局管理类
    private final CefApp cefApp_;
    // CEF 客户端程序类
    private final CefClient cefClient_;
    // 浏览器对象类,一个客户端会有多个浏览器
    private final CefBrowser cefBrowser_;
    private final Component cefBrowserUI_;
    // 窗体当前是否获得焦点
    private boolean cefBrowserFocus_ = true;
    // 一个文本框对象,用于获取地址栏输入框的值
//    private final JTextField address_;

    /**
     * 要显示一个简单的浏览器窗口,只需创建一个类 CefBrowser 的实例并将其 UI 组件分配给应用程序(例如,分配给内容窗格)就足够了。
     *
     * @param startURL      启动的页面地址,可以是网络地址,也可以是一个本地 html 文件地址
     * @param useOSR        是否以无窗口模式启动
     * @param isTransparent 是否透明
     * @param args
     */
    public MyBrowser(String startURL, boolean useOSR, boolean isTransparent, String[] args) {
        /* 1、
            JCEF 的入口点总是类 CefApp。每个应用程序只有一个实例,因此必须调用
            方法"getInstance()"而不是一个 CTOR。
            CefApp 负责全局 CEF 上下文。它加载所有必需的本地库,相应地初始化 CEF,
            启动后台任务来处理 CEF 的消息循环,并在处理完后关闭 CEF。
        */
        CefApp.addAppHandler(new CefAppHandlerAdapter(args) {
            @Override
            // 实现此方法以获取CefApp的状态更改。
            public void stateHasChanged(CefApp.CefAppState cefAppState) {
                // 如果本机 CEF 部分终止,则关闭整个应用程序
                if (cefAppState == CefAppState.TERMINATED) {
                    System.exit(0);
                }
            }
        });
        CefSettings settings = new CefSettings();
        settings.windowless_rendering_enabled = useOSR;
        cefApp_ = CefApp.getInstance(settings);

        /* 2、
             JCEF 可以同时处理一到多个浏览器实例。这些浏览器实例按类 CefClient 的实例在逻辑上分组在一起。
             在您的应用程序中,您可以创建一到多个 CefClient 实例,每个客户端有一到多个 CefBrowser 实例。
             要获取 CefClient 的实例,必须使用 CefApp 实例的方法"createClient()"。不支持调用 CefClient 的 CTOR。

             CefClient 是连接来自 CefBrowser 实例的所有可能事件的连接器。
             这些事件可以是诸如更改浏览器标题之类的简单事件,也可以是诸如上下文菜单事件之类的更复杂事件。
             通过将处理程序分配给 CefClient,您可以控制浏览器的行为。有关如何使用这些处理程序的示例,请参见 tests.detailed.MyFrameTest。
        */
        cefClient_ = cefApp_.createClient();

        /* 3、
            一个 CefBrowser 实例负责控制在该实例的 UI 组件上看到的内容。
             它可以显示屏幕外渲染或窗口渲染。要获取 CefBrowser 实例,必须调用 CefClient 实例的方法"createBrowser()"。

             CefBrowser 有"goBack()"、"goForward()"、"loadURL()"等方法,这些方法用于控制显示内容的行为。
             该 UI 保存在 UI 组件中,可以通过调用 CefBrowser 实例上的方法"getUIComponent()"来访问该 UI 组件。
             UI 组件继承自java.awt.Component,因此可以嵌入到任何 AWT UI 中。
        */
        cefBrowser_ = cefClient_.createBrowser(startURL, useOSR, isTransparent);
        cefBrowserUI_ = cefBrowser_.getUIComponent();
        cefBrowserUI_.setBackground(new Color(255, 192, 203, 138));

        /* 4、
            对于这个最小的浏览器,我们只需要一个文本字段来输入我们要导航到的 url,以及一个 CefBrowser 窗口来显示 url 的内容。
            为了响应用户的输入,我们注册了一个匿名 ActionListener。每当用户在地址字段中按“回车”键时,就会执行此侦听器。
            如果发生这种情况,则将输入的值传递给要作为 url 加载的 CefBrowser 实例。
         */
        /*address_ = new JTextField(startURL,100);
        address_.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                cefBrowser_.loadURL((address_.getText()));
            }
        });*/

        // 当浏览器 URL 更改时更新地址字段。
        /*cefClient_.addDisplayHandler(new CefDisplayHandlerAdapter() {
            @Override
            public void onAddressChange(CefBrowser cefBrowser, CefFrame cefFrame, String url) {
                address_.setText(url);
            }
        });*/
        // 当地址字段获得焦点时,从浏览器中清除焦点。
        /*address_.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                if (!cefBrowserFocus_) return;
                cefBrowserFocus_ = false;
                // 通过焦点管理器,获取返回调用线程上下文的当前KeyboardFocusManager实例,清除Java和本机级别的全局焦点所有者。
                KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
                // 地址栏请求获取输入焦点,并且此Component的顶级祖先成为焦点Window
                address_.requestFocus();
            }
        });*/
        // 当浏览器获得焦点时,从地址栏字段中清除焦点
        /*cefClient_.addFocusHandler(new CefFocusHandlerAdapter() {
            @Override
            public void onGotFocus(CefBrowser cefBrowser) {
                if (cefBrowserFocus_) return;
                cefBrowserFocus_ = true;
                KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
                cefBrowser.setFocus(true);
            }
        });*/

        // 5、窗体属性设置
        // 在内容窗体中添加 地址栏对象,位置在北方(正上方)
//        getContentPane().add(address_,BorderLayout.NORTH);
        getContentPane().add(cefBrowserUI_, BorderLayout.CENTER);
        /*
            pack()方法是Frame类从java.awt.Window继承而来的方法,原型为:public void pack();
            作用:调整窗口的大小,使其适应组件的大小和布局。如果该窗口或其所有者仍不可显示,则两者在计算首选大小之前变得可显示。
            在计算首选大小之后,将会验证该Window。窗口自动适应大小,使窗口能正好显示里面所有的控件。
         */
        pack();
        // 定义控件的大小,有两个参数,分别对应宽度和高度;
        setSize(1700, 800);
        // 将组件移到新位置,用x 和 y 参数来指定新位置的左上角
        setLocation(10, 10);
        // 显示/隐藏GUI组件的。
        // setVisible()方法放到最后面,代码是按顺序执行的 ,如果把setVisible()放在前边,后边再添加其他组件的时候,有可能不会显示出来。
        setVisible(true);

        /* 6、
            要相应地关闭 CEF,如果 Java 应用程序将被关闭,那么调用 CefApp 实例的方法"dispose()"非常重要。否则你会得到 CEF 的指控。
         */
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                CefApp.getInstance().dispose();
                dispose();
            }
        });

         /*
            7、添加键盘快捷键监听
         */
        // 传递 this 是在当前窗口上打开一个弹窗,随着当前窗体显示隐藏
        cefClient_.addKeyboardHandler(new KeyboardHandler(this));
        // 传递 new JFrame() 可以创建一个新的窗体,这样不会遮挡当前窗体内容,可用于开发者工具显示
//        cefClient_.addKeyboardHandler(new KeyboardHandler(new JFrame()));
    }
}

添加开发者工具弹窗关键代码

打开DevToolsDialog文件,加入以下代码,代码已添加相关注释

点击查看代码
import org.cef.browser.CefBrowser;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

/**
 * 开发者工具弹窗类
 */
public class DevToolsDialog extends JDialog {
    private final CefBrowser devTools_;

    public DevToolsDialog(JFrame owner,String title,CefBrowser browser){
        this(owner,title,browser,null);
    }

    public DevToolsDialog(JFrame owner,String title ,CefBrowser browser,Point inspectAt){
        super(owner,title,false);

        setLayout(new BorderLayout());
        // 使用Toolkit可以获得本机系统的屏幕的参数
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(screenSize.width/2,screenSize.height/2);
        // 居中显示
        setLocationRelativeTo(owner);
        setAlwaysOnTop(false);

        // 获取当前浏览器的开发工具的实例
        devTools_=browser.getDevTools(inspectAt);
        add(devTools_.getUIComponent());

        addComponentListener(new ComponentAdapter() {
            @Override
            public void componentHidden(ComponentEvent e) {
                dispose();
            }
        });
    }

    @Override
    public void dispose(){
        // 此方法为强制关闭浏览器窗口,会导致再次打开开发者工具出现空白页面
//        devTools_.close(true);
        super.dispose();
    }
}

添加键盘按键操作类关键代码

打开KeyboardHandler文件,加入以下代码,代码已添加相关注释

点击查看代码
import org.cef.browser.CefBrowser;
import org.cef.handler.CefKeyboardHandlerAdapter;
import top.whitelies_7.dialog.DevToolsDialog;

import javax.swing.*;
import java.awt.*;

public class KeyboardHandler extends CefKeyboardHandlerAdapter {
    private final JFrame owner_;
    private DevToolsDialog devToolsDialog_ = null;

    public KeyboardHandler(JFrame owner_) {
        this.owner_ = owner_;
    }

    @Override
    public boolean onKeyEvent(CefBrowser cefBrowser, CefKeyEvent cefKeyEvent) {
        if (cefKeyEvent.type==CefKeyEvent.EventType.KEYEVENT_KEYUP){
            switch (cefKeyEvent.windows_key_code){
                // F12 开发者工具
                case 123:
                    devToolsShow(cefBrowser);
                    break;
                default:
                    return false;
            }
        }
        return true;
    }

    /**
     * 开发者工具显示或隐藏
     * @param cefBrowser 显示开发者工具的浏览器
     */
    private void devToolsShow(CefBrowser cefBrowser){
        if (devToolsDialog_ != null) {
            if (devToolsDialog_.isActive()) {
                devToolsDialog_.setVisible(false);
            } else {
                devToolsDialog_.setVisible(true);
            }
        } else {
            // 因为是开发者工具,不能影响内容页面的显示,所以单独新建一个窗体显示
            devToolsDialog_ = new DevToolsDialog(new JFrame(), "开发者工具", cefBrowser);
//            devToolsDialog_ = new DevToolsDialog(owner_, "开发者工具", cefBrowser);
            devToolsDialog_.setVisible(true);
        }
    }
}

最后添加启动项代码

打开Main文件,加入以下代码,代码已添加相关注释

点击查看代码
import org.cef.CefApp;
import org.cef.OS;
import top.whitelies_7.browser.MyBrowser;

public class Main {
    public static void main(String[] args) {
        if (!CefApp.startup(args)) {
            System.out.println("CEF APP 启动失败!");
        }
        boolean userOsr = OS.isLinux();

        MyBrowser myBrowser = new MyBrowser("http://www.baidu.com", userOsr, true, args);
    }
}

启动Main类文件中main方法即可查看到对应的功能,按键盘F12可以打开开发者工具,再次按可关闭,若开发者工具弹窗不在最前端,按F12可以将其展示在最前端

image

后续

由于本人才开始学JAVA,所以若代码中存在不规范的地方望大佬指正,后面会继续更新学习Java相关文章

致谢

在此感谢下面的大佬,大佬的文章让我受益匪浅!
http://www.xuanyimao.com/jcef/index.html#jcef 玄翼猫
https://blog.csdn.net/u013642500/article/details/103003284 奔跑的苍狼
https://github.com/xiongms/jcef-v49 xbmlz

posted @ 2022-08-25 17:15  嘿丶给你一块饼干  阅读(1837)  评论(0编辑  收藏  举报