tzdwindows 7 d2e40744cf refactor(browser): 重构消息路由和界面组件以支持双路由和主题适配
- 实现双CefMessageRouter配置,支持javaQuery和cefQuery两种查询方式
- 移除handler判空注释,优化system请求处理逻辑
- 修复java-response解析中的数组越界问题
- 添加运行时计时器管理,避免计时器冲突
- 优化背景图绘制和主题色动态适配
- 实现卡片组件的动态布局和悬停效果
- 改进搜索框的动画和主题适配
- 修复JAR文件处理中的异常捕获和错误响应
- 优化工具卡片的鼠标事件处理和线程安全
- 实现响应式面板布局和组件尺寸同步
2026-01-03 10:41:24 +08:00
2025-08-18 00:15:31 +08:00
2025-02-05 15:02:27 +08:00
2025-02-05 15:02:27 +08:00
2025-02-05 15:02:27 +08:00

AxisInnovatorsBox Window API

项目链接 | 官网 | 简体中文


📖 项目概述

AxisInnovatorsBoxWindowApi 是专为 AxisInnovatorsBox 平台打造的核心扩展 API 库。它赋予开发者创建自定义插件的能力,支持窗口深度管理、跨语言事件交互及 UI 定制。该仓库包含完整的接口定义、开发文档及示例代码,旨在帮助开发者无缝接入并扩展 AxisInnovatorsBox 生态系统。

功能特性

  • 🖥️ 全生命周期窗口管理 - 精确控制窗口创建、销毁、最小化/最大化及模态状态。
  • 🎮 事件驱动架构 - 基于发布/订阅模式的事件总线,支持系统级事件监听与自定义事件广播。
  • 📦 多语言插件引擎 - 原生支持 Java 插件,并通过 Jython 实现 Python 插件的无缝加载与互操作。
  • 📄 动态配置与国际化 - 支持通过 Properties 灵活管理配置,提供完整的 I18n 多语言支持。
  • 📊 统一日志系统 - 集成 Java 日志框架,自动捕获并同步 Python 插件的运行日志与异常堆栈。

🧩 插件开发指南

插件加载系统是程序的核心组件,由主程序内部自动调度。

1. Java 插件开发 (Jar)

Jar 格式插件需放置在 /plug-in 目录下。

核心注解 @PluginMeta 用于描述插件的基本信息。系统会自动实例化被标记的类,并填充 INSTANCE 字段。

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 示例

{
  "id": "py_testing",
  "name": "Python测试插件",
  "version": "0.0.1",
  "description": "Python脚本插件示例",
  "author": "tzdwindows 7",
  "dependencies": [],
  "_comment": {
    "path": "资源文件应放置在 plugins/{id}/ 目录下"
  }
}

main.py 示例

"""
功能:注册自定义工具类别和工具项
"""
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 属性:
    jar {
        manifest {
            attributes 'CorePlugin': 'com.axis.core.template.TemplateLoadingCorePlugin'
        }
    }
    
  2. 实现 LoadingCorePlugin 接口:
    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 修改字节码):
    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: 全局单例总线,用于跨模块通信。

使用示例

// 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 窗口

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

// 在前端 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 处理请求

// 获取路由并添加处理器
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: 主题变更通知。
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): 安全关闭并注销窗口。
Description
No description provided
Readme 847 MiB
Languages
JavaScript 43.1%
Java 23.1%
C 22.3%
HTML 6.5%
CSS 3.2%
Other 1.8%