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

137 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

这份文档是对 `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. 开发流程示例
### 第一步:定义控制器
```java
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";
}
}
```
### 第二步:启动窗口
```java
WindowRegistry.getInstance().createNewChildWindow("win01", builder -> {
builder.title("我的应用")
.htmlPath("index.html")
.controller(new MyActionController()); // 绑定
});
```
### 第三步:前端调用
```javascript
// 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` 会重新注入脚本,建议在页面初次加载完成后进行控制器切换,以获得最佳稳定性。