创建一个默认打开指定网页的浏览器,在文末有完整代码。
首先,我们创建一个 maven 项目,参见
https://my.oschina.net/u/4282617/blog/11052290
https://www.toutiao.com/article/7356989476817732136/
然后我们定义一个名为 "JcefDemo_1" 的 Java 类,继承自 JFrame 类。它包含了四个私有成员变量:
public class JcefDemo_1 extends JFrame {
private static final long serialVersionUID = 2024_0412_22_44_30L;;
private final CefApp cefApp_; // CEF应用程序对象
private final CefClient client_; // CEF客户端对象
private final CefBrowser browser_; // CEF浏览器对象
private final Component browserUI_; // CEF浏览器UI组件对象
构造函数的参数如下:
/**
*
* @param startURL 启动时打开的url
* @param useOSR 用于启用或禁用无窗口渲染模式。
* @param isTransparent 是否透明
*/
public JcefDemo_1(String startURL, boolean useOSR, boolean isTransparent) {
构造函数详细
创建一个新的 CefAppBuilder 实例 builder
CefAppBuilder builder = new CefAppBuilder();
设置 JCEF 的安装目录
CefSettingUtils.setInstallDirAuto(builder);
安装目录的设置具体如下(可以省去不设置,有默认值 jcef-bundle):
package com.virhuiai.utils;
import me.friwi.jcefmaven.CefAppBuilder;
import me.friwi.jcefmaven.Enumplatform;
import me.friwi.jcefmaven.UnsupportedPlatformException;
import org.apache.commons.logging.Log;
import java.io.File;
public class CefSettingUtils {
private static Log LOGGER = CshLogUtils.getLog(CefSettingUtils.class);
/**
* 设置JCEF(Java Chromium Embedded Framework)的安装目录。
*
* 这个目录可能是相对于当前工作目录的相对路径,或者是一个绝对路径。
* setInstallDir() 方法将这个目录设置为 JCEF 的安装目录,以便在构建 CefApp 对象时使用。
*
* 通过设置安装目录,可以确保 JCEF 能够正确加载所需的资源、库文件和其他依赖项。
* 在实际使用中,您需要将该目录设置为正确的 JCEF 安装目录。
*
* @param builder
*/
public static void setInstallDirAuto(CefAppBuilder builder){
String installDir = "jcef-bundle";// 默认路径
EnumPlatform platform = null;
try {
platform = EnumPlatform.getCurrentPlatform();
installDir = installDir "-" platform.getIdentifier();
} catch (UnsupportedPlatformException e) {
LOGGER.error("设置JCEF安装目录失败", e);
// throw new RuntimeException(e);
}
LOGGER.debug("设置JCEF安装目录:" installDir);
// 配置 builder 实例
builder.setInstallDir(new File(installDir));
}
}
关闭应用时退出 jvm 运行
builder.setAppHandler(new MavenCefAppHandlerAdapter() {
@Override
public void stateHasChanged(CefApp.CefAppState state) {
// 关闭应用时退出jvm运行
if (state == CefApp.CefAppState.TERMINATED) {
System.out.println("关闭应用时退出jvm运行");
System.exit(0);
}
}
});
使用上述配置构建一个 CefApp 实例:
try {
// 全局的 CefApp 每个程序只能有一个,线程安全
cefApp_ = builder.build();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (UnsupportedPlatformException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (CefInitializationException e) {
throw new RuntimeException(e);
}
JCEF 可以同时处理一个到多个浏览器实例。这些浏览器实例通过 CefClient 类的实例在逻辑上进行分组。在您的应用程序中,您可以创建一个到多个 CefClient 实例, 并为每个客户端创建一个到多个 CefBrowser 实例。要获得 CefClient 的实例,您必须使用您的 CefApp 实例的 "createClient ()" 方法。不支持调用 CefClient 的构造函数。
CefClient 是连接到所有可能来自 CefBrowser 实例的事件的连接器。 这些事件可以是简单的事情,比如浏览器标题的更改,也可以是更复杂的事情,比如上下文菜单事件。通过为 CefClient 分配处理程序,您可以控制浏览器的行为。 请参阅 tests.detailed.MainFrame 以获取如何使用这些处理程序的示例。
创建一个浏览器客户端实例
client_ = cefApp_.createClient();
一个 CefBrowser 实例负责控制您在实例的 UI 组件上看到的内容。它可以以离屏渲染或窗口渲染的方式显示。要获得 CefBrowser 的实例,您必须调用 CefClient 实例的 "createBrowser ()" 方法。
CefBrowser 具有诸如 "goBack ()"、"goForward ()"、"loadURL ()" 等方法, 用于控制显示内容的行为。UI 位于一个 UI 组件中,可以通过在 CefBrowser 实例上调用 "getUIComponent ()" 方法来访问。UI 组件继承自 java.awt.Component,因此可以嵌入到任何 AWT UI 中。
browser_ = client_.createBrowser(startURL, useOSR, isTransparent);
browserUI_ = browser_.getUIComponent();
所有的 UI 组件都被分配给这个 JFrame 的默认内容面板,并且之后将该窗口对用户可见。
getContentPane().add(browserUI_, BorderLayout.CENTER);
pack();
setSize(800, 600);
setVisible(true);
为了正确处理关闭 CEF,重要的是在 Java 应用程序关闭时调用 CefApp 实例的 "dispose ()" 方法。否则,您将从 CEF 中得到断言。
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
CefApp.getInstance().dispose();
dispose();
}
});
下面打开一个网站试试:
public static void main(String[] args) throws UnsupportedPlatformException, CefInitializationException, IOException, InterruptedException {
new JcefDemo_1("https://magpcss.org/ceforum/viewforum.php?f=17", false, false);
}
结果如图:
完整代码如下:
package com.virhuiai.demo.jcef;
import com.virhuiai.utils.CefSettingUtils;
import com.virhuiai.utils.CshLogUtils;
import me.friwi.jcefmaven.CefAppBuilder;
import me.friwi.jcefmaven.CefBuildInfo;
import me.friwi.jcefmaven.CefInitializationException;
import me.friwi.jcefmaven.MavenCefAppHandlerAdapter;
import me.friwi.jcefmaven.UnsupportedPlatformException;
import me.friwi.jcefmaven.impl.progress.ConsoleProgressHandler;
import org.apache.commons.logging.Log;
import org.cef.CefApp;
import org.cef.CefClient;
import org.cef.browser.CefBrowser;
import javax.swing.JFrame;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
/// java-cef-master[24_02_27]/java/tests/simple/MainFrame.java README.md
public class JcefDemo_1 extends JFrame {
private static Log LOGGER = CshLogUtils.getLog(JcefDemo_1.class);
private static final long serialVersionUID = 2024_0412_22_44_30L;;
private final CefApp cefApp_; // CEF应用程序对象
private final CefClient client_; // CEF客户端对象
private final CefBrowser browser_; // CEF浏览器对象
private final Component browserUI_; // CEF浏览器UI组件对象
/**
*
* @param startURL 启动时打开的url
* @param useOSR 用于启用或禁用无窗口渲染模式。
* @param isTransparent 是否透明
*/
public JcefDemo_1(String startURL, boolean useOSR, boolean isTransparent) {
// 创建一个新的 CefAppBuilder 实例 builder
CefAppBuilder builder = new CefAppBuilder();
// todo blog 1. 设置JCEF的安装目录
CefSettingUtils.setInstallDirAuto(builder);
// 处理进度更新
// 默认就是ConsoleProgressHandler,在 CefAppBuilder 中有:
// private static final IProgressHandler DEFAULT_PROGRESS_HANDLER = new ConsoleProgressHandler();
builder.setProgressHandler(new ConsoleProgressHandler());
// 设置AppHandle
builder.setAppHandler(new MavenCefAppHandlerAdapter() {
@Override
public void stateHasChanged(CefApp.CefAppState state) {
// 关闭应用时退出jvm运行
if (state == CefApp.CefAppState.TERMINATED) {
System.out.println("关闭应用时退出jvm运行");
System.exit(0);
}
}
});
try {
// 使用上述配置构建一个 CefApp 实例
// 全局的 CefApp 每个程序只能有一个,线程安全
cefApp_ = builder.build();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (UnsupportedPlatformException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (CefInitializationException e) {
throw new RuntimeException(e);
}
// 显示一些版本信息
CefBuildInfo buildInfo = null;
try {
buildInfo = CefBuildInfo.fromClasspath();
} catch (IOException e) {
throw new RuntimeException(e);
}
LOGGER.info(buildInfo);
CefApp.CefVersion cefVersion = cefApp_.getVersion();
LOGGER.info(cefVersion);
// (2) JCEF可以同时处理一个到多个浏览器实例。
// 这些浏览器实例通过CefClient类的实例在逻辑上进行分组。
// 在您的应用程序中,您可以创建一个到多个CefClient实例,
// 并为每个客户端创建一个到多个CefBrowser实例。要获得CefClient的实例,
// 您必须使用您的CefApp实例的"createClient()"方法。不支持调用CefClient的构造函数。
//
// CefClient是连接到所有可能来自CefBrowser实例的事件的连接器。
// 这些事件可以是简单的事情,比如浏览器标题的更改,也可以是更复杂的事情,比如上下文菜单事件。
// 通过为CefClient分配处理程序,您可以控制浏览器的行为。
// 请参阅tests.detailed.MainFrame以获取如何使用这些处理程序的示例。
// 创建一个浏览器客户端实例
client_ = cefApp_.createClient();
// (3) 一个CefBrowser实例负责控制您在实例的UI组件上看到的内容。
// 它可以以离屏渲染或窗口渲染的方式显示。
// 要获得CefBrowser的实例,您必须调用CefClient实例的"createBrowser()"方法。
//
// CefBrowser具有诸如"goBack()"、"goForward()"、"loadURL()"等方法,
// 用于控制显示内容的行为。
// UI位于一个UI组件中,可以通过在CefBrowser实例上调用"getUIComponent()"方法来访问。
// UI组件继承自java.awt.Component,因此可以嵌入到任何AWT UI中。
browser_ = client_.createBrowser(startURL, useOSR, isTransparent);
browserUI_ = browser_.getUIComponent();
// (5) 所有的UI组件都被分配给这个JFrame的默认内容面板,并且之后将该窗口对用户可见。
getContentPane().add(browserUI_, BorderLayout.CENTER);
pack();
setSize(800, 600);
setVisible(true);
// (6) 为了正确处理关闭CEF,重要的是在Java应用程序关闭时调用CefApp实例的"dispose()"方法。
// 否则,您将从CEF中得到断言。
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
CefApp.getInstance().dispose();
dispose();
}
});
}
public static void main(String[] args) throws UnsupportedPlatformException, CefInitializationException, IOException, InterruptedException {
new JcefDemo_1("https://magpcss.org/ceforum/viewforum.php?f=17", false, false);
}
}
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved