UI渲染 (_ui)
此文档描述了 SCE-Universe_Java_Edition 项目中用于控制台界面的 UI 渲染系统。该系统提供了一套基于文本的 UI 组件,支持颜色高亮和结构化内容展示,以实现命令行应用程序的用户交互。
概述
_ui UI 渲染系统是一个轻量级的、自定义的控制台用户界面框架。它允许应用程序开发者以结构化的方式定义和显示文本内容,包括标题、正文、提示、列表、选项和用户输入字段。通过使用 ANSI 转义码,该系统能够在支持此功能的终端中渲染带颜色的文本,从而提升用户体验和信息的可读性。
该系统的核心在于将 UI 内容抽象为 Tiles 对象列表,并在渲染前对这些 Tiles 进行预处理,最终按顺序将它们打印到控制台。它专注于提供一种简单而有效的方式来构建和管理控制台应用程序的视觉输出和基本输入处理。
架构
UI 渲染系统主要由以下核心组件构成:
Source:
组件说明:
ui_header: 抽象基类,定义了 UI 渲染系统的核心接口和一些共享的静态状态(如article列表)。UI_core:ui_header的具体实现类,包含了创建、处理和渲染 UI 元素的所有业务逻辑。它是应用程序与 UI 渲染系统交互的主要入口。Tiles: UI 元素的基本单元,封装了元素的类型 (type)、文本内容 (textContent) 和颜色 (rgb)。所有要显示在控制台的内容都首先被转换为Tiles对象。type: 包含了用于标识Tiles对象类型的常量(如TEXT,TITLE,HINT等)。Color: 提供了一组预定义的rgb颜色常量,方便开发者使用标准颜色。fmt包: 包含rgb和fmt类,负责实际的控制台文本格式化和输出。rgb类将 RGB 值转换为 ANSI 转义码,fmt类则使用这些转义码打印带颜色的文本。控制台 (Console): UI 内容的最终输出目的地和用户输入来源。操作系统 (OS):UI_core通过调用cls()方法与操作系统交互,实现控制台清屏功能。
主要功能与实现
UI 渲染系统的核心功能围绕着 Tiles 列表的构建、预处理和最终渲染。
UI 元素构建
UI_core 提供了多种 insert 方法,用于向内部维护的 List<Tiles> article 中添加不同类型的 UI 元素。article 是一个静态列表,存储了所有待渲染的 UI 元素。
1public class UI_core extends ui_header {
2 // ...
3 public void insertTitle(String textContent,rgb color){
4 ensureArticle();
5 article.add(new Tiles(type.TITLE,textContent,color));
6 if(isBuild)isBuild = false;
7 }
8 public void insertText(String textContent){
9 ensureArticle();
10 article.add(new Tiles(type.TEXT,textContent,Color.DEFAULT));
11 if(isBuild)isBuild = false;
12 }
13 public void insertHint(String textContent){
14 ensureArticle();
15 article.add(new Tiles(type.HINT,textContent,Color.GREEN));
16 if(isBuild)isBuild=false;
17 }
18 public void insertInput(boolean isPause){
19 ensureArticle();
20 if(!isPause){
21 article.add(new Tiles(type.INPUT,"# ",Color.YELLOW));
22 }
23 else {
24 article.add(new Tiles(type.INPUT,"按下回车继续...",Color.YELLOW));
25 }
26 if (isBuild)isBuild=false;
27 }
28 public void insertOption(String textContent,int index){
29 ensureArticle();
30 String fullOption = "[" + String.valueOf(index) + "]" + textContent;
31 article.add(new Tiles(type.OPTION,fullOption,Color.DEFAULT));
32 if(isBuild)isBuild= false;
33 }
34 // ...
35}Source: UI_core.java
UI 内容预处理 (build() 方法)
在内容被渲染到控制台之前,build() 方法会对 article 列表中的 Tiles 进行一次预处理。这个过程会根据 Tiles 的类型添加额外的格式化元素,例如为标题添加下划线、为列表项添加序号、为提示信息添加特殊符号等。
1public boolean build(){
2 int index =0;
3 ensureArticle();
4 if(!isBuild){
5 ListIterator<Tiles> it = article.listIterator();
6 if(buildLine !=0){
7 buildLine++;
8 }
9 // ... (跳过已构建的行)
10 while(it.hasNext()){
11 Tiles t =it.next();
12 try{
13 switch(t.type){
14 case type.TITLE:
15 it.add(new Tiles(type.NEWLINE,""));
16 Tiles prev = it.previous(); // 回到 NEWLINE 前的 TITLE
17 int len = prev.textContent.length();
18 it.next(); // 回到 NEWLINE 后
19 it.add(new Tiles(type.TEXT, "-".repeat(len))); // 插入标题下划线
20 it.add(new Tiles(type.NEWLINE,""));
21 buildLine +=3;
22 break;
23 case type.LIST:
24 // ... 插入列表前缀
25 break;
26 case type.HINT:
27 // ... 添加提示符号
28 break;
29 case type.TEXT:
30 case type.OPTION:
31 it.add(new Tiles(type.NEWLINE,"")); // 文本和选项后添加换行
32 buildLine +=2;
33 break;
34 // ... 其他类型处理
35 }
36 } catch(Exception e) {
37 System.out.println("UI.build :未知错误");
38 }
39 }
40 }
41 isBuild =true;
42 return true;
43}Source: UI_core.java
UI 内容渲染 (run() 方法)
run() 方法是实际执行 UI 渲染的核心。它首先确保 article 列表已经经过 build() 方法的预处理,然后遍历列表中的每个 Tiles 对象,并根据其类型和颜色将其打印到控制台。
1public boolean run() throws Exception
2{
3 ensureArticle();
4 if (isBuild)
5 {
6 return true;
7 }
8 if (!build())
9 {
10 throw(new Exception("ui::run :构建失败"));
11 }
12 for (var it : article)
13 {
14 switch (it.type)
15 {
16 case type.TITLE:
17 case type.TEXT:
18 case type.HINT:
19 case type.LIST:
20 case type.OPTION:
21 case type.INPUT:
22 case type.SPAN:
23 case type.OPTION_WITHOUT_NEWLINE:
24 post(it.textContent, it.color); // 调用 post 方法打印带颜色文本
25 break;
26 case type.NEWLINE:
27 System.out.println(); // 打印换行
28 break;
29 default:
30 throw(new Exception("ui.run :不存在的类型"));
31 }
32 }
33 return true;
34}
35
36protected void post(String textContent,rgb color)
37{
38 // print without newline; run() will handle newlines and NEWLINE tiles
39 fmt.print(fmt.fg(color), "{}", textContent);
40};Source: UI_core.java, UI_core.java
颜色和格式化 (fmt 包)
fmt 包负责将颜色信息转换为终端可识别的 ANSI 转义码,并进行实际的控制台输出。
rgb 类将 R、G、B 值转换为 \033[38;2;R;G;Bm 格式的 24 位真彩色 ANSI 序列。
fmt.print 方法接收这个颜色控制字符串和文本内容,打印到 System.out,并在文本结束后使用 \033[0m 重置终端颜色。
1// src/cn/oraclestar/sce/system/UI/fmt/rgb.java
2public class rgb {
3 public int R=0;
4 public int G=0;
5 public int B=0;
6 public rgb(int R,int G, int B){
7 this.R = R;
8 this.G = G;
9 this.B = B;
10 };
11 @Override
12 public String toString(){
13 return "\033[38;2;"+String.valueOf(R)+";"+String.valueOf(G)+";"+String.valueOf(B)+"m";
14 }
15}Source: rgb.java
1// src/cn/oraclestar/sce/system/UI/fmt/fmt.java
2public class fmt {
3 public static void print(String Controllor,String format,String text){
4 // use print (no automatic newline) to avoid duplicate blank lines;
5 // caller (post/display) decides when to print newline.
6 System.out.print(Controllor + text);
7 System.out.print("\033[0m"); // Reset color
8 };
9 // ...
10}Source: fmt.java
核心流程
以下序列图展示了 UI 渲染系统从内容插入到最终在控制台显示的完整生命周期。
Source:
使用示例
创建并渲染一个简单的页面
1// 假设这是应用程序中的某个页面逻辑
2package cn.oraclestar.sce.system.pages;
3
4import cn.oraclestar.sce.system.UI.UI_core;
5import cn.oraclestar.sce.system.UI.Color;
6
7public class main {
8 public void showWelcomePage() throws Exception {
9 UI_core ui = new UI_core(); // 或通过其他方式获取 UI_core 实例
10 ui.cls(); // 清屏
11
12 ui.insertTitle("欢迎来到 SCE-Universe", Color.YELLOW);
13 ui.insertNewLine();
14 ui.insertText("这是一个基于控制台的应用程序。", Color.DEFAULT);
15 ui.insertHint("请选择一个选项继续。", Color.GREEN);
16 ui.insertNewLine();
17 ui.insertOption("开始游戏", 1, Color.BLUE);
18 ui.insertOption("查看设置", 2, Color.DEFAULT);
19 ui.insertOption("退出", 3, Color.RED);
20 ui.insertNewLine();
21 ui.insertInput(false, Color.YELLOW); // 提示用户输入
22
23 ui.run(); // 渲染所有添加的 UI 元素
24
25 String input = ui.getUserInput();
26 System.out.println("您输入了: " + input); // 处理用户输入
27
28 ui.reset(); // 清空当前页面内容以便下一次渲染
29 }
30}Source: main.java (示例代码基于对该文件和 UI_core 的理解创建,部分代码结构参考了
UI_core的用法)
清屏功能
cls() 方法用于清除控制台屏幕,提供更清晰的 UI 体验。它会自动检测操作系统类型。
1public static void cls(){
2 try{
3 String os = System.getProperty("os.name").toLowerCase();
4 if(os.contains("win")){
5 new ProcessBuilder("cmd","/c","cls").inheritIO().start().waitFor();
6 } else {
7 new ProcessBuilder("clear").inheritIO().start().waitFor();
8 }
9 }catch (Exception e){
10 e.printStackTrace();
11 };
12};Source: ui_header.java
API 参考
UI_core 类
insertTitle(String textContent, rgb color)
插入一个标题文本。标题在渲染时会自动在其下方生成一条与标题等长的分隔线。 参数:
textContent(String): 标题的文本内容。color(rgb): 标题的颜色。
insertText(String textContent)
插入一段普通文本,使用默认颜色。 参数:
textContent(String): 文本内容。
insertHint(String textContent, rgb color)
插入一段提示信息。提示信息在渲染时会以特殊符号(如 ×, !, -, +)包裹。
参数:
textContent(String): 提示文本内容。color(rgb): 提示文本的颜色。特定颜色(红、黄、绿)会对应不同的提示符号。
insertInput(boolean isPause, rgb color)
插入一个用户输入提示或暂停提示。 参数:
isPause(boolean): 如果为true,则显示 "按下回车继续...",否则显示 "# " 作为输入提示。color(rgb): 提示文本的颜色。
insertOption(String textContent, int index, rgb color)
插入一个带编号的选项。 参数:
textContent(String): 选项的文本内容。index(int): 选项的编号,显示为[index]。color(rgb): 选项文本的颜色。
insertNewLine()
插入一个新行。
run()
处理并渲染所有已插入的 UI 元素到控制台。
返回: boolean - 如果成功渲染则为 true。
抛出: Exception - 如果构建或渲染过程中发生错误。
getUserInput()
从控制台读取用户的单行输入。
返回: String - 用户输入的文本。
erase(int line)
擦除 article 列表中指定行号的 UI 元素。
参数:
line(int): 要擦除的 UI 元素在列表中的索引。 抛出:Exception- 如果行号超出范围。
reset() (静态方法)
清除所有已插入的 UI 元素,重置内部状态,为新的页面渲染做准备。
cls() (静态方法)
清除控制台屏幕。
Tiles 类
Tiles 类是 UI 元素的内部表示,通常不直接由外部调用。
字段:
public int type: UI 元素的类型,对应type类中的常量。public String textContent: 元素的文本内容。public rgb color: 元素的颜色。
type 类
定义了 Tiles 元素的常量类型:TEXT, HINT, TITLE, LIST, NEWLINE, OPTION, INPUT, SPAN, OPTION_WITHOUT_NEWLINE。
Color 类
提供了预定义的 rgb 颜色常量,例如 Color.RED, Color.GREEN, Color.YELLOW, Color.DEFAULT 等。
rgb 类
表示一个 RGB 颜色值。 构造函数:
rgb(int R, int G, int B): 创建一个指定 R、G、B 值的颜色对象。 方法:toString(): 返回对应的 ANSI 24 位真彩色转义码字符串。