路由与页面 (router_core)
router_core 模块提供了一套用于构建和管理控制台应用程序用户界面的路由和页面导航机制。它允许开发者定义不同的“页面”,并通过用户输入实现页面间的流畅切换。
概述
router_core 及其相关组件构成了一个轻量级的控制台界面框架。应用程序启动后,会注册所有可用的页面,并由 router_core 管理这些页面的生命周期和导航。每个页面负责渲染其自身的内容并处理用户的输入,根据输入决定下一个要显示的页面。这种设计模式使得控制台应用的交互逻辑清晰,易于扩展和维护。
核心功能:
- 页面注册: 将页面ID与页面实例关联。
- 页面导航: 根据用户输入,从一个页面切换到另一个页面。
- 页面渲染: 定义每个页面的显示内容。
- 用户输入处理: 捕获并解释用户在当前页面上的输入。
- 状态管理: 跟踪当前活动页面。
架构
整个路由和页面管理系统围绕 pageheader、PageManager 和 router_core 这三个核心抽象构建。UI_core 提供了底层的控制台交互能力,而 pages 类则定义了所有页面的唯一标识符。
组件说明:
UI_core: 这是一个静态工具类,负责底层的控制台输入/输出操作,例如清屏、显示文本、获取用户输入等。所有页面都通过它与用户交互。pageheader: 所有页面的抽象基类。它维护一个静态的UI_core实例供所有页面共享,并定义了所有具体页面必须实现的run()抽象方法。run()方法的返回值是一个整数,代表下一个要导航到的页面ID。PageManager: 一个抽象类,继承自pageheader。它负责管理一个静态的Map(_pages) 来存储所有注册的页面实例,以及一个静态变量 (_currentPage) 来追踪当前激活的页面。它提供了静态方法addPage用于页面注册,并声明了由router_core实现的抽象方法setInitialPage和start。router_core: 路由系统的核心实现,继承自PageManager。它实现了setInitialPage和start()方法,并包含了驱动整个页面导航逻辑的主循环。它还提供了innermod()方法,可能用于与模块加载器进行交互。值得注意的是,具体的页面实现(如AboutPage)也直接继承自router_core,并重写buildPage()和handlePageInput()方法来定制其行为。这意味着router_core同时扮演了路由协调者和具体页面的抽象基类的角色。pages: 一个纯静态类,包含了所有预定义的页面ID及其特殊控制ID(如EXIT和CURRENT)的整数常量。ConcretePage(例如about类): 这些是应用程序中实际的用户界面。它们继承router_core,并重写buildPage()来定义页面的显示内容,重写handlePageInput(String input)来处理用户的输入并返回下一个页面的ID。
核心流程
应用程序的页面导航流程从 App.main 方法开始,经过页面的初始化和注册,最终由 router_core 启动并循环执行。
流程说明:
- 应用启动:
App类是应用程序的入口点,它创建router_core的实例。 - 页面注册: 在
App.register()方法中,应用程序通过router_core.addPage()静态方法将所有的具体页面实例及其对应的ID注册到路由系统中。 - 设置初始页面: 应用程序调用
router.setInitialPage()来设定应用启动时首先显示的页面。 - 启动路由: 调用
router.start()方法,启动路由的主循环。 - 页面执行: 在主循环中,
router_core会获取当前页面ID对应的页面实例,并调用其run()方法。 - 页面内容构建与输入: 每个具体页面的
run()方法(通常通过router_core的实现)会调用buildPage()来构建并显示页面的UI元素,然后调用UI_core.getUserInput()等待用户输入。 - 输入处理与页面切换: 接收到用户输入后,页面实例的
handlePageInput()方法会被调用。该方法根据输入逻辑,返回下一个要导航到的页面ID (pages.DESCRIPTION,pages.MAIN等),或者指示停留在当前页面 (pages.CURRENT)。 - 循环与退出:
router_core根据handlePageInput()返回的ID更新_currentPage,并继续下一个循环,直到某个页面返回pages.EXIT,此时路由循环结束,应用程序退出。
使用示例
初始化与页面注册
在应用程序启动时,需要实例化 router_core,并注册所有可用的页面。
1public class App {
2 public static cn.oraclestar.sce.system.router.router_core router = new router_core();
3
4 public static void main(String[] args) throws Exception {
5 // ... 其他初始化代码 ...
6 register(); // 注册所有页面
7 router.setInitialPage(cn.oraclestar.sce.system.router.pages.WELCOME); // 设置起始页面
8 router.start(); // 启动路由
9 }
10
11 private static void register(){
12 try{
13 // ... 添加其他设置 ...
14
15 // 注册页面
16 cn.oraclestar.sce.system.router.router_core.addPage(cn.oraclestar.sce.system.router.pages.ABOUT,new cn.oraclestar.sce.system.pages.about());
17 cn.oraclestar.sce.system.router.router_core.addPage(cn.oraclestar.sce.system.router.pages.MAIN,new cn.oraclestar.sce.system.pages.main());
18 // ... 注册更多页面 ...
19 } catch(Exception e){
20 e.printStackTrace();
21 }
22 }
23}Source: src/cn/oraclestar/sce/App/App.java, src/cn/oraclestar/sce/App/App.java, src/cn/oraclestar/sce/App/App.java
创建具体页面
每个具体页面都需要继承 router_core,并重写 buildPage() 和 handlePageInput() 方法。
1public class about extends cn.oraclestar.sce.system.router.router_core {
2 @Override
3 protected void buildPage()
4 {
5 _ui.insertTitle("(主界面) 关于");
6 _ui.insertHint("V1.0B1", cn.oraclestar.sce.system.UI.Color.GREEN);
7
8 _ui.insertNewLine();
9 _ui.insertOption("软件介绍", (int)1);
10 _ui.insertOption("更新日志", (int)2);
11 // ... 更多选项 ...
12
13 _ui.insertNewLine();
14 _ui.insertOption("返回", (int)0);
15
16 _ui.insertNewLine();
17 _ui.insertInput(); // 提示用户输入
18 }
19
20 @Override
21 protected int handlePageInput(String input)
22 {
23 if (input.equals("1"))
24 {
25 return cn.oraclestar.sce.system.router.pages.DESCRIPTION; // 导航到软件介绍页面
26 }
27 else if (input.equals("2"))
28 {
29 return cn.oraclestar.sce.system.router.pages.CHANGELOG; // 导航到更新日志页面
30 }
31 // ... 处理其他输入 ...
32 else if (input.equals("0"))
33 {
34 return cn.oraclestar.sce.system.router.pages.MAIN; // 返回主页面
35 }
36 else
37 {
38 return cn.oraclestar.sce.system.router.pages.CURRENT; // 停留在当前页面
39 }
40 }
41}配置选项
router_core 模块本身没有外部可配置的选项。页面的注册和初始页面的设置都在代码中完成。页面的行为和导航逻辑由每个具体页面的 buildPage() 和 handlePageInput() 方法决定。
API 参考
cn.oraclestar.sce.system.router.pageheader (抽象类)
所有页面的抽象基类。
run(): int
- 描述: 抽象方法,所有具体页面必须实现。这是页面的主要执行逻辑,负责构建页面UI并处理用户输入,最终返回下一个页面的ID。
- 返回:
int- 下一个页面的ID (pages.CURRENT表示停留在当前页,pages.EXIT表示退出应用,其他为特定页面ID)。 - 抛出:
Exception- 在页面执行过程中可能发生的异常。
close(): void
- 描述:
AutoCloseable接口的实现,用于资源清理,当前为空实现。
displayEditInfo(String editContent, int oldValue): String / displayEditInfo(String editContent, String oldValue): String
- 描述: 辅助方法,用于在控制台显示编辑信息(如当前值)并获取用户输入。
- 参数:
editContent(String): 要编辑内容的描述。oldValue(int/String): 当前值。
- 返回:
String- 用户的输入字符串。
toInt(String olaValue): int
- 描述: 辅助方法,尝试将用户输入转换为整数。
- 参数:
olaValue(String): 要转换的字符串。
- 返回:
int- 转换后的整数,如果无法转换则返回0。
cn.oraclestar.sce.system.router.PageManager (抽象类)
页面管理器的抽象基类。
static addPage(int id, pageheader page): void
- 描述: 静态方法,用于将页面ID与页面实例注册到路由系统中。
- 参数:
id(int): 页面的唯一ID,通常来自pages类。page(pageheader): 实现了pageheader接口的页面实例。
setInitialPage(int id): void
- 描述: 抽象方法,用于设置应用程序启动时显示的初始页面。
- 参数:
id(int): 初始页面的ID。
start(): void
- 描述: 抽象方法,用于启动路由的主循环,开始页面导航。
- 抛出:
Exception- 在路由启动过程中可能发生的异常。
cn.oraclestar.sce.system.router.router_core (具体类)
路由系统的核心实现,所有具体页面也直接继承此接口。
innermod(): void
- 描述: 静态方法,可能与模块加载器
modlist交互,将模块内容注入到当前页面。
run(): int
- 描述: 实现了
pageheader的run方法。此方法包含页面执行的模板逻辑:清屏、重置UI、调用buildPage()、保存设置、等待用户输入,然后调用handlePageInput()。它还会集成modloader_main进行额外的输入处理。 - 返回:
int- 下一个页面的ID。 - 抛出:
Exception- 执行过程中可能发生的异常。
setInitialPage(int id): void
- 描述: 实现了
PageManager的setInitialPage方法。设置路由的初始页面ID。如果指定ID不存在,则将当前页面设置为pages.EXIT。 - 参数:
id(int): 初始页面的ID。
start(): void
- 描述: 实现了
PageManager的start方法。启动路由主循环,不断获取当前页面实例并调用其run()方法,直到当前页面ID变为pages.EXIT。 - 抛出:
Exception- 启动过程中可能发生的异常。
protected void buildPage() throws Exception
- 描述: 在
PageManager中定义的空实现,通常由具体页面重写以定义页面的UI布局。
protected int handlePageInput(String input)
- 描述: 在
PageManager中定义的默认实现,通常由具体页面重写以处理用户输入并返回下一个页面的ID。
cn.oraclestar.sce.system.router.pages (静态类)
定义了应用程序中所有页面的整数ID常量。
EXIT:-1,表示退出应用程序。CURRENT:0,表示停留在当前页面。WELCOME:1,欢迎页。MAIN:2,主页。SETTING:3,设置页。- ... (其他页面ID常量)