Files
window-axis-innovators-box1.17/api-documentation/browser/Axis Innovators Box Browser 模块使用文档.md
tzdwindows 7 7badbb0d8e docs: 添加 Axis Innovators Box 框架完整 API 文档
- 新增浏览器模块技术文档,涵盖 BrowserCore、BrowserWindow 等核心组件
- 添加事件系统文档,包括 EventBus、GlobalEventBus 及各类事件定义
- 创建 LanguageManager 国际化管理器详细说明文档
- 新增 Log4j2OutputStream 标准输出重定向类文档
- 添加 Main 入口类启动流程与路由机制说明
- 创建 BrowserCreationCallback 回调接口使用指南
- 完善 AxisInnovatorsBox 主类架构与崩溃诊断系统文档
2026-01-03 08:46:19 +08:00

5.9 KiB
Raw Permalink Blame History

这份文档是对 com.axis.innovators.box.browser 包核心架构的深度解析。它涵盖了从底层核心代理到高层 UI 容器,以及 Java-JS 桥接机制的所有关键类。


Axis Innovators Box Browser 核心类技术文档

本模块旨在为 Swing 应用程序提供一个高性能、易扩展的嵌入式浏览器解决方案。通过高度抽象的架构,开发者可以轻松地在 Java 窗口中嵌入 Web 页面,并实现双向通信。


1. 核心架构设计

系统采用了 代理模式 (Proxy Pattern)构建者模式 (Builder Pattern)

  • 核心逻辑 (BrowserCore) 与 窗口容器 (BrowserWindow/BrowserWindowJDialog) 分离。
  • 配置逻辑 (BaseBrowserBuilder) 统一管理窗口属性。
  • 通信逻辑 (JsBridgeController) 通过注解驱动。

2. 接口与基类 (抽象层)

2.1 BrowserContainer.java (统一接口)

这是所有浏览器窗口容器的通用协议。无论是 JFrame 还是 JDialog,都必须实现此接口。

  • 核心职责:提供对外的统一 API使得 WindowRegistry 和业务逻辑可以忽略窗口的具体物理类型。
  • 关键方法
    • executingJsCode(String script): 在 JS 环境中执行代码(支持跨线程)。
    • setController(JsBridgeController controller): 动态切换 Java 逻辑控制器。
    • getBrowser() / getMsgRouter(): 获取底层 CEF 对象。

2.2 BaseBrowserBuilder.java (通用配置器)

采用泛型链式调用的抽象构建器类。

  • 核心职责:存储所有窗口初始化所需的配置数据(尺寸、标题、初始 URL、图标等
  • 主要字段
    • htmlUrl / htmlPath: 指定要加载的内容来源。
    • operationHandler: 系统级消息处理器。
    • controller: 初始的 JSBridge 控制器。
    • size, title, resizable: 基础窗口属性。

3. UI 容器层 (实现层)

3.1 BrowserWindow.java

继承自 JFrame,用于创建独立的主窗口或顶层窗口。

  • 特点:支持任务栏图标、最大化/最小化等标准窗口行为。
  • 内部实现:通过 BrowserCore 初始化浏览器组件,并将其作为 BorderLayout.CENTER 添加到内容面板。

3.2 BrowserWindowJDialog.java

继承自 JDialog,用于创建子窗口或模态/非模态对话框。

  • 特点:支持设置 parentFrame,可以实现点击父窗口时弹窗保持在最前的逻辑。
  • 应用场景:设置界面、详情弹窗、登录界面等。

4. 浏览器引擎核心

4.1 BrowserCore.java (系统大脑)

这是最关键的类,封装了 JCEF 的所有复杂逻辑。

  • 职责
    1. 初始化:管理 CefClient 的创建和 CefBrowser 的生命周期。
    2. Handler 路由:自动设置加载监听、右键菜单处理、证书错误处理、文件选择对话框处理等。
    3. 通信初始化:配置 CefMessageRouter (基于 window.javaQuery)。
    4. 脚本队列:维护 pendingScripts 队列。如果页面尚未加载完成就调用了 JS 代码,代码会暂存在队列中,直到 onLoadEnd 触发后自动冲刷执行。
    5. 资源注入:自动向 Web 页面注入系统字体、主题颜色和 extLibsPath 等全局变量。

5. Java-JS 桥接机制 (通信层)

这是实现“Java 调用 JS”和“JS 调用 Java”的核心组件。

5.1 JsMapping.java (方法注解)

一个运行时注解,用于标记控制器中可以被 JS 访问的方法。

  • 属性 value():
    • 若为空:默认挂载在 tzd.方法名()
    • 若为单纯字符串(如 "login"):挂载在 tzd.login()
    • 若包含点号(如 "app.utils.calc"):挂载在 window.app.utils.calc()

5.2 JsBridgeController.java (抽象控制器)

用户自定义业务逻辑的基类。

  • 工作原理
    1. 反射扫描:在初始化时自动扫描带有 @JsMapping 的所有方法。
    2. 代码生成generateInjectionJs() 会生成一套复杂的 JS 代理对象代码,在 onLoadEnd 时注入浏览器。
    3. 参数转换:利用 Gson 将 JS 传来的 JSON 数组自动反序列化为 Java 方法的参数类型(如 String, int, boolean 或自定义 POJO
    4. 异步回调:封装了 window.javaQuery 的复杂调用,使 JS 端可以像调用本地函数一样使用 async/await 获取结果。

6. 开发流程示例

第一步:定义控制器

public class MyActionController extends JsBridgeController {
    @JsMapping("saveConfig") // JS 调用: tzd.saveConfig(data)
    public boolean save(String data) {
        System.out.println("Saving: " + data);
        return true; 
    }

    @JsMapping("sys.getInfo") // JS 调用: sys.getInfo()
    public String getInfo() {
        return "Version 1.0.0";
    }
}

第二步:启动窗口

WindowRegistry.getInstance().createNewChildWindow("win01", builder -> {
    builder.title("我的应用")
           .htmlPath("index.html")
           .controller(new MyActionController()); // 绑定
});

第三步:前端调用

// index.html
async function doSave() {
    // 调用 Java 并获取返回值
    const success = await tzd.saveConfig("{id: 1}");
    if (success) {
        const info = await sys.getInfo();
        alert("保存成功, " + info);
    }
}

7. 最佳实践建议

  1. 资源管理:始终通过 WindowRegistry.unregisterWindow() 关闭窗口,以确保内存和进程资源被释放。
  2. 线程注意事项
    • executingJsCode 是线程安全的,可以在任意线程调用。
    • @JsMapping 标记的 Java 方法中,如果涉及 UI 更新(如修改 Swing 组件),必须包裹在 SwingUtilities.invokeLater 中。
  3. 动态切换:由于 setController 会重新注入脚本,建议在页面初次加载完成后进行控制器切换,以获得最佳稳定性。