Files
window-axis-innovators-box1.17/README.md
lanxi f0b6f540e0 更新 README.md
Signed-off-by: lanxi <3636115238@qq.com>
2026-02-09 22:55:06 +08:00

320 lines
10 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.

# AxisInnovatorsBox Window API
[项目链接](https://gitea.lingqi.vip/lanxi/window-axis-innovators-box1.17) | [官网](https://box.lingqi.vip) | 简体中文
---
## 📖 项目概述
`AxisInnovatorsBoxWindowApi` 是专为 **AxisInnovatorsBox** 平台打造的核心扩展 API 库。它赋予开发者创建自定义插件的能力,支持窗口深度管理、跨语言事件交互及 UI 定制。该仓库包含完整的接口定义、开发文档及示例代码,旨在帮助开发者无缝接入并扩展 AxisInnovatorsBox 生态系统。
## ✨ 功能特性
* 🖥️ **全生命周期窗口管理** - 精确控制窗口创建、销毁、最小化/最大化及模态状态。
* 🎮 **事件驱动架构** - 基于发布/订阅模式的事件总线,支持系统级事件监听与自定义事件广播。
* 📦 **多语言插件引擎** - 原生支持 Java 插件,并通过 Jython 实现 Python 插件的无缝加载与互操作。
* 📄 **动态配置与国际化** - 支持通过 Properties 灵活管理配置,提供完整的 I18n 多语言支持。
* 📊 **统一日志系统** - 集成 Java 日志框架,自动捕获并同步 Python 插件的运行日志与异常堆栈。
---
## 🧩 插件开发指南
插件加载系统是程序的核心组件,由主程序内部自动调度。
### 1. Java 插件开发 (Jar)
Jar 格式插件需放置在 `/plug-in` 目录下。
**核心注解 `@PluginMeta`**
用于描述插件的基本信息。系统会自动实例化被标记的类,并填充 `INSTANCE` 字段。
```java
package com.example.plugin;
import com.axis.innovators.box.plugins.PluginDescriptor;
import com.axis.innovators.box.plugins.PluginMeta;
import com.axis.innovators.box.events.GlobalEventBus;
import com.axis.innovators.box.events.StartupEvent;
import com.axis.innovators.box.events.SubscribeEvent;
import com.axis.innovators.box.window.MainWindow;
@PluginMeta(
id = "test_plugin",
name = "测试插件",
version = "1.0.0",
supportedVersions = {"0.0.2"},
description = "这是一个Java插件示例",
icon = "icon.png",
registeredName = "test"
)
public class Template {
// 系统加载时会自动注入此描述符
public static PluginDescriptor INSTANCE = null;
public Template() {
// 在构造函数中注册事件监听
GlobalEventBus.EVENT_BUS.register(this);
}
@SubscribeEvent
public void onStartup(StartupEvent event) {
// 在启动事件中注册工具栏分类
MainWindow.ToolCategory category = new MainWindow.ToolCategory("测试分类", "test_icon", "分类描述");
event.main().getRegistrationTool().addToolCategory(
category,
INSTANCE,
"templatePlugin::category"
);
}
}
```
### 2. Python 插件开发 (Script)
Python 插件需放置在 `/plug-in/python` 的子目录中(例如 `/plug-in/python/Examples`。Python 脚本可直接调用 Java 类库。
**必要文件结构**
* `metadata.json`: 插件元数据
* `main.py`: 入口脚本
**metadata.json 示例**
```json
{
"id": "py_testing",
"name": "Python测试插件",
"version": "0.0.1",
"description": "Python脚本插件示例",
"author": "tzdwindows 7",
"dependencies": [],
"_comment": {
"path": "资源文件应放置在 plugins/{id}/ 目录下"
}
}
```
**main.py 示例**
```python
"""
功能:注册自定义工具类别和工具项
"""
from com.axis.innovators.box.python import PyLocalSide
from javax.swing import AbstractAction
class MyAction(AbstractAction):
def actionPerformed(self, event):
print("[DEBUG] Python工具项被点击事件源:", event.getSource())
def onStartup():
"""系统启动钩子函数"""
print('[INFO] 初始化Python插件...')
# 1. 创建工具类别
tool_category = PyLocalSide.getToolCategory(
u"数据分析", # 名称
u"analytics.png", # 图标
u"Python数据分析工具" # 描述
)
# 2. 创建并添加工具项
tool_action = MyAction()
tool_item = PyLocalSide.getToolItem(
u"生成图表",
u"chart.png",
u"点击生成报表",
1001,
tool_action
)
tool_category.addTool(tool_item)
# 3. 注册到系统
PyLocalSide.addToolCategory(
tool_category,
u"py_module::analysis"
)
print('[SUCCESS] Python插件加载完成')
# 将 onStartup 绑定到全局作用域,供 Java 端调用
if __name__ == '__main__':
globals()['onStartup'] = onStartup
```
### 3. CorePlugins (字节码增强)
CorePlugins 允许在类加载阶段修改目标类的字节码ASM
**配置步骤**
1.`build.gradle` 中声明 Manifest 属性:
```groovy
jar {
manifest {
attributes 'CorePlugin': 'com.axis.core.template.TemplateLoadingCorePlugin'
}
}
```
2. 实现 `LoadingCorePlugin` 接口:
```java
public class TemplateLoadingCorePlugin implements LoadingCorePlugin {
@Override
public String getMainClass() {
return Template.class.getName(); // 返回插件主类
}
@Override
public String[] getASMTransformerClass() {
return new String[]{TemplateTransformer.class.getName()}; // 返回Transformer类
}
}
```
3. 实现 `IClassTransformer` 接口(使用 ASM 修改字节码):
```java
public class TemplateTransformer implements IClassTransformer {
@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
// 使用 ASM ClassReader/ClassWriter 修改字节码
// 示例:将所有 private 字段和方法修改为 public
// ... (省略具体ASM代码参考原文档)
return modifiedBytes;
}
}
```
---
## 📡 事件驱动系统
基于 `EventBus` 的发布/订阅模式,实现模块解耦与通信。
### 核心组件
* `EventBus`: 基础事件总线。
* `GlobalEventBus.EVENT_BUS`: **全局单例总线**,用于跨模块通信。
### 使用示例
```java
// 1. 定义事件
public class UserLoginEvent {
private final String username;
public UserLoginEvent(String u) { this.username = u; }
// getters...
}
// 2. 注册监听器 (@SubscribeEvent)
public class LoginLogger {
public LoginLogger() {
GlobalEventBus.EVENT_BUS.register(this);
}
@SubscribeEvent
public void onLogin(UserLoginEvent event) {
System.out.println("用户登录: " + event.getUsername());
}
}
// 3. 发布事件
GlobalEventBus.EVENT_BUS.post(new UserLoginEvent("admin"));
```
### 内置系统事件表
| 事件类名 | 描述 |
| :--- | :--- |
| `StartupEvent` | 程序启动完成事件,常用于注册工具栏 |
| `SettingsLoadEvents` | 设置界面初始化事件,用于添加设置项 |
| `MainWindowEvents` | 主窗口生命周期相关事件 |
| `CategoryRenderingEvent` | 工具栏分类渲染事件 |
| `OpenFileEvents` | 外部文件打开请求事件 |
| `TABUIEvents` | 选项卡 UI 属性变更事件 |
---
## 🌐 HTML 窗口集成 (JCEF)
通过 JCEF (Chromium) 渲染高性能 HTML/JS 界面,并支持与 Java 双向通信。
### 创建 HTML 窗口
```java
SwingUtilities.invokeLater(() -> {
WindowRegistry.getInstance().createNewChildWindow("ai_toolbox", builder -> {
builder.title("AI 工具箱")
.size(1280, 720)
.htmlPath(FolderCreator.getJavaScriptFolder() + "/ui/index.html") // 本地HTML路径
.build();
});
});
```
### Java 与 JavaScript 通信 (`CefMessageRouter`)
**1. JavaScript 调用 Java**
```javascript
// 在前端 JS 中调用
window.cefQuery({
request: JSON.stringify({ action: "getData", id: 1 }),
onSuccess: function(response) { console.log("Java返回:", response); },
onFailure: function(code, msg) { console.error("错误:", msg); }
});
```
**2. Java 处理请求**
```java
// 获取路由并添加处理器
CefMessageRouter router = window.getMsgRouter();
router.addHandler(new CefMessageRouterHandlerAdapter() {
@Override
public boolean onQuery(CefBrowser browser, CefFrame frame, long queryId,
String request, boolean persistent, CefQueryCallback callback) {
if (request.contains("getData")) {
callback.success("{\"data\": \"Hello from Java\"}");
return true;
}
return false;
}
}, true);
```
**3. HTML 监听 Java 事件**
HTML 页面可监听来自 Java 的系统级通知:
* `javaFontsLoaded`: 字体加载完成。
* `javaThemeChanged`: 主题变更通知。
```javascript
document.addEventListener('javaThemeChanged', (e) => {
console.log('主题变更为:', e.detail);
});
```
---
## 📚 核心 API 参考
### 1. `AxisInnovatorsBox` (主程序入口)
获取应用全局状态和核心管理器。
* `getInstance()` / `getMain()`: 获取单例。
* `getRegistrationTool()`: 获取工具注册器。
* `getRegistrationTopic()`: 获取主题注册器。
* `getMainWindow()`: 获取主窗口对象。
* `popupWindow(WindowsJDialog)` / `clearWindow(...)`: 窗口堆栈管理。
### 2. `RegistrationTool` (工具注册)
在 `StartupEvent` 中使用,用于向主界面添加功能入口。
* `addToolCategory(category, regName)`: 注册工具分类。
* `getToolCategory(UUID)`: 获取已注册分类。
### 3. `RegistrationTopic` (主题注册)
在初始化阶段注册自定义 LookAndFeel 或主题类。
* `addTopic(topicClass, name, tip, icon, regName)`: 注册主题。
* **注意**: 注册名称 (`regName`) 必须唯一,否则会抛出异常。
### 4. `RegistrationSettingsItem` (设置项注册)
在 `SettingsLoadEvents` 中使用,向设置中心添加面板。
* `addSettings(JPanel panel, String title, Icon icon, String tip, PluginDescriptor plugin, String regName)`: 注册设置页。
### 5. `StateManager` (状态持久化)
用于保存插件配置或用户偏好设置(键值对)。
* `saveState(key, value)`: 持久化保存。
* `getStateAsString(key)` / `getStateAsInt(key)`: 读取配置。
### 6. `LanguageManager` (国际化)
* `addLanguage(Language lang)`: 注册新的语言包。
* `getLanguage(String id)`: 获取特定语言资源。
### 7. `WindowRegistry` (窗口管理)
统一管理 JCEF 和原生 Swing 窗口的生命周期。
* `createNewChildWindow(id, config)`: 创建模态子窗口。
* `unregisterWindow(id)`: 安全关闭并注销窗口。