覆写现有页面
本文档详细介绍了在 SCE-Universe_Java_Edition 中如何通过模块化系统覆写(即替换)现有页面。
概述
SCE-Universe_Java_Edition 应用程序采用模块化设计,允许开发者通过插件(Mods)扩展或修改其核心行为。其中一个关键特性是能够覆写应用程序的默认页面。这意味着开发者可以创建自定义页面,并将其注册到系统中,以替换由应用程序核心提供的任何现有页面。
此机制的核心在于 PageManager 和 modloader_main 接口。应用程序的页面由实现 pageheader 抽象类的具体类表示,并通过唯一的整数 ID 进行标识。ModLoader 系统在应用启动时加载外部 JAR 文件中的模块,这些模块可以利用 PageManager.addPage() 方法注册自己的页面实现,从而实现对现有页面的替换。
何时使用:
- 需要完全改变某个页面的用户界面和交互逻辑。
- 希望在不修改核心应用程序代码的情况下,为特定页面添加新功能。
- 创建主题或定制化版本,以提供不同的用户体验。
架构
页面的管理和覆写功能涉及 PageManager、pageheader 和 ModLoader 模块。PageManager 维护所有注册页面的映射,而 ModLoader 则负责发现、加载并激活允许覆写页面的插件。
Source:
架构说明:
pageheader: 所有页面的抽象基类,定义了页面的核心行为,如run()方法来执行页面逻辑,以及buildPage()和handlePageInput()来处理 UI 渲染和用户输入。PageManager: 作为pageheader的子类,它是一个抽象类,负责维护一个static的页面映射 (_pages)。addPage方法允许向这个映射中添加页面。router_core:PageManager的具体实现,包含了应用程序的主要页面导航循环。它调用当前页面的run()方法,并根据其返回值切换到下一个页面。它还集成了ModLoader的功能,允许模块在页面生命周期中介入。pages: 一个常量类,定义了所有内置页面的整数 ID。ModLoader: 模块加载系统,由modlist和modloader_main接口组成。modlist负责扫描插件目录(plugins/),加载 JAR 文件,并实例化实现modloader_main接口的类。modloader_main: 模块接口,定义了插件的生命周期方法 (onEnable(),onDisable()) 以及与页面系统交互的方法 (innerToPage(),innerHandle())。
核心流程:覆写页面
覆写现有页面的核心流程是通过 ModLoader 系统在应用程序启动时动态替换页面注册表中的条目。
流程说明:
- 应用程序启动:当
SCE-Universe_Java_Edition应用程序启动时,它会初始化ModLoader。 - 模块加载:
Modlist扫描plugins/目录下的 JAR 文件,并动态加载实现modloader_main接口的类。 - 模块启用:对于每个加载的自定义模块 (
MyCustomMod),Modlist会调用其onEnable()方法。 - 页面覆写:在
onEnable()方法内部(或在innerToPage()中),自定义模块会创建其自定义页面 (MyCustomPage) 的实例,并使用PageManager.addPage(EXISTING_PAGE_ID, MyCustomPageInstance)方法将其注册到PageManager的_pages映射中。如果EXISTING_PAGE_ID已经存在,则新的自定义页面实例将替换原有的页面实例。 - 页面导航:当应用程序的
router_core开始其页面导航循环时,它会从PageManager获取当前页面。由于之前已执行覆写,router_core将检索到MyCustomPageInstance。 - 自定义页面运行:
router_core调用MyCustomPageInstance的run()方法。此方法执行自定义页面的逻辑,包括buildPage()(渲染 UI)和handlePageInput()(处理用户输入)。页面返回下一个页面 ID,导航循环继续。
使用示例
要覆写一个现有页面,您需要创建一个实现 modloader_main 接口的模块,并在其中注册您的自定义页面。
1. 定义您的自定义页面
您的自定义页面类必须继承 cn.oraclestar.sce.system.router.pageheader 抽象类,并至少实现 run() 方法。通常,您还会覆写 buildPage() 来定义页面内容,以及 handlePageInput() 来处理用户输入。
例如,覆写 start 页面 (ID 为 pages.START):
1package com.yourcompany.mod.pages;
2
3import cn.oraclestar.sce.system.global;
4import cn.oraclestar.sce.system.router.pageheader;
5import cn.oraclestar.sce.system.router.pages;
6import cn.oraclestar.sce.system.UI.Color;
7
8public class MyCustomStartPage extends pageheader {
9
10 private global global_var = global.getcore(); // 访问全局变量
11
12 @Override
13 protected void buildPage() throws Exception {
14 _ui.insertTitle("【自定义】欢迎来到我的启动页面!", Color.GREEN);
15 _ui.insertOption("开始新的旅程", 1);
16 _ui.insertOption("加载旧的存档", 2);
17 _ui.insertOption("退出应用程序", 0);
18 _ui.insertNewLine();
19 _ui.insertInput();
20 }
21
22 @Override
23 protected int handlePageInput(String input) {
24 if (input.equals("1")) {
25 // 假设 EVALUATE 是创建新旅程的页面
26 return pages.EVALUATE;
27 } else if (input.equals("2")) {
28 // 假设 OPEN 是加载存档的页面
29 return pages.OPEN;
30 } else if (input.equals("0")) {
31 return pages.EXIT;
32 } else {
33 _ui.display("无效的选项,请重试。", true, Color.RED);
34 return pages.CURRENT; // 停留在当前页面
35 }
36 }
37
38 @Override
39 public int run() throws Exception {
40 int nextPage = pages.CURRENT;
41 while (nextPage == pages.CURRENT) {
42 _ui.cls(); // 清屏
43 _ui.reset(); // 重置UI
44 buildPage(); // 构建页面UI
45 _ui.run(); // 显示UI
46 String input = _ui.getUserInput(); // 获取用户输入
47 nextPage = handlePageInput(input); // 处理用户输入
48 }
49 return nextPage;
50 }
51}Sources:
2. 创建您的自定义模块
您的模块类必须实现 cn.oraclestar.sce.system.modloader.modloader_main 接口。在 onEnable() 或 innerToPage() 方法中,您可以使用 PageManager.addPage() 注册您的自定义页面。
1package com.yourcompany.mod;
2
3import cn.oraclestar.sce.system.UI.UI_core;
4import cn.oraclestar.sce.system.modloader.modloader_main;
5import cn.oraclestar.sce.system.modloader.target;
6import cn.oraclestar.sce.system.router.PageManager;
7import cn.oraclestar.sce.system.router.pages;
8import com.yourcompany.mod.pages.MyCustomStartPage; // 导入您的自定义页面
9
10@target(name = "MyCustomMod", author = "YourName", version = "1.0.0", Description = "覆写启动页面的示例模块")
11public class MyCustomMod implements modloader_main {
12
13 @Override
14 public void onEnable() {
15 System.out.println("[MyCustomMod] 模块已启用,正在注册自定义页面...");
16 // 覆写 pages.START 页面
17 PageManager.addPage(pages.START, new MyCustomStartPage());
18 System.out.println("[MyCustomMod] MyCustomStartPage 已成功注册为启动页面。");
19 }
20
21 @Override
22 public void onDisable() {
23 System.out.println("[MyCustomMod] 模块已禁用。");
24 }
25
26 @Override
27 public void innerToPage(UI_core ui_core, int now_page) {
28 // 模块可以在这里对页面显示进行额外处理,如果需要的话
29 // 例如:ui_core.display("当前页面: " + now_page, true);
30 }
31
32 @Override
33 public int innerHandle(String input, int now_page) {
34 // 模块可以在这里处理用户输入,如果需要的话
35 // 返回 pages.CURRENT 表示由当前页面处理
36 // 返回其他页面ID表示切换页面
37 return pages.CURRENT;
38 }
39}Sources:
- modloader_main.java
- PageManager.java
- pages.java
- target.java (Implied, as it's an annotation for mod metadata)
3. 构建并部署模块
- 将您的自定义页面和模块类编译成一个 JAR 文件。确保 JAR 中包含所有必要的类文件。
- 将生成的 JAR 文件放置到应用程序根目录下的
plugins/文件夹中。 - 启动
SCE-Universe_Java_Edition应用程序。ModLoader 将会自动加载您的模块,并在启动时覆写pages.START页面。
配置选项
覆写现有页面主要依赖于 ModLoader 的配置,而不是特定的配置文件。
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
plugins/ | 目录 | 应用程序根目录下的 plugins/ | 模块加载器扫描 JAR 文件的主要目录。所有自定义模块 JAR 文件应放置在此处。 |
plugins/preload/ | 目录 | 应用程序根目录下的 plugins/preload/ | 模块加载器扫描 JAR 文件的预加载目录。此目录下的模块可能会在主模块之前加载。 |
API 参考
cn.oraclestar.sce.system.router.PageManager
static void addPage(int id, pageheader page)
注册或覆写一个页面。如果 id 对应的页面已存在,则会替换为新的 page 实例。
id(int): 页面的唯一整数 ID,通常来自cn.oraclestar.sce.system.router.pages常量。page(cn.oraclestar.sce.system.router.pageheader): 要注册或覆写的页面实例。
返回: 无
抛出: 无
Source: PageManager.java
cn.oraclestar.sce.system.modloader.modloader_main (Interface)
模块实现此接口以与 ModLoader 系统交互。
void onEnable()
当模块被加载和启用时调用。这是注册自定义页面的理想时机。
返回: 无
抛出: 无
Source: modloader_main.java
void innerToPage(cn.oraclestar.sce.system.UI.UI_core ui_core, int now_page)
在页面显示之前,由 router_core 调用。模块可以在此方法中对 UI 或页面行为进行额外调整。
ui_core(cn.oraclestar.sce.system.UI.UI_core): 应用程序的 UI 核心实例。now_page(int): 当前页面的 ID。
返回: 无
抛出: 无
Source: modloader_main.java