← 返回索引

范围:源码目录定位与类继承关系。

前置:无。

项目定位

FluentUI 是一个客户端 Fabric Minecraft 模组,提供了一套完整的 UI 框架,用于构建丰富的 Minecraft GUI 界面。它不是一个独立的库,而是扩展了 Minecraft 的 Screen 类并依赖 Fabric API,因此所有公开入口都位于模组初始化与具体 Screen 子类上。

框架有五个核心特性:

  • 自渲染:所有 UI 元素通过 GuiGraphicsExtractor 自行绘制,绕过 Minecraft 原生的 widget 系统,因此每个 Element 自行绘制自身的像素。
  • 单一事件入口:所有鼠标、键盘、焦点与覆盖层路由都经过 InteractionManager,Screen 只做转发。
  • 惰性布局:元素仅在 dirty 标志被置位时才重新测量与排列,机制详见 布局系统。
  • 覆盖层树:工具提示、上下文菜单、对话框等浮动元素组织为一棵多根森林,推送与渲染语义见 覆盖层系统。
  • 链式 API:每个 setter 通过自界定泛型返回具体的子类型,支持流畅的构建器写法;泛型取舍的背景记录在 设计决策。

源码结构

目录树标注每个子系统的位置与关键文件的行数;行数取自当前源码,改动后需同步更新。

FluentUI/
├── build.gradle              # Fabric Loom,使用分离的源集
├── gradle.properties         # MC 26.2, Java 25, mod_version 26.7.0
├── src/
│   ├── main/java/xianfish/fluentui/
│   │   └── FluentUI.java                 # 公共入口 (ModInitializer)
│   └── client/java/xianfish/fluentui/client/
│       ├── FluentScreen.java             # 抽象基类 Screen
│       ├── FluentUIClient.java           # 客户端入口 (ClientModInitializer)
│       └── ui/
│           ├── element/
│           │   ├── Element.java          # 根基类 (186 行)
│           │   ├── LayoutElement.java    # 容器基类 (62 行)
│           │   ├── TooltippingElement.java
│           │   ├── FocusableElement.java
│           │   ├── Focusable.java
│           │   ├── KeyboardReceiver.java
│           │   ├── Margin.java
│           │   └── layout/
│           │       ├── StackPanel.java   # 线性堆叠 (225 行)
│           │       ├── Canvas.java       # 自由定位 (68 行)
│           │       ├── EntryRow.java     # 标签+控件行 (41 行)
│           │       ├── Orientation.java
│           │       ├── StackDirection.java
│           │       ├── OverflowMode.java
│           │       └── Anchor.java
│           ├── interaction/
│           │   ├── InteractionManager.java  # 中央事件路由器
│           │   └── Hit.java                 # 静态碰撞检测 (73 行)
│           ├── overlay/
│           │   ├── OverlayManager.java      # 覆盖层树的持有方 (42 行)
│           │   └── OverlayTree.java         # 多根森林 (136 行)
│           ├── component/                   # 15 个具体组件(清单见下)
│           ├── animation/
│           │   ├── Animator.java
│           │   └── Easing.java
│           └── util/
│               ├── Colors.java
│               └── UIRenderUtil.java

ui/component/ 下共有 15 个组件类,是贡献者最常改动的叶子类:Button、Toggle、SelectBox、Slider、Stepper、TextBox、AutoCompleteBox、SelectDropdown、ListView、ItemList、ItemView、Tooltip、ContextMenu、MessageFlyout、ProgressBar。

类层次结构

元素体系由 Element 分出三条支线:布局容器、可悬浮元素、可聚焦元素。全模块的继承关系以下图为准:元素系统 展开元素侧的细节,但与此图一致。

Element<T>                              # 根基类
├── LayoutElement<T>                    # 添加子元素 + 滚动
│   ├── StackPanel                      # 线性布局 (H/V)
│   ├── Canvas                          # 自由定位 + 锚点
│   └── EntryRow                        # 左标签 + 右控件
├── TooltippingElement<T>               # 添加工具提示支持
│   ├── FocusableElement<T>             # 添加焦点 + 键盘输入(其本身也是组件基类)
│   │   ├── TextBox                     # 文本输入
│   │   ├── AutoCompleteBox             # 自动完成输入
│   │   └── Stepper                     # 数字步进器
│   ├── Toggle                          # 开关
│   ├── Slider                          # 滑条
│   ├── SelectBox                       # 选择框
│   ├── ListView                        # 列表视图
│   │   └── ItemList                    # 可编辑列表(继承自 ListView)
│   ├── ItemView                        # 项视图
│   └── SelectDropdown                  # 下拉选择(内部 DropPanel 才是覆盖层)
└── 直接继承 Element 的组件
    ├── Button                          # 按钮
    ├── Tooltip                         # 悬停工具提示
    ├── ProgressBar                     # 进度条
    ├── ContextMenu                     # 右键菜单
    └── MessageFlyout                   # Toast 通知

SelectDropdown 与 Tooltip 不属于 TooltippingElement 分支。 SelectDropdown 只是 TooltippingElement,真正带覆盖层语义的是其内部的 DropPanel 私有类;Tooltip 直接继承 Element,由其他元素依据 TooltippingElement 的悬浮逻辑推送。同理,AutoCompleteBox 内部的 DropdownOverlay 也是私有 Element 子类,而非顶层组件;内部面板类不进组件清单,也不进上图的分支。

不变量

  • 继承层次是对外契约:上图中每个类的父类位置决定了它能用的能力(悬浮、焦点、覆盖层生命周期、子元素布局),改动任何 extends 都等于改动能力集合,必须同步概述中的类层次图、ElementSystem 的复述以及涉及组件的文档。
  • 组件清单恒为 15 个:新增或删除 ui/component/ 下的顶层组件类时,源码结构中的清单必须同步;内部私有面板类(如 DropPanel、DropdownOverlay)永远不计入。
  • 行数表以源码为准:InteractionManager 465、Hit 73、OverlayManager 42、OverlayTree 136、Element 186、LayoutElement 62、StackPanel 225、Canvas 68、EntryRow 41;改动这些文件后应同步更新对应行数,避免文档与源码不一致。
  • 版本号以 gradle.properties 为准:当前 mod_version=26.7.0。

连带影响

  • 调整某个组件的父类(例如让 Tooltip 改为继承 TooltippingElement),会同时改变它的悬浮能力、覆盖层推送方式与命中分发路径,波及 元素系统 的字段说明和该组件的开发文档。
  • ui/element/layout/ 下新增一种容器时,需要在源码结构、类层次图、布局系统 的容器小节三处同步。
  • 修改 Element 的核心字段或 layout() 语义,会波及全部 15 个组件与三条渲染/输入流水线,见 元素系统 与 根树与层级系统。
  • 修改 InteractionManager 的路由规则(全仓最大的单文件),波及 交互引擎 与 覆盖层系统 的行为描述。

相关文档