docs: 添加 Axis Innovators Box 框架完整 API 文档
- 新增浏览器模块技术文档,涵盖 BrowserCore、BrowserWindow 等核心组件 - 添加事件系统文档,包括 EventBus、GlobalEventBus 及各类事件定义 - 创建 LanguageManager 国际化管理器详细说明文档 - 新增 Log4j2OutputStream 标准输出重定向类文档 - 添加 Main 入口类启动流程与路由机制说明 - 创建 BrowserCreationCallback 回调接口使用指南 - 完善 AxisInnovatorsBox 主类架构与崩溃诊断系统文档
This commit is contained in:
108
api-documentation/AxisInnovatorsBox.md
Normal file
108
api-documentation/AxisInnovatorsBox.md
Normal file
@@ -0,0 +1,108 @@
|
||||
这是一个为您编写的专门用于介绍 `package com.axis.innovators.box` 中 `AxisInnovatorsBox` 类的 Markdown 文档。
|
||||
|
||||
该文档详细涵盖了类的架构、核心功能、生命周期管理、崩溃处理机制以及主题系统。
|
||||
|
||||
***
|
||||
|
||||
# AxisInnovatorsBox 类技术文档
|
||||
|
||||
**包路径:** `com.axis.innovators.box.AxisInnovatorsBox`
|
||||
**版本:** 0.2.2
|
||||
**作者:** tzdwindows 7, lyxyz5223, 🐾Mr. Liu🐾, 泽钰
|
||||
|
||||
## 1. 概述
|
||||
|
||||
`AxisInnovatorsBox` 是 **Axis Innovators Box** 应用程序的核心入口类和应用控制器。它主要负责应用程序的生命周期管理、全局配置初始化、插件加载、GUI 窗口调度、崩溃诊断报告生成以及用户身份验证。
|
||||
|
||||
该类采用了 **单例模式 (Singleton Pattern)**,确保在整个应用运行期间只有一个主控制器实例存在,并通过 `GlobalEventBus` 进行事件驱动的模块间通信。
|
||||
|
||||
## 2. 核心架构与职责
|
||||
|
||||
该类承载了以下关键职责:
|
||||
|
||||
* **启动引导 (Bootstrapping):** 解析命令行参数,初始化 Log4j2 日志系统,加载原生库 (JNI)。
|
||||
* **资源加载:** 并行加载 Java 插件 (`PluginLoader`) 和 Python 插件 (`PluginPyLoader`),并管理加载进度条 (`ProgressBarManager`)。
|
||||
* **GUI 管理:** 初始化主窗口 (`MainWindow`),管理子窗口 (`WindowsJDialog`),并处理系统托盘 (`Tray`)。
|
||||
* **主题与外观:** 集成 FlatLaf 和 Material 主题,支持明/暗模式自动切换及系统主题监听。
|
||||
* **异常熔断与诊断:** 捕获未处理的异常,生成包含堆栈、内存快照 (Heap Dump)、线程快照等的详细崩溃报告。
|
||||
* **安全与验证:** 处理 Casdoor 用户登录,管理加密的 Token (`AESCryptoUtil`, `Base64CryptoUtil`)。
|
||||
|
||||
## 3. 关键特性详解
|
||||
|
||||
### 3.1 启动流程 (`run` 方法)
|
||||
启动过程被设计为异步非阻塞模式:
|
||||
1. **环境检查:** 区分快速启动模式 (`quickStart`) 和调试模式 (`isDebug`)。
|
||||
2. **原生库加载:** 在静态块中加载核心原生库:`FridaNative`, `ThrowSafely`, `DogAgent`, `RegisterTray`。
|
||||
3. **插件加载线程:** 开启独立线程加载插件,避免阻塞 UI 渲染,同时通过 `ProgressBarManager` 反馈进度。
|
||||
4. **事件广播:** 插件加载完成后,通过事件总线发送 `StartupEvent` 和 `OpenFileEvents`。
|
||||
5. **UI 呈现:** 最终调用 `runWindow()` 初始化并显示主界面。
|
||||
|
||||
### 3.2 强大的崩溃诊断系统 (`organizingCrashReports`)
|
||||
这是该类最复杂的功能之一。当发生未捕获异常时,它会:
|
||||
1. 拦截异常(包括 EDT 线程异常)。
|
||||
2. 收集全面的调试信息:
|
||||
* **日志:** Log4j2 的所有 Appender 日志。
|
||||
* **JVM 信息:** 类加载器层级、内存使用详情 (Heap/Non-Heap)、线程堆栈 (Thread Dump)、GC 状态。
|
||||
* **系统环境:** 环境变量、系统属性。
|
||||
* **内存转储:** 调用 `HotSpotDiagnosticMXBean` 生成 `.hprof` 文件。
|
||||
3. **UI 反馈:** 弹出一个自定义的崩溃对话框,展示错误堆栈和插件信息。
|
||||
4. **导出:** 允许用户将所有诊断信息打包导出为 ZIP 文件。
|
||||
|
||||
### 3.3 主题管理系统 (`setTopic` & `updateTheme`)
|
||||
支持高度可定制的外观,并能响应系统级的主题变更:
|
||||
* **集成主题库:** FlatLaf (Light, Dark, IntelliJ, Darcula, Mac), Material (Oceanic, Lite, Mars), 以及 Java 标准主题 (Metal, Motif)。
|
||||
* **动态切换:** 通过 `WindowsTheme` 监听系统主题变化,并实时广播 `TopicsUpdateEvents` 事件来刷新所有已打开的窗口。
|
||||
|
||||
### 3.4 身份验证 (`popupLogin`)
|
||||
* 集成了 **Casdoor** 认证服务器。
|
||||
* 使用 `StateManager` 本地存储加密后的登录 Token。
|
||||
* 支持自动登录:如果本地存在有效 Token,自动解密并校验;否则弹出登录窗口。
|
||||
|
||||
## 4. 主要方法说明
|
||||
|
||||
| 方法签名 | 描述 |
|
||||
| :--- | :--- |
|
||||
| `static void run(String[] args, boolean isDebug, boolean quickStart)` | 程序的静态入口点。初始化全局异常处理并启动主实例。 |
|
||||
| `void quit()` | 安全退出程序,中断主线程并关闭 JVM。 |
|
||||
| `void runWindow()` | 初始化主窗口 UI,加载注册的工具组件,并显示窗口。 |
|
||||
| `void organizingCrashReports(Exception e)` | 核心崩溃处理逻辑。收集数据并显示错误报告 GUI。 |
|
||||
| `void reloadAllWindow()` | 重新加载所有活动窗口(主窗口及子弹窗),用于主题切换或语言更新时刷新 UI。 |
|
||||
| `void updateTheme(String themeName, boolean isDarkMode)` | 设置 Swing 的 LookAndFeel 并触发全局主题更新事件。 |
|
||||
| `static AxisInnovatorsBox getMain()` | 获取当前运行的应用主实例(单例)。 |
|
||||
|
||||
## 5. 调试功能
|
||||
|
||||
当 `isDebug` 为 `true` 时,程序会:
|
||||
1. 启动一个独立的 `DebugWindow`,实时显示应用内部状态。
|
||||
2. 允许通过 `generateFileDump()` 等内部方法手动生成性能分析数据。
|
||||
|
||||
## 6. 原生库依赖
|
||||
|
||||
该类在静态初始化块中加载了以下原生库,表明应用具备底层系统交互能力:
|
||||
* **FridaNative:** 可能用于动态插桩或 Hook。
|
||||
* **ThrowSafely:** 安全异常处理。
|
||||
* **DogAgent:** 代理或监控组件。
|
||||
* **RegisterTray:** 系统托盘的原生实现。
|
||||
|
||||
## 7. 代码示例:获取主实例与工具注册
|
||||
|
||||
```java
|
||||
// 获取主程序实例
|
||||
AxisInnovatorsBox app = AxisInnovatorsBox.getMain();
|
||||
|
||||
// 获取注册工具管理器
|
||||
RegistrationTool tool = app.getRegistrationTool();
|
||||
|
||||
// 检查是否处于调试环境
|
||||
if (app.isDebugEnvironment()) {
|
||||
System.out.println("Current task progress: " + app.progressBarManager);
|
||||
}
|
||||
|
||||
// 强制重新加载 UI (例如在插件更改后)
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
app.reloadAllWindow();
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
*文档生成时间: 2026-01-02*
|
||||
97
api-documentation/Log4j2OutputStream.md
Normal file
97
api-documentation/Log4j2OutputStream.md
Normal file
@@ -0,0 +1,97 @@
|
||||
这是一个专门为 `com.axis.innovators.box.Log4j2OutputStream` 类编写的技术介绍文档。
|
||||
|
||||
---
|
||||
|
||||
# Log4j2OutputStream 类技术文档
|
||||
|
||||
**包路径:** `com.axis.innovators.box.Log4j2OutputStream`
|
||||
**主要功能:** 标准输出重定向与日志集成
|
||||
**作者:** tzdwindows 7
|
||||
|
||||
## 1. 概述
|
||||
|
||||
`Log4j2OutputStream` 是一个高度定制化的 `OutputStream` 实现,旨在解决 Java 应用程序中标准输出 (`System.out`) 和标准错误 (`System.err`) 与日志框架(Log4j2)集成时的冲突问题。
|
||||
|
||||
传统的日志重定向往往会“吞掉”控制台输出,导致开发者在调试时无法实时看到控制台信息。该类通过**多路输出机制**,实现了在保持控制台原始输出的同时,将内容自动同步到 Log4j2 日志记录器中,并保留一份副本在内存中用于崩溃诊断。
|
||||
|
||||
## 2. 核心特性
|
||||
|
||||
* **三路并行输出 (Triple-Way Output):** 任何写入此流的数据会同时流向:
|
||||
1. **原始控制台流:** 保证开发环境下的实时可见性。
|
||||
2. **Log4j2 Logger:** 将普通的 `print` 语句转换为结构化的日志条目。
|
||||
3. **内存缓冲区:** 静态存储在 `systemOutContent` 和 `systemErrContent` 中,供系统在发生崩溃时提取诊断数据。
|
||||
* **智能行缓冲 (Line-Buffered Logging):** 为了避免日志碎片化,该流会累积字符直到遇到换行符 (`\n`) 或手动触发 `flush()` 时,才会将其作为一条完整的日志记录(INFO 或 ERROR 级别)发送给 Log4j2。
|
||||
* **字符编码安全:** 全程采用 `StandardCharsets.UTF_8` 处理,有效防止中文字符在重定向过程中出现乱码。
|
||||
* **无缝集成:** 提供静态方法一键重定向整个系统的标准流。
|
||||
|
||||
## 3. 工作原理
|
||||
|
||||
### 3.1 数据流向图
|
||||
```text
|
||||
System.out.println("Hello")
|
||||
│
|
||||
▼
|
||||
Log4j2OutputStream.write()
|
||||
│
|
||||
├───> 原始 PrintStream (控制台显示)
|
||||
├───> 内存 ByteArrayOutputStream (诊断快照)
|
||||
└───> 内部 Buffer ───(遇到 \n)───> LogManager.getLogger().info()
|
||||
```
|
||||
|
||||
### 3.2 级别映射
|
||||
* `System.out` 映射为 Log4j2 的 **INFO** 级别。
|
||||
* `System.err` 映射为 Log4j2 的 **ERROR** 级别。
|
||||
|
||||
## 4. API 说明
|
||||
|
||||
### 4.1 核心静态方法
|
||||
|
||||
| 方法 | 描述 |
|
||||
| :--- | :--- |
|
||||
| `static void redirectSystemStreams()` | **最常用的方法**。调用后会立即劫持全局 `System.out` 和 `System.err`,并将其替换为封装后的 `Log4j2OutputStream`。 |
|
||||
| `static String getSystemOutContent()` | 获取自程序启动(或上次清空)以来标准输出的所有文本内容。 |
|
||||
| `static String getSystemErrContent()` | 获取自程序启动以来标准错误的所有文本内容。 |
|
||||
| `static void clearBuffers()` | 重置内存中的静态缓冲区,释放内存。 |
|
||||
|
||||
### 4.2 构造函数
|
||||
|
||||
```java
|
||||
public Log4j2OutputStream(boolean isErrorStream, PrintStream originalStream)
|
||||
```
|
||||
* `isErrorStream`: 指定该流是否作为错误流处理(影响日志级别)。
|
||||
* `originalStream`: 传入系统原始的打印流(如 `System.out` 在重定向前的副本),确保数据能回流到控制台。
|
||||
|
||||
## 5. 使用场景:崩溃诊断报告
|
||||
|
||||
该类与 `AxisInnovatorsBox` 的崩溃报告系统紧密配合。当程序发生未捕获异常时,`AxisInnovatorsBox` 会调用:
|
||||
|
||||
```java
|
||||
String systemOut = Log4j2OutputStream.systemOutContent.toString();
|
||||
String systemErr = Log4j2OutputStream.systemErrContent.toString();
|
||||
// ... 组合成完整的诊断报告
|
||||
```
|
||||
|
||||
这确保了即使用户没有查看日志文件的习惯,程序也能在崩溃瞬间抓取到最后时刻的控制台输出,极大地方便了远程排查。
|
||||
|
||||
## 6. 使用示例
|
||||
|
||||
在程序启动的最早期(通常在 `main` 方法或初始化块中)调用:
|
||||
|
||||
```java
|
||||
public static void main(String[] args) {
|
||||
// 初始化并启动重定向
|
||||
Log4j2OutputStream.redirectSystemStreams();
|
||||
|
||||
// 现在的 println 既会出现在控制台,也会进入 log4j2 配置文件定义的 Appender 中
|
||||
System.out.println("This is a test message.");
|
||||
System.err.println("This error will be logged as ERROR level.");
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 注意事项
|
||||
|
||||
1. **资源开销:** 由于内存中保留了输出副本,如果程序产生极大量的控制台输出(如数 GB 的日志),应定期调用 `clearBuffers()` 以防止内存溢出。
|
||||
2. **线程安全:** 该类依赖 `ByteArrayOutputStream` 的同步机制和 Log4j2 的线程安全保证。
|
||||
|
||||
---
|
||||
*文档生成时间: 2026-01-02*
|
||||
75
api-documentation/Main.md
Normal file
75
api-documentation/Main.md
Normal file
@@ -0,0 +1,75 @@
|
||||
这是一个专门为 `com.axis.innovators.box.Main` 类编写的技术介绍文档。
|
||||
|
||||
---
|
||||
|
||||
# Main 类技术文档
|
||||
|
||||
**包路径:** `com.axis.innovators.box.Main`
|
||||
**主要功能:** 应用程序入口点、启动路由、单实例控制
|
||||
**作者:** tzdwindows 7
|
||||
|
||||
## 1. 概述
|
||||
|
||||
`Main` 类是 **Axis Innovators Box** 的核心启动器(Launcher)。它并不直接负责业务逻辑,而是扮演“调度员”的角色。它的主要职责包括初始化基础环境(语言、日志)、解析命令行参数、执行单实例检查,并根据输入文件的类型决定是启动完整的主程序,还是进入特定的“快速启动(Quick Start)”模式。
|
||||
|
||||
## 2. 核心流程与职责
|
||||
|
||||
### 2.1 启动预处理
|
||||
在程序真正运行前,`Main` 执行以下环境准备工作:
|
||||
* **日志清理:** 调用 `FolderCleaner` 清理过期的日志文件(保留最近10天)。
|
||||
* **多语言初始化:** 通过 `LanguageManager` 加载用户保存的语言设置,默认为中文(zh_CN)。
|
||||
* **插件目录重定向:** 解析 `pluginsDirectory=` 参数,动态设置插件加载路径。
|
||||
|
||||
### 2.2 启动路由机制 (Quick Start)
|
||||
这是 `Main` 类最显著的特性。它会分析命令行传入的文件扩展名,并进行智能跳转:
|
||||
|
||||
| 文件类型 | 触发行为 | 对应组件 |
|
||||
| :--- | :--- | :--- |
|
||||
| `.jar` | 进入 JAR 可视化分析模式 | `ModernJarViewer` |
|
||||
| `.html` | 进入 HTML 浏览模式 | `MainApplication` |
|
||||
| 音乐类 (`.mflac`, `.mgg`, `.qmc`等) | 进入音乐解密界面 | `DecryptionUI` |
|
||||
|
||||
**快速启动逻辑:** 如果识别到上述特定文件,程序会立即启动对应的专用窗口,释放文件锁,并将 `quickStart` 标记设为 `true`,从而跳过完整的主界面初始化过程。
|
||||
|
||||
### 2.3 单实例锁 (Single Instance Lock)
|
||||
为了防止多个程序实例同时运行冲突,`Main` 实现了一套基于文件锁的保护机制:
|
||||
* **锁文件:** 在系统临时目录下创建 `axis_innovators_box.lock`。
|
||||
* **原理:** 利用 `FileChannel.tryLock()` 尝试获取排他锁。如果获取失败,说明已有实例在运行,程序将直接退出。
|
||||
* **释放:** 在程序关闭(Shutdown Hook)或进入快速启动模式时,会自动释放锁。
|
||||
|
||||
## 3. 命令行参数说明
|
||||
|
||||
`Main` 类支持以下关键参数:
|
||||
|
||||
* **`-debugControlWindow-on`**: 开启调试控制窗口(仅在非发布环境下有效)。
|
||||
* **`pluginsDirectory="path"`**: 指定插件的存储目录。
|
||||
* **文件路径**: 直接传入文件路径,程序会自动判断扩展名并路由至对应的工具。
|
||||
|
||||
## 4. 关键方法解析
|
||||
|
||||
### 4.1 `main(String[] args)`
|
||||
启动主函数。逻辑顺序为:
|
||||
1. 基础环境清理与加载。
|
||||
2. 过滤并解析特定标志位参数。
|
||||
3. 遍历文件参数,检查是否符合“快速启动”条件。
|
||||
4. 如果不是快速启动模式,则尝试获取单实例锁。
|
||||
5. 调用 `AxisInnovatorsBox.run()` 移交控制权。
|
||||
|
||||
### 4.2 `acquireLock()` & `releaseLock()`
|
||||
* **`acquireLock`**: 尝试在磁盘上锁定文件。如果返回 `false`,则程序退出。
|
||||
* **`releaseLock`**: 关闭文件通道并删除锁文件。这是确保应用能二次启动的关键清理步骤。
|
||||
|
||||
## 5. 设计模式与技术点
|
||||
|
||||
* **资源保护 (Shutdown Hook):** 通过 `Runtime.getRuntime().addShutdownHook` 注册清理线程,确保无论程序是正常关闭还是异常中止,都能尝试释放文件锁。
|
||||
* **异步启动:** 对于 UI 组件(如 `ModernJarViewer` 和 `DecryptionUI`),使用 `SwingUtilities.invokeLater` 确保在事件调度线程(EDT)中创建界面,保证线程安全。
|
||||
* **参数剥离:** 采用 `List<String> remainingArgs` 机制,将系统级参数(如目录设置)与业务级参数(待处理文件)分离。
|
||||
|
||||
## 6. 与 AxisInnovatorsBox 的关系
|
||||
|
||||
`Main` 类是第一级入口,而 `AxisInnovatorsBox` 是第二级核心。
|
||||
* 如果 `Main` 识别到特定文件,它会配置一个轻量级的 `AxisInnovatorsBox` 实例(`quickStart=true`)。
|
||||
* 如果没有特定文件,它将锁定单实例环境,并启动完整的 `AxisInnovatorsBox` 重量级主循环。
|
||||
|
||||
---
|
||||
*文档生成时间: 2026-01-02*
|
||||
137
api-documentation/browser/Axis Innovators Box Browser 模块使用文档.md
Normal file
137
api-documentation/browser/Axis Innovators Box Browser 模块使用文档.md
Normal file
@@ -0,0 +1,137 @@
|
||||
这份文档是对 `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` 会重新注入脚本,建议在页面初次加载完成后进行控制器切换,以获得最佳稳定性。
|
||||
122
api-documentation/events/Axis Innovators Box 事件类集合技术文档.md
Normal file
122
api-documentation/events/Axis Innovators Box 事件类集合技术文档.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Axis Innovators Box 事件类集合技术文档
|
||||
|
||||
**包路径:** `com.axis.innovators.box.events.*`
|
||||
**主要功能:** 作为事件总线(EventBus)的载体,定义系统各模块间的通信数据结构
|
||||
**作者:** tzdwindows 7
|
||||
|
||||
---
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本篇文档总结了 **Axis Innovators Box** 框架中定义的核心事件类。这些类作为 `EventBus` 分发的数据负载(Payload),涵盖了应用程序生命周期、UI 渲染、用户交互及系统设置等多个维度。
|
||||
|
||||
框架采用了 **Java Records (JDK 16+)** 和 **常规 POJO** 混合编写的方式:
|
||||
* **Records**: 用于纯数据传输,简洁高效。
|
||||
* **Classes**: 用于需要逻辑处理或可变状态(如事件拦截)的复杂场景。
|
||||
|
||||
---
|
||||
|
||||
## 2. 核心事件分类详解
|
||||
|
||||
### 2.1 系统生命周期事件
|
||||
|
||||
#### `StartupEvent` (Record)
|
||||
* **触发时机**: 应用程序启动阶段。
|
||||
* **用途**: 允许插件或子模块在系统就绪时获取主程序实例并执行初始化。
|
||||
* **字段**:
|
||||
* `AxisInnovatorsBox main`: 主程序入口实例。
|
||||
|
||||
---
|
||||
|
||||
### 2.2 主窗口与 UI 交互事件
|
||||
|
||||
#### `MainWindowEvents` (Container Class)
|
||||
内部包含两个核心 Record,用于处理主窗口的不同阶段:
|
||||
* **`initialize` (Record)**:
|
||||
* **触发时机**: 主窗口初始化加载时。
|
||||
* **用途**: 向主面板 (`mainPanel`) 添加自定义组件。
|
||||
* **`update` (Record)**:
|
||||
* **触发时机**: 窗口重绘或更新周期。
|
||||
* **用途**: 执行基于 `Graphics` 的自定义绘制逻辑。
|
||||
|
||||
#### `TABUIEvents` (Class)
|
||||
* **用途**: 管理选项卡(Tab)组件的 UI 属性设置。
|
||||
* **内部类 `update`**: 专门用于选项卡的重绘事件,传递 `Graphics` 上下文。
|
||||
|
||||
#### `TopicsUpdateEvents` (Class)
|
||||
* **触发时机**: 当系统主题发生变更(如切换深色模式/更换皮肤)时。
|
||||
* **用途**: 通知所有 UI 组件同步更新样式。
|
||||
* **字段**:
|
||||
* `String themeName`: 主题名称。
|
||||
* `boolean darkTheme`: 是否为暗黑模式。
|
||||
|
||||
---
|
||||
|
||||
### 2.3 文件与 IO 操作事件
|
||||
|
||||
#### `OpenFileEvents` (Class)
|
||||
* **触发时机**: 当程序接收到外部文件打开请求(如拖拽文件入窗口)时。
|
||||
* **核心功能**: **流程控制**。
|
||||
* **关键字段**:
|
||||
* `File filePath`: 文件路径。
|
||||
* `String extension`: 文件后缀名。
|
||||
* `boolean isContinue`: 默认值为 `true`。监听器可以通过 `setContinue(false)` 来**拦截**后续操作,阻止程序打开该文件。
|
||||
|
||||
---
|
||||
|
||||
### 2.4 设置与配置事件
|
||||
|
||||
#### `SettingsLoadEvents` (Record)
|
||||
* **触发时机**: 设置对话框加载时。
|
||||
* **用途**: 动态扩展设置界面。开发者可以获取 `JPanel content` 容器,向其中注入新的设置项(如复选框、输入框)。
|
||||
* **字段**:
|
||||
* `WindowsJDialog dialog`: 设置窗口实例。
|
||||
* `JPanel content`: 承载设置内容的容器面板。
|
||||
|
||||
---
|
||||
|
||||
## 3. 事件一览表
|
||||
|
||||
| 事件类名 | 类型 | 核心字段 | 应用场景 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `StartupEvent` | Record | `main` | 插件初始化、全局资源准备 |
|
||||
| `MainWindowEvents.initialize` | Record | `mainWindow`, `mainPanel` | 注入主界面组件 |
|
||||
| `MainWindowEvents.update` | Record | `mainWindow`, `g` | 自定义画布渲染 |
|
||||
| `OpenFileEvents` | Class | `filePath`, `isContinue` | 文件打开监听、格式校验与拦截 |
|
||||
| `SettingsLoadEvents` | Record | `dialog`, `content` | 动态添加设置选项 |
|
||||
| `TABUIEvents` | Class | `javax`, `card` | 选项卡组件管理 |
|
||||
| `TopicsUpdateEvents` | Class | `themeName`, `darkTheme` | 皮肤切换、实时调色板更新 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 使用代码示例
|
||||
|
||||
### 示例 1:拦截特定格式的文件打开
|
||||
```java
|
||||
@SubscribeEvent
|
||||
public void onFileOpen(OpenFileEvents event) {
|
||||
if (event.getExtension().equalsIgnoreCase("tmp")) {
|
||||
System.out.println("拒绝打开临时文件");
|
||||
event.setContinue(false); // 拦截流程
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 示例 2:在系统启动时注册组件
|
||||
```java
|
||||
@SubscribeEvent
|
||||
public void onStartup(StartupEvent event) {
|
||||
System.out.println("Axis Innovators Box 已启动: " + event.main().getClass().getName());
|
||||
}
|
||||
```
|
||||
|
||||
### 示例 3:动态添加设置项
|
||||
```java
|
||||
@SubscribeEvent
|
||||
public void onSettingsLoad(SettingsLoadEvents event) {
|
||||
event.content().add(new JButton("扩展插件设置"));
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
*文档生成时间: 2026-01-02*
|
||||
83
api-documentation/events/BrowserCreationCallback.md
Normal file
83
api-documentation/events/BrowserCreationCallback.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# BrowserCreationCallback 接口技术文档
|
||||
|
||||
**包路径:** `com.axis.innovators.box.events.BrowserCreationCallback`
|
||||
**类型:** 接口 (Interface)
|
||||
**主要功能:** 浏览器窗口布局自定义回调
|
||||
**作者:** tzdwindows 7
|
||||
|
||||
---
|
||||
|
||||
## 1. 概述
|
||||
|
||||
`BrowserCreationCallback` 是 **Axis Innovators Box** 框架中用于高度定制浏览器窗口布局的扩展接口。
|
||||
|
||||
在框架启动嵌入式浏览器窗口(如 HTML 查看器、数据库管理工具、或 AI 界面)时,默认会执行一套标准的布局逻辑(通常是将浏览器组件充满整个内容区域)。通过实现此接口,开发者可以拦截并接管窗口的布局过程,从而在浏览器组件周边添加自定义的 UI 元素(如侧边栏、工具栏、状态栏等)。
|
||||
|
||||
## 2. 核心方法详解
|
||||
|
||||
### 2.1 `onLayoutCustomization`
|
||||
|
||||
```java
|
||||
boolean onLayoutCustomization(
|
||||
Window window,
|
||||
Container contentPane,
|
||||
Component browserComponent,
|
||||
Object builder
|
||||
);
|
||||
```
|
||||
|
||||
#### 参数说明:
|
||||
* **`window`**: 当前正在创建的顶级窗口对象(通常是 `JFrame` 或 `JDialog` 的实例)。
|
||||
* **`contentPane`**: 窗口的主内容面板。开发者应在此容器上执行 `setLayout` 或 `add` 操作。
|
||||
* **`browserComponent`**: 已经实例化完成的浏览器渲染组件(UI 组件)。
|
||||
* **`builder`**: 触发创建流程的构建器对象(通常是内部的 `BrowserWindowBuilder`)。通过此对象可以获取更多上下文配置。
|
||||
|
||||
#### 返回值逻辑:
|
||||
* **`true` (已处理)**: 告诉框架:*“我已经手动安排好了所有组件的布局,请不要再执行系统默认的布局逻辑。”*
|
||||
* **`false` (未完全处理)**: 告诉框架:*“我可能做了一些预处理(如设置了背景色),但请继续执行默认的布局逻辑(通常是将 `browserComponent` 放入 `BorderLayout.CENTER`)。”*
|
||||
|
||||
---
|
||||
|
||||
## 3. 使用场景
|
||||
|
||||
该回调接口通常用于以下高级自定义需求:
|
||||
1. **添加导航栏**: 在浏览器组件上方添加地址栏、后退/前进按钮。
|
||||
2. **集成侧边栏**: 在浏览器左侧添加树状菜单或历史记录面板。
|
||||
3. **多组件混排**: 将浏览器作为界面的一部分,与其他 Swing 组件(如表格、控制台)共同展示。
|
||||
4. **注入装饰器**: 为浏览器窗口添加自定义的边框、水印或重写背景。
|
||||
|
||||
---
|
||||
|
||||
## 4. 代码示例:在浏览器上方添加工具栏
|
||||
|
||||
以下示例展示了如何使用该回调在浏览器窗口中插入一个简单的工具栏:
|
||||
|
||||
```java
|
||||
BrowserCreationCallback myCallback = (window, contentPane, browserComponent, builder) -> {
|
||||
// 1. 设置内容面板布局
|
||||
contentPane.setLayout(new BorderLayout());
|
||||
|
||||
// 2. 创建自定义工具栏
|
||||
JPanel toolbar = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
toolbar.add(new JButton("刷新"));
|
||||
toolbar.add(new JButton("主页"));
|
||||
|
||||
// 3. 将自定义组件和浏览器组件添加到面板
|
||||
contentPane.add(toolbar, BorderLayout.NORTH);
|
||||
contentPane.add(browserComponent, BorderLayout.CENTER);
|
||||
|
||||
// 4. 返回 true,表示我们已经手动完成了布局
|
||||
return true;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 设计优势
|
||||
|
||||
* **非侵入式修改**: 无需修改框架核心代码即可改变浏览器窗口的呈现方式。
|
||||
* **灵活性**: 基于接口的设计允许每个工具(Tool)根据自身业务需求定义完全不同的布局方案。
|
||||
* **控制反转 (IoC)**: 框架负责处理繁琐的浏览器引擎初始化,而将 UI 的最终决定权交还给开发者。
|
||||
|
||||
---
|
||||
*文档生成时间: 2026-01-02*
|
||||
105
api-documentation/events/EventBus.md
Normal file
105
api-documentation/events/EventBus.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# EventBus 类技术文档
|
||||
|
||||
**包路径:** `com.axis.innovators.box.events.EventBus`
|
||||
**主要功能:** 发布-订阅(Publish-Subscribe)模式的事件中心
|
||||
**作者:** tzdwindows 7
|
||||
|
||||
---
|
||||
|
||||
## 1. 概述
|
||||
|
||||
`EventBus` 是 **Axis Innovators Box** 框架的核心通信组件。它通过事件驱动的方式实现模块间的解耦,允许应用程序的不同部分在无需相互引用的情况下进行信息交换。
|
||||
|
||||
该实现采用了 **基于注解(Annotation-based)** 的方法,通过反射动态扫描和分发事件。它不仅支持简单的事件发布,还具备完整的对象生命周期管理(注册/注销)以及跨类层级的事件监听能力。
|
||||
|
||||
## 2. 核心架构设计
|
||||
|
||||
### 2.1 存储机制
|
||||
`EventBus` 内部维护了两个关键的映射表,以保证高效的事件分发和快速的资源清理:
|
||||
1. **`eventSubscribers` (Map<Class<?>, List<Subscriber>>)**:
|
||||
* **用途**: 用于事件发布。
|
||||
* **逻辑**: 以事件的 `Class` 类型为键,快速找到所有订阅了该事件的监听者列表。
|
||||
2. **`targetSubscribers` (Map<Object, List<Subscriber>>)**:
|
||||
* **用途**: 用于对象注销。
|
||||
* **逻辑**: 以订阅对象实例为键,记录该对象注册的所有监听器,确保在对象销毁时能一次性清理所有相关引用,防止内存泄漏。
|
||||
|
||||
### 2.2 订阅者封装 (`Subscriber`)
|
||||
内部类 `Subscriber` 封装了执行事件回调所需的三个要素:
|
||||
* **Target**: 接收事件的对象实例。
|
||||
* **Method**: 标记了 `@SubscribeEvent` 的方法对象。
|
||||
* **EventType**: 该监听器关注的事件类型(方法参数类型)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 关键功能详解
|
||||
|
||||
### 3.1 动态注册 (`register`)
|
||||
当一个对象调用 `register` 时,`EventBus` 会:
|
||||
1. **递归扫描**: 遍历目标对象的所有方法,包括从父类继承的方法(通过 `getSuperclass()` 向上递归)。
|
||||
2. **注解验证**: 筛选出带有 `@SubscribeEvent` 注解的方法。
|
||||
3. **参数检查**: 确保方法有且仅有一个参数(该参数即为监听的事件类型)。
|
||||
4. **建立索引**: 将符合条件的方法封装成 `Subscriber` 并存入上述两个映射表中。
|
||||
|
||||
### 3.2 事件发布 (`post`)
|
||||
当发布一个事件对象时:
|
||||
1. **类型匹配**: 获取事件的 `Class` 类型。
|
||||
2. **副本保护**: 在遍历订阅者列表前创建 `copySubs` 副本。这是为了防止在执行事件回调过程中,某个监听者尝试注销自己而引发 `ConcurrentModificationException`。
|
||||
3. **反射调用**: 通过 `setAccessible(true)` 强制调用(即使是私有方法),并将事件对象传入。
|
||||
|
||||
### 3.3 生命周期管理
|
||||
* **注销 (`unregister`)**: 彻底切断事件总线对目标对象的引用,是资源清理的关键步骤。
|
||||
* **熔断 (`shutdown`)**: 一旦总线关闭,所有的 `post` 操作将失效,确保在应用关闭阶段不再产生新的业务逻辑执行。
|
||||
|
||||
---
|
||||
|
||||
## 4. API 接口说明
|
||||
|
||||
| 方法 | 描述 |
|
||||
| :--- | :--- |
|
||||
| `void register(Object target)` | 扫描目标对象并注册所有合法的事件监听器。 |
|
||||
| `void unregister(Object target)` | 移除该对象在总线上的所有订阅关系。 |
|
||||
| `boolean post(Object event)` | 向所有订阅了该事件类型的监听者发送事件。 |
|
||||
| `void shutdown()` | 关闭事件总线。 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 技术亮点
|
||||
|
||||
* **继承支持**: 通过 `while (clazz != null)` 循环,支持在父类中定义通用的事件处理逻辑,子类只需注册即可继承该能力。
|
||||
* **解耦性**: 发布者完全不知道谁在处理事件,监听者也无需知道事件由谁产生,只需关注事件本身。
|
||||
* **健壮性**: 内置 `handleException` 机制,确保某个监听器执行失败时不会影响总线上其他监听器的正常运行。
|
||||
|
||||
---
|
||||
|
||||
## 6. 使用代码示例
|
||||
|
||||
### 定义事件
|
||||
```java
|
||||
public class UserLoginEvent {
|
||||
public final String username;
|
||||
public UserLoginEvent(String name) { this.username = name; }
|
||||
}
|
||||
```
|
||||
|
||||
### 注册监听器
|
||||
```java
|
||||
public class LogModule {
|
||||
@SubscribeEvent
|
||||
public void onUserLogin(UserLoginEvent event) {
|
||||
System.out.println("用户登录: " + event.username);
|
||||
}
|
||||
}
|
||||
|
||||
// 在初始化处
|
||||
EventBus bus = new EventBus();
|
||||
LogModule logModule = new LogModule();
|
||||
bus.register(logModule);
|
||||
```
|
||||
|
||||
### 发布事件
|
||||
```java
|
||||
bus.post(new UserLoginEvent("Admin"));
|
||||
```
|
||||
|
||||
---
|
||||
*文档生成时间: 2026-01-02*
|
||||
101
api-documentation/events/GlobalEventBus.md
Normal file
101
api-documentation/events/GlobalEventBus.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# GlobalEventBus 类技术文档
|
||||
|
||||
**包路径:** `com.axis.innovators.box.events.GlobalEventBus`
|
||||
**主要功能:** 全局单例事件总线访问点
|
||||
**作者:** tzdwindows 7
|
||||
|
||||
---
|
||||
|
||||
## 1. 概述
|
||||
|
||||
`GlobalEventBus` 是 **Axis Innovators Box** 框架中 `EventBus` 机制的静态包装类。它的核心作用是提供一个**全局唯一的、线程安全**的事件分发中心。
|
||||
|
||||
在一个复杂的解耦系统中,虽然可以实例化多个 `EventBus`(用于局部通信),但通常需要一个贯穿整个应用程序生命周期的主总线。`GlobalEventBus` 通过预定义的静态实例,消除了在不同模块、控制器或类之间传递 `EventBus` 引用的复杂性,实现了真正的“随处注册,随处发布”。
|
||||
|
||||
## 2. 核心架构设计
|
||||
|
||||
### 2.1 单例模式 (Singleton)
|
||||
该类采用了最简洁的静态常量初始化方式:
|
||||
```java
|
||||
public static final EventBus EVENT_BUS = new EventBus();
|
||||
```
|
||||
* **线程安全性**: 依赖于 Java 类加载机制,保证了 `EVENT_BUS` 实例在全局范围内的唯一性且只会被初始化一次。
|
||||
* **可见性**: `public` 修饰符允许框架内任何位置的代码直接访问,无需通过复杂的依赖注入(DI)容器。
|
||||
|
||||
### 2.2 职责定位
|
||||
`GlobalEventBus` 本身不包含复杂的逻辑,它更像是一个“门户”:
|
||||
1. **持有者**: 持有 `EventBus` 的核心实例。
|
||||
2. **默认中心**: 作为系统默认的、最高层级的通信渠道。
|
||||
|
||||
---
|
||||
|
||||
## 3. 关键特性
|
||||
|
||||
* **零配置访问**: 开发者无需关心 `EventBus` 的初始化时机,直接通过 `GlobalEventBus.EVENT_BUS` 即可获取能力。
|
||||
* **一致性**: 确保了核心系统事件(如应用启动、配置变更、全局错误处理)都在同一个频道内流动。
|
||||
* **低耦合**: 模块 A 只需要知道 `GlobalEventBus` 和事件类,而无需知道模块 B 的存在,即可实现与模块 B 的交互。
|
||||
|
||||
---
|
||||
|
||||
## 4. API 使用指南
|
||||
|
||||
由于 `GlobalEventBus` 是对 `EventBus` 的静态引用,其主要操作均通过 `EVENT_BUS` 成员完成。
|
||||
|
||||
| 操作类型 | 代码示例 | 说明 |
|
||||
| :--- | :--- | :--- |
|
||||
| **注册监听** | `GlobalEventBus.EVENT_BUS.register(this);` | 在组件初始化(如 `onInit`)时调用。 |
|
||||
| **发送事件** | `GlobalEventBus.EVENT_BUS.post(new ConfigChangedEvent());` | 在任何业务逻辑发生点触发。 |
|
||||
| **取消注册** | `GlobalEventBus.EVENT_BUS.unregister(this);` | 在组件销毁(如 `onDestroy`)时调用,防止内存泄漏。 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 最佳实践
|
||||
|
||||
### 5.1 何时使用 GlobalEventBus?
|
||||
* **全局生命周期事件**: 如用户登录/登出、系统配置刷新。
|
||||
* **跨层级通信**: 例如底层的网络模块需要通知最顶层的 UI 界面显示通知。
|
||||
* **临时任务**: 不需要长期维护引用关系的瞬时事件处理。
|
||||
|
||||
### 5.2 注意事项
|
||||
1. **内存管理**: 凡是使用 `GlobalEventBus.EVENT_BUS.register()` 的对象,必须在生命周期结束时手动调用 `unregister()`,否则该对象将因为被全局静态引用持有而无法被 JVM 回收。
|
||||
2. **性能考量**: 虽然单次分发效率很高,但若全局总线上挂载了数千个监听器,频繁发布高频事件(如鼠标移动)可能会产生性能抖动。
|
||||
|
||||
---
|
||||
|
||||
## 6. 使用代码示例
|
||||
|
||||
### 场景:全局错误处理系统
|
||||
```java
|
||||
// 1. 定义全局异常事件
|
||||
public class GlobalErrorEvent {
|
||||
public final String message;
|
||||
public GlobalErrorEvent(String msg) { this.message = msg; }
|
||||
}
|
||||
|
||||
// 2. 在 UI 层注册监听
|
||||
public class MainNotificationUI {
|
||||
public MainNotificationUI() {
|
||||
GlobalEventBus.EVENT_BUS.register(this);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onErrorMessage(GlobalErrorEvent event) {
|
||||
showToast("系统错误: " + event.message);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 在底层业务逻辑处发布
|
||||
public class DatabaseWorker {
|
||||
public void doWork() {
|
||||
try {
|
||||
// 某些业务操作...
|
||||
} catch (Exception e) {
|
||||
// 发现错误,直接向全局总线抛出,无需持有 UI 的引用
|
||||
GlobalEventBus.EVENT_BUS.post(new GlobalErrorEvent(e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
*文档生成时间: 2026-01-02*
|
||||
102
api-documentation/events/SubscribeEvent.md
Normal file
102
api-documentation/events/SubscribeEvent.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# SubscribeEvent 注解技术文档
|
||||
|
||||
**包路径:** `com.axis.innovators.box.events.SubscribeEvent`
|
||||
**主要功能:** 标记事件订阅方法并定义执行优先级
|
||||
**作者:** tzdwindows 7
|
||||
|
||||
---
|
||||
|
||||
## 1. 概述
|
||||
|
||||
`@SubscribeEvent` 是 **Axis Innovators Box** 事件系统的核心元数据注解。它被用于标记类中的方法,使其能够被 `EventBus` 识别并注册为事件监听器(Listener)。
|
||||
|
||||
该注解的存在实现了“声明式”的事件监听。开发者无需实现复杂的接口,只需在任意方法上添加此注解,并确保方法签名符合规范(单参数),即可自动参与系统的事件流转。
|
||||
|
||||
## 2. 注解配置说明
|
||||
|
||||
### 2.1 运行时保留 (`@Retention`)
|
||||
设置为 `RetentionPolicy.RUNTIME`。这意味着注解信息在类加载后依然保留在 JVM 中,允许 `EventBus` 在运行时通过**反射(Reflection)**动态扫描到这些方法。
|
||||
|
||||
### 2.2 目标范围 (`@Target`)
|
||||
设置为 `ElementType.METHOD`。明确限定该注解仅能用于方法上。
|
||||
|
||||
---
|
||||
|
||||
## 3. 核心属性详解
|
||||
|
||||
### 3.1 `priority()`
|
||||
* **类型**: `int`
|
||||
* **默认值**: `0`
|
||||
* **功能**: 定义事件处理的先后顺序。
|
||||
* **逻辑规则**:
|
||||
* 当一个事件被发布时,`EventBus` 会根据所有订阅该事件的方法的 `priority` 值进行排序。
|
||||
* **值越大,优先级越高**,该方法将越早接收到事件通知。
|
||||
* 当优先级相同时,执行顺序取决于系统反射获取方法的自然顺序(通常不保证固定顺序)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 订阅方法规范
|
||||
|
||||
为了使 `@SubscribeEvent` 生效,标记的方法必须遵循以下约束:
|
||||
|
||||
1. **参数限制**: 方法必须有且仅有一个参数。该参数的类型即为该监听器关注的事件类型。
|
||||
2. **访问权限**: 虽然 `EventBus` 内部通过 `setAccessible(true)` 支持私有方法,但建议根据模块化设计合理设置方法的可见性。
|
||||
3. **返回类型**: 通常为 `void`。因为事件发布是单向的分发过程,`EventBus` 不会处理监听方法的返回值。
|
||||
|
||||
---
|
||||
|
||||
## 5. 使用示例
|
||||
|
||||
### 5.1 基础用法
|
||||
```java
|
||||
@SubscribeEvent
|
||||
public void onGenericEvent(MessageEvent event) {
|
||||
System.out.println("收到消息: " + event.getContent());
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 优先级应用场景
|
||||
假设有一个日志系统,需要在业务逻辑处理前记录日志,在业务逻辑处理后进行清理:
|
||||
|
||||
```java
|
||||
public class SecurityMonitor {
|
||||
// 高优先级:先检查权限
|
||||
@SubscribeEvent(priority = 100)
|
||||
public void checkPermission(UserActionEvent event) {
|
||||
if (!event.user.hasAccess()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class BusinessLogic {
|
||||
// 默认优先级:正常执行业务
|
||||
@SubscribeEvent(priority = 0)
|
||||
public void handleAction(UserActionEvent event) {
|
||||
if (!event.isCancelled()) {
|
||||
executeTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 技术亮点
|
||||
|
||||
* **非侵入式设计**: 业务类不需要继承任何父类或实现特定接口,保持了代码的纯净性。
|
||||
* **精细化控制**: 通过 `priority` 属性,解决了传统观察者模式中监听器执行顺序不可控的问题。
|
||||
* **自描述性**: 开发者通过阅读代码中的注解,可以清晰地识别出哪些逻辑是响应式的,增强了代码的可读性。
|
||||
|
||||
---
|
||||
|
||||
## 7. 配合 EventBus 的工作流程
|
||||
|
||||
1. **扫描**: `EventBus.register(obj)` 被调用。
|
||||
2. **识别**: 遍历 `obj` 及其父类,筛选出所有带有 `@SubscribeEvent` 的方法。
|
||||
3. **解析**: 读取 `priority` 数值以及参数类型。
|
||||
4. **排序**: 将这些信息封装为 `Subscriber` 对象并根据优先级存入订阅列表。
|
||||
5. **分发**: `post(event)` 时,按优先级从高到低依次反射调用。
|
||||
|
||||
---
|
||||
*文档生成时间: 2026-01-02*
|
||||
109
api-documentation/register/LanguageManager.md
Normal file
109
api-documentation/register/LanguageManager.md
Normal file
@@ -0,0 +1,109 @@
|
||||
这是一个专门为 `com.axis.innovators.box.register.LanguageManager` 类编写的技术介绍文档。
|
||||
|
||||
---
|
||||
|
||||
# LanguageManager 类技术文档
|
||||
|
||||
**包路径:** `com.axis.innovators.box.register.LanguageManager`
|
||||
**主要功能:** 多语言国际化 (i18n) 管理器、插件语言合并系统
|
||||
**作者:** tzdwindows 7
|
||||
|
||||
## 1. 概述
|
||||
|
||||
`LanguageManager` 是 **Axis Innovators Box** 框架的核心组件之一,负责管理应用程序的所有文本翻译和语言环境。它不仅支持内置的系统语言(中文、英文、日文),还具备高度的可扩展性,允许外部插件动态地将自己的语言包合并到主程序的语言池中。
|
||||
|
||||
该系统采用了 **Properties** 文件作为底层存储,通过 **UTF-8** 编码确保跨平台字符兼容性,并提供了完善的语言持久化(自动保存用户选择)功能。
|
||||
|
||||
## 2. 核心架构
|
||||
|
||||
### 2.1 语言描述类 (`Language` 内部类)
|
||||
`Language` 是该管理器的基本数据单元,包含:
|
||||
* **语言名称 (Language Name):** 用于 UI 显示的易读名称(如 "简体中文")。
|
||||
* **注册名 (Registered Name):** 内部唯一标识符(如 "system:zh_CN")。
|
||||
* **属性池 (Properties):** 存储键值对翻译数据的核心容器。
|
||||
* **智能加载:** 能够从磁盘文件或 JAR 包输入流中加载数据。
|
||||
|
||||
### 2.2 存储与路径
|
||||
* **语言文件夹:** 由 `FolderCreator.getLanguageFolder()` 定义。
|
||||
* **持久化文件:** `saved_language.properties`,用于记录用户上一次关闭程序时使用的语言,实现启动自加载。
|
||||
|
||||
## 3. 核心功能特性
|
||||
|
||||
### 3.1 插件语言扩展机制 (`registerPluginLanguage`)
|
||||
这是该类最强大的功能。插件无需修改主程序代码,即可通过以下流程添加翻译:
|
||||
1. **资源读取:** 插件通过其 `PluginDescriptor` 从 JAR 包内部读取 `.properties` 文件。
|
||||
2. **动态合并:** `LanguageManager` 会根据插件指定的 `targetRegisteredName`(如 "system:zh_CN"),自动将插件的翻译键值对并入主程序的对应语言对象中。
|
||||
|
||||
### 3.2 智能合并逻辑 (`addLanguage`)
|
||||
当新语言资源并入时,系统会执行“差异化合并”:
|
||||
* **新增条目:** 如果键不存在,则添加。
|
||||
* **更新条目:** 如果键已存在,则用新值覆盖(允许插件覆盖系统默认文本)。
|
||||
* **合并报告:** 自动生成详细的日志,记录新增和更新的数量,并列出前 5 个示例键。
|
||||
|
||||
### 3.3 语言切换与持久化
|
||||
* **`loadLanguage(String name)`:** 切换当前语言并立即将选择写入磁盘。
|
||||
* **`loadSavedLanguage()`:** 在程序启动时调用,恢复用户偏好的语言环境。
|
||||
|
||||
## 4. API 说明
|
||||
|
||||
### 4.1 管理器核心方法
|
||||
|
||||
| 方法 | 描述 |
|
||||
| :--- | :--- |
|
||||
| `static void registerPluginLanguage(...)` | **插件专用接口**。从插件资源中加载并合并语言包。 |
|
||||
| `static void addLanguage(Language lang)` | 将一个 Language 对象合并到现有的语言列表中。 |
|
||||
| `static void loadLanguage(String name)` | 设置当前激活的语言。 |
|
||||
| `static Language getLoadedLanguages()` | 获取当前正在使用的 Language 对象。 |
|
||||
| `static List<Language> getLanguages()` | 获取系统当前支持的所有语言列表。 |
|
||||
|
||||
### 4.2 Language 对象常用方法
|
||||
|
||||
| 方法 | 描述 |
|
||||
| :--- | :--- |
|
||||
| `String getText(String key)` | **最常用方法**。根据键获取翻译文本。如果键不存在,则返回键名本身(防止 UI 出现空白)。 |
|
||||
| `void addText(String key, String val)` | 动态添加单条翻译。 |
|
||||
|
||||
## 5. 日志与反馈示例
|
||||
|
||||
当插件合并语言时,控制台会输出如下形式的“合并报告”,极大地方便了插件开发者的调试:
|
||||
|
||||
```text
|
||||
【语言合并报告】
|
||||
▌合并来源:MyPlugin Resource -> system:zh_CN
|
||||
▌变更统计:新增 10 条 / 更新 2 条
|
||||
▌当前总量:156 条
|
||||
▌关键示例:
|
||||
✦ 新增条目:
|
||||
▸ myplugin.button.start
|
||||
▸ myplugin.menu.settings
|
||||
✦ 更新条目:
|
||||
▸ common.ok
|
||||
```
|
||||
|
||||
## 6. 使用示例
|
||||
|
||||
### 6.1 在代码中获取翻译
|
||||
```java
|
||||
// 建议在 UI 组件中使用
|
||||
String title = LanguageManager.getLoadedLanguages().getText("mainWindow.title");
|
||||
btn.setText(title);
|
||||
```
|
||||
|
||||
### 6.2 插件注册语言
|
||||
```java
|
||||
// 在插件初始化时调用
|
||||
LanguageManager.registerPluginLanguage(
|
||||
this.descriptor,
|
||||
"assets/lang/zh_CN.properties",
|
||||
"system:zh_CN"
|
||||
);
|
||||
```
|
||||
|
||||
## 7. 注意事项
|
||||
|
||||
1. **UTF-8 编码:** 所有的 `.properties` 文件必须保存为 UTF-8 编码,否则在处理非 ASCII 字符(如中文、日文)时会出现乱码。
|
||||
2. **启动顺序:** 建议在 `Main` 类中尽早调用 `loadSavedLanguage()`,以确保主窗口初始化时能正确显示本地化文本。
|
||||
3. **Key 冲突:** 插件开发者应为 Key 添加前缀(如 `plugin.id.text`),以避免意外覆盖主程序或其他插件的翻译。
|
||||
|
||||
---
|
||||
*文档生成时间: 2026-01-02*
|
||||
63
api-documentation/register/RegistrationError..md
Normal file
63
api-documentation/register/RegistrationError..md
Normal file
@@ -0,0 +1,63 @@
|
||||
这是一个专门为 `com.axis.innovators.box.register.RegistrationError` 类编写的技术介绍文档。
|
||||
|
||||
---
|
||||
|
||||
# RegistrationError 类技术文档
|
||||
|
||||
**包路径:** `com.axis.innovators.box.register.RegistrationError`
|
||||
**类型:** 自定义错误类 (Custom Error)
|
||||
**继承关系:** `java.lang.Error`
|
||||
**作者:** tzdwindows 7
|
||||
|
||||
## 1. 概述
|
||||
|
||||
`RegistrationError` 是 **Axis Innovators Box** 框架中专门用于处理**注册阶段致命失败**的类。与标准的 `Exception` 不同,该类继承自 `java.lang.Error`,这表明它代表的是一种不可恢复的严重问题。
|
||||
|
||||
在工具加载、插件注册或核心组件初始化过程中,如果发生了违反框架逻辑或导致系统无法继续运行的错误,框架会抛出此错误以立即中断当前非法的操作流程。
|
||||
|
||||
## 2. 为什么选择继承自 `Error`?
|
||||
|
||||
在 Java 异常体系中,通常 `Exception` 用于程序可以处理的异常情况,而 `Error` 用于指示合理的应用程序不应该试图捕获的严重问题。
|
||||
|
||||
`RegistrationError` 继承自 `Error` 的设计意图在于:
|
||||
1. **强制中断:** 注册失败通常意味着插件配置错误、依赖缺失或核心工具 ID 冲突。这种情况下,继续运行程序可能会导致不可预知的行为或数据损坏。
|
||||
2. **跳过普通捕获:** 许多代码块会使用 `catch (Exception e)` 来捕获业务异常。继承自 `Error` 可以确保注册阶段的致命问题不会被普通的业务异常处理器“默默吞掉”,从而能被最外层的崩溃处理器(如 `AxisInnovatorsBox` 中的崩溃报告系统)捕获。
|
||||
3. **语义化:** 明确标识这是一个“框架级”的初始化错误,而非普通的“业务级”异常。
|
||||
|
||||
## 3. 构造函数
|
||||
|
||||
```java
|
||||
public RegistrationError(String message) {
|
||||
super(message);
|
||||
}
|
||||
```
|
||||
|
||||
* **`message`**: 详细的错误描述信息。通常包含注册失败的工具名称、原因以及可能的解决建议。
|
||||
|
||||
## 4. 使用场景
|
||||
|
||||
该错误通常由以下组件在验证失败时抛出:
|
||||
* **RegistrationTool**: 当尝试注册一个 ID 已经存在或参数非法的工具分类时。
|
||||
* **RegistrationTopic**: 当加载的主题类无法被实例化或不符合规范时。
|
||||
* **PluginLoader**: 当插件描述文件损坏或插件版本与核心框架严重不兼容时。
|
||||
|
||||
## 5. 代码示例
|
||||
|
||||
以下是该类在注册逻辑中的典型应用:
|
||||
|
||||
```java
|
||||
public void registerTool(String toolId, ToolInstance tool) {
|
||||
if (registry.containsKey(toolId)) {
|
||||
// 如果 ID 冲突,抛出 RegistrationError,这将导致程序或该插件加载流程终止
|
||||
throw new RegistrationError("致命错误:工具 ID [" + toolId + "] 已存在,无法重复注册!");
|
||||
}
|
||||
registry.put(toolId, tool);
|
||||
}
|
||||
```
|
||||
|
||||
## 6. 与崩溃报告系统的集成
|
||||
|
||||
当 `RegistrationError` 被抛出且未被捕获时,它会触发 `AxisInnovatorsBox` 中设置的 `UncaughtExceptionHandler`。这将直接导致崩溃诊断窗口弹出,向用户显示详细的注册失败信息,并允许用户导出包含插件列表和系统状态的诊断包。
|
||||
|
||||
---
|
||||
*文档生成时间: 2026-01-02*
|
||||
85
api-documentation/register/RegistrationSettingsItem.md
Normal file
85
api-documentation/register/RegistrationSettingsItem.md
Normal file
@@ -0,0 +1,85 @@
|
||||
这是一个专门为 `com.axis.innovators.box.register.RegistrationSettingsItem` 类编写的技术介绍文档。
|
||||
|
||||
---
|
||||
|
||||
# RegistrationSettingsItem 类技术文档
|
||||
|
||||
**包路径:** `com.axis.innovators.box.register.RegistrationSettingsItem`
|
||||
**继承关系:** `com.axis.innovators.box.window.WindowsJDialog`
|
||||
**主要功能:** 设置中心控制器、设置项注册引擎、应用配置管理
|
||||
**作者:** tzdwindows 7
|
||||
|
||||
## 1. 概述
|
||||
|
||||
`RegistrationSettingsItem` 是 **Axis Innovators Box** 的配置核心。它既是一个用于展示设置界面的对话框组件,也是一个全局的设置项注册仓库。它允许主程序和外部插件动态地将自定义的设置面板(JPanel)插入到统一的“设置中心”内。
|
||||
|
||||
此外,该类还负责处理应用的外观(主题、字体、背景图片)、性能(CUDA 加速)和国际化(语言)的持久化逻辑。
|
||||
|
||||
## 2. 核心职责
|
||||
|
||||
### 2.1 设置项注册 (Registration)
|
||||
提供标准的 API,允许不同模块注册设置页面:
|
||||
* **内置页面:** 自动初始化“常规设置”、“插件管理”、“主题选择”和“关于我们”四个核心面板。
|
||||
* **插件扩展:** 插件可以通过 `addSettings()` 方法将自己的配置界面无缝集成到主设置窗口中。
|
||||
|
||||
### 2.2 环境外观管理
|
||||
* **主题切换:** 与 `RegistrationTopic` 配合,实现 LookAndFeel 的动态切换与搜索。
|
||||
* **字体定制:** 全局修改 UI 字体,包括字体家族和大小。
|
||||
* **背景特效:** 支持设置主窗口背景图片,并提供实时的**高斯模糊/毛玻璃**特效预览与应用。
|
||||
|
||||
### 2.3 配置持久化
|
||||
使用 `StateManager`(关联文件 `app_settings`)将用户的个性化选择保存到磁盘:
|
||||
* `theme.color`: 界面主题主色调。
|
||||
* `ui.font`: 用户选择的字体。
|
||||
* `background.path` & `background.blur`: 背景图片路径及其模糊程度。
|
||||
* `ui.language`: 选定的语言环境。
|
||||
* `ai.cuda.enabled`: AI 推理的 CUDA 加速开关。
|
||||
|
||||
## 3. 关键功能模块解析
|
||||
|
||||
### 3.1 动态背景模糊系统
|
||||
该类内置了复杂的图像处理算法用于背景预览:
|
||||
* **`applyFastBlur`**: 快速盒式模糊,适用于小半径预览。
|
||||
* **`applyScaledBlur`**: 缩放模糊算法,通过降低采样率再放大的方式,在大半径模糊下保持极高的性能。
|
||||
* **`applyGaussianBlur`**: 标准高斯模糊,通过一维卷积核两次传递(水平+垂直)实现高质量效果。
|
||||
|
||||
### 3.2 插件管理面板 (`createPluginSettingsPanel`)
|
||||
实时统计并展示系统中已加载的所有插件信息:
|
||||
* 区分 **Java 插件** 和 **Python 插件**。
|
||||
* 支持双击查看详细信息,包括插件图标、物理位置(JAR 路径)、主类名及转换器信息。
|
||||
|
||||
### 3.3 全局应用逻辑 (`applyAllSettings`)
|
||||
这是一个静态方法,通常在 `AxisInnovatorsBox` 启动时调用。它会按顺序读取 `StateManager` 中的所有记录,并一次性应用到当前 JVM 环境中,确保用户每次打开应用时都能获得一致的体验。
|
||||
|
||||
## 4. API 接口说明
|
||||
|
||||
### 4.1 注册设置项
|
||||
|
||||
```java
|
||||
public void addSettings(JPanel panel, String title, Icon icon, String tip, String registeredName)
|
||||
```
|
||||
* `panel`: 要显示的设置 UI 面板。
|
||||
* `title`: 侧边栏或标签页显示的标题。
|
||||
* `registeredName`: 唯一标识符(建议格式 `pluginId:itemName`)。
|
||||
|
||||
### 4.2 设置项管理
|
||||
|
||||
| 方法 | 描述 |
|
||||
| :--- | :--- |
|
||||
| `static void overloading()` | 重新初始化设置列表,常用于切换语言后刷新 UI 文本。 |
|
||||
| `static void applyAllSettings()` | 从磁盘加载并应用所有已保存的配置。 |
|
||||
| `void registration(JTabbedPane tp)` | 将所有已注册的设置项填充到指定的选项卡组件中。 |
|
||||
|
||||
## 5. 交互特性
|
||||
|
||||
1. **主题搜索:** 在主题面板按 `Ctrl + F` 可调出搜索栏,快速定位已安装的主题。
|
||||
2. **实时预览:** 调整模糊滑块或选择颜色时,设置界面内的预览组件会立即更新。
|
||||
3. **热重载:** 切换主题或语言后,会触发 `AxisInnovatorsBox.getMain().reloadAllWindow()`,无需重启即可看到全局变化。
|
||||
|
||||
## 6. 设计细节
|
||||
|
||||
* **隔离性:** 使用 `UUID` 内部管理设置项,确保即使注册名相似也不会发生引用冲突。
|
||||
* **健壮性:** 在加载背景图片或字体时,会自动检查物理文件是否存在及字体在当前系统中是否可用,防止因配置损坏导致启动崩溃。
|
||||
|
||||
---
|
||||
*文档生成时间: 2026-01-02*
|
||||
110
api-documentation/register/RegistrationTool.md
Normal file
110
api-documentation/register/RegistrationTool.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# RegistrationTool 类技术文档
|
||||
|
||||
**包路径:** `com.axis.innovators.box.register.RegistrationTool`
|
||||
**主要功能:** 工具箱组件注册中心、功能分类管理器
|
||||
**作者:** tzdwindows 7
|
||||
|
||||
---
|
||||
|
||||
## 1. 概述
|
||||
|
||||
`RegistrationTool` 是 **Axis Innovators Box** 的功能调度核心。它负责管理主程序中所有的工具项(`ToolItem`)及其所属的分类(`ToolCategory`)。通过该类,开发者可以将各种功能模块(如调试工具、编程环境、AI 推理等)注册到主界面的工具栏中。
|
||||
|
||||
该类不仅内置了丰富的系统工具,还为外部插件提供了一套标准的扩展接口,支持基于命名空间的工具注册逻辑。
|
||||
|
||||
## 2. 核心职责
|
||||
|
||||
* **功能分类管理:** 将相似功能的工具组织在 `ToolCategory` 下(如“调试工具”、“AI工具”)。
|
||||
* **工具项路由:** 定义点击工具图标后的具体行为(通过 `AbstractAction` 实现窗口弹出或逻辑执行)。
|
||||
* **插件扩展支持:** 提供 API 允许插件在加载时动态注入自定义工具。
|
||||
* **唯一性校验:** 确保每个注册项拥有唯一的 `UUID` 和注册名称(Registered Name),防止冲突。
|
||||
* **平台适配:** 在初始化时根据 `BuildInformation` 检查操作系统兼容性(主要针对 Windows)。
|
||||
|
||||
## 3. 内置工具分类
|
||||
|
||||
在 Windows 系统环境下,`RegistrationTool` 默认初始化以下分类及工具:
|
||||
|
||||
### 3.1 调试工具 (Debug Tools)
|
||||
* **Frida 注入工具:** 使用 Frida 框架对目标进程进行脚本注入。
|
||||
|
||||
### 3.2 编程工具 (Programming Tools)
|
||||
* **JarApi 查看器:** 反射查看 JAR 包内的方法定义及其注解。
|
||||
* **C 语言编辑器:** 智能化的 C 语言编译与编辑环境。
|
||||
* **多语言在线执行:** 支持多种编程语言的实时在线运行,具备无限循环检测机制。
|
||||
* **数据库管理:** 跨平台的数据库管理客户端。
|
||||
* **Linux 终端:** 启动一个真实的 Linux 终端模拟环境。
|
||||
* **MySQL 控制台:** 模拟 MySQL 命令行交互界面。
|
||||
|
||||
### 3.3 AI 工具 (AI Tools)
|
||||
* **本地 AI 执行工具:** 在本地运行开源大语言模型(LLM)。支持自动加载 **CUDA** 硬件加速库(通过 `LM` 类)。
|
||||
|
||||
### 3.4 系统工具 (System Tools)
|
||||
* **任务栏主题设置:** 深度定制 Windows 任务栏的外观、颜色和透明度。
|
||||
|
||||
---
|
||||
|
||||
## 4. 插件扩展机制
|
||||
|
||||
`RegistrationTool` 支持插件化扩展,插件可以通过以下方法将自己的工具分类注册到主程序中:
|
||||
|
||||
```java
|
||||
public void addToolCategory(ToolCategory toolCategory,
|
||||
PluginDescriptor pluginDescriptor,
|
||||
String registeredName)
|
||||
```
|
||||
|
||||
**命名空间规则:**
|
||||
为了防止不同插件之间的工具冲突,系统会自动使用 `插件注册名:工具注册名` 的格式生成全局唯一的标识符。
|
||||
|
||||
---
|
||||
|
||||
## 5. API 接口说明
|
||||
|
||||
### 5.1 注册方法
|
||||
|
||||
| 方法 | 描述 |
|
||||
| :--- | :--- |
|
||||
| `addToolCategory(ToolCategory, String)` | 注册一个新的工具分类(系统级使用)。 |
|
||||
| `addToolCategory(ToolCategory, PluginDescriptor, String)` | **插件专用接口**。通过插件描述符注册分类。 |
|
||||
|
||||
### 5.2 查询方法
|
||||
|
||||
| 方法 | 描述 |
|
||||
| :--- | :--- |
|
||||
| `ToolCategory getToolCategory(UUID id)` | 根据 UUID 获取分类对象。 |
|
||||
| `UUID getUUID(String registeredName)` | 根据注册名称(如 "system:debugTools")获取其 UUID。 |
|
||||
| `List<ToolCategory> getToolCategories()` | 获取当前所有已注册的分类列表。 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 关键技术约束:注册时机
|
||||
|
||||
**生命周期限制:**
|
||||
`RegistrationTool` 的注册操作具有严格的时机限制:**必须在应用主窗口启动(`run` 方法执行完毕)之前完成。**
|
||||
|
||||
* 如果在主窗口已处于显示状态(`main.isWindow()` 为 `true`)时尝试添加工具,系统会通过日志记录 `logger.warn("Wrong time to add tools")` 并拒绝注册。
|
||||
* 这种设计确保了 UI 在渲染初期能获得完整的工具树,避免动态修改 UI 导致的线程竞争或布局闪烁。
|
||||
|
||||
---
|
||||
|
||||
## 7. 错误处理
|
||||
|
||||
如果在注册过程中检测到**重复的注册名称**,该类会抛出 `RegistrationError`。这是一种致命错误,旨在提醒开发者工具标识符冲突,必须在开发阶段解决。
|
||||
|
||||
## 8. 示例代码:添加简单工具
|
||||
|
||||
```java
|
||||
ToolCategory myCategory = new ToolCategory("我的工具", "icon.png", "说明");
|
||||
myCategory.addTool(new ToolItem("弹窗演示", "btn.png", "点击会弹出消息", 100, new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JOptionPane.showMessageDialog(null, "你好,这是注册工具!");
|
||||
}
|
||||
}));
|
||||
|
||||
// 注册到系统
|
||||
registrationTool.addToolCategory(myCategory, "my_custom_tools");
|
||||
```
|
||||
|
||||
---
|
||||
*文档生成时间: 2026-01-02*
|
||||
98
api-documentation/register/RegistrationTopic.md
Normal file
98
api-documentation/register/RegistrationTopic.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# RegistrationTopic 类技术文档
|
||||
|
||||
**包路径:** `com.axis.innovators.box.register.RegistrationTopic`
|
||||
**主要功能:** 主题/外观 (LookAndFeel) 注册中心、视觉模式管理
|
||||
**作者:** tzdwindows 7
|
||||
|
||||
---
|
||||
|
||||
## 1. 概述
|
||||
|
||||
`RegistrationTopic` 是 **Axis Innovators Box** 框架中负责视觉外观管理的核心组件。它充当了一个“主题仓库”,统一管理应用程序支持的所有 `LookAndFeel`(外观)。通过该类,开发者可以注册系统原生主题、第三方现代主题(如 FlatLaf、Material UI)以及自定义的视觉样式。
|
||||
|
||||
该类不仅存储主题的实现,还记录了主题的元数据(名称、图标、描述)以及色彩属性(明/暗模式),为设置中心的 UI 渲染和全局主题切换提供了数据支持。
|
||||
|
||||
## 2. 核心职责
|
||||
|
||||
* **多模式注册:** 支持通过“类全限定名(String)”或“主题实例(LookAndFeel)”两种方式注册主题。
|
||||
* **状态追踪:** 记录当前正在加载的主题,并提供实时状态查询。
|
||||
* **明/暗模式识别:** 维护每个主题的色彩属性,允许框架根据当前主题自动调整其他组件(如代码编辑器、图标)的色调。
|
||||
* **生命周期保护:** 严格限制注册时机,确保 UI 稳定性。
|
||||
|
||||
## 3. 核心机制详解
|
||||
|
||||
### 3.1 双路注册支持
|
||||
为了兼容不同的 UI 库,`RegistrationTopic` 提供了重载的 `addTopic` 方法:
|
||||
1. **基于类名注册:** 适用于 JVM 默认提供的或在类路径下的标准主题(如 `UIManager.getSystemLookAndFeelClassName()`)。
|
||||
2. **基于实例注册:** 适用于需要初始化参数的现代主题(如 `new FlatMacDarkLaf()`),这允许主题在注册前进行预配置。
|
||||
|
||||
### 3.2 同步列表结构
|
||||
该类内部使用多个对齐的 `ArrayList` 来维护数据。每个主题在所有列表中的索引(Index)是统一的。例如,索引为 `5` 的项,其类名、图标、描述和暗黑模式标志位都存储在各自列表的第 `5` 位。
|
||||
|
||||
### 3.3 明/暗模式感知 (`isDarkMode`)
|
||||
该方法通过查找当前活跃主题(`loadTopics`)在注册列表中的位置,返回其对应的 `isDarkMode` 布尔值。这对于实现“跟随主题自动切换图标颜色”等高级 UI 特性至关重要。
|
||||
|
||||
---
|
||||
|
||||
## 4. API 接口说明
|
||||
|
||||
### 4.1 注册方法
|
||||
|
||||
| 方法签名 | 描述 |
|
||||
| :--- | :--- |
|
||||
| `addTopic(String class, String name, String tip, Icon icon, String regName, boolean isDark)` | 通过主题类名注册。 |
|
||||
| `addTopic(LookAndFeel laf, String name, String tip, Icon icon, String regName, boolean isDark)` | 通过 LookAndFeel 实例注册。 |
|
||||
|
||||
### 4.2 状态管理与查询
|
||||
|
||||
| 方法 | 描述 |
|
||||
| :--- | :--- |
|
||||
| `void setLoading(String regName)` | 设置当前激活的主题 ID(注册名)。 |
|
||||
| `boolean isLoading(String regName)` | 检查指定的主题是否是当前正在使用的主题。 |
|
||||
| `boolean isDarkMode()` | 获取当前激活的主题是否属于暗黑模式。 |
|
||||
| `boolean isEmpty()` | 检查仓库中是否尚未注册任何主题。 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 关键约束:注册时机
|
||||
|
||||
与 `RegistrationTool` 类似,`RegistrationTopic` 具有严格的**时机约束**:
|
||||
|
||||
* **限制:** 所有的主题注册必须在 `AxisInnovatorsBox.isWindow()` 为 `false` 时进行(即主窗口启动前)。
|
||||
* **违规处理:** 如果在窗口显示后尝试调用 `addTopic`,系统会记录警告日志:`logger.warn("Wrong time to add topics")`,且该注册请求会被忽略。
|
||||
* **设计目的:** 保证 Swing 的 `UIManager` 状态在初始化阶段是确定的,防止运行时切换导致的界面渲染异常或部分组件更新失败。
|
||||
|
||||
## 6. 错误处理
|
||||
|
||||
如果在注册过程中出现**重复的注册名称**(`registeredName`),该类会抛出 `RegistrationError`。这确保了每个主题在设置界面和配置文件中都有唯一的引用 ID。
|
||||
|
||||
## 7. 使用示例
|
||||
|
||||
在 `AxisInnovatorsBox` 初始化阶段注册主题:
|
||||
|
||||
```java
|
||||
RegistrationTopic topicRegistry = main.getRegistrationTopic();
|
||||
|
||||
// 1. 注册系统默认主题
|
||||
topicRegistry.addTopic(
|
||||
UIManager.getSystemLookAndFeelClassName(),
|
||||
"系统默认",
|
||||
"使用操作系统的原生外观",
|
||||
null,
|
||||
"system:native",
|
||||
false
|
||||
);
|
||||
|
||||
// 2. 注册 FlatLaf 现代暗黑主题
|
||||
topicRegistry.addTopic(
|
||||
new com.formdev.flatlaf.themes.FlatMacDarkLaf(),
|
||||
"MacOS Dark",
|
||||
"现代化的深色苹果风格界面",
|
||||
new ImageIcon("mac_dark_icon.png"),
|
||||
"system:flatMacDark",
|
||||
true
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
*文档生成时间: 2026-01-02*
|
||||
Reference in New Issue
Block a user