JCEF 初体验一,快捷键打开开发者工具
前言
由于本人接触项目需要开发客户端程序,同时前端页面通过VUE编写,还需要对接第三方的厂家的相关接口;之前采用的是C#+VUE来实现,现在想更改技术方案,所以选择了Java和VUE来实现,通过JCEF框架来显示页面。
准备工作
JCEF编译jar包
此仓库中含有windows32位和64位的编译jar包,需要的可自行下载
https://gitee.com/liangmengcheng/jcef
一个spring项目
主要是红框中的四个
添加库文件
将jcef相关的jar包添加为库文件
可以直接在jcefx86文件夹上右击,添加为库
将jcef中的win32文件夹或win64文件夹添加到库中
1、进入项目结构,左侧选择库
2、中间项选中添加的jcefx86,如果没有,可以点击上方加号进行添加
3、在弹窗中选择jcefx86->lib->win32文件夹,点击确定
4、在右侧出现此项及为完成
代码编写
添加 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可以将其展示在最前端
后续
由于本人才开始学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