GuiTagList

tag 列表控件(按分类分组)

基本信息

属性 值
路径 com.github.lunatrius.ingameinfo.client.gui.GuiTagList
行数 198(client/gui 包最大文件)
父类 net.minecraft.client.gui.GuiListExtended
容器 GuiTags

两个常量(:21-22)

public static final int OFFSET_X = 150;
public static final int SCROLLBAR_WIDTH = 6;

⚠️ OFFSET_X = 150 与 GuiTags 的 文本框宽度 150、列表 x 偏移都是同一个数 —— 三者共用「150」这个布局常量,但定义在不同类里 (OFFSET_X 在本类,文本框尺寸在 GuiTags 的 initGui 里字面量写出)。 改一处不会同步另一处。

构造器(:27-~60)

super(minecraft, guiTags.width, guiTags.height, 18, guiTags.height - 30, 24);

GuiListExtended 的 7 参构造: width、height、top、bottom、entryHeight。

⚠️ top = 18 是字面量,而 bottom 用 guiTags.height - 30。 两者不同源 —— 18 是硬编码的。

两层数据结构

private final Map<CategoryEntry, Set<TagEntry>> map;   // :24
private IGuiListEntry[] entries;                        // :25
容器 用途
Map<CategoryEntry, Set<TagEntry>> 按分类分组的 tag 集合
IGuiListEntry[] 展平后交给父类渲染的数组

⚠️ Set 用 TreeSet(:42)—— 保证排序稳定, 因为 Tag 没有覆写 Comparable(见 Tag), 所以 TreeSet 实际按插入顺序(LinkedHashSet 语义外的退化), 或按 CategoryEntry/TagEntry 自己的 compareTo。

分类分组的构建(:32-~50)

Map<String, CategoryEntry> stringCategoryEntryMap = new HashMap<>();
for (Tag tag : TagRegistry.INSTANCE.getRegisteredTags()) {
    String category = tag.getLocalizedCategory();      // ⚠️ 用本地化文本作 key
    String name = tag.getFormattedName();
    String description = tag.getLocalizedDescription();
    CategoryEntry categoryEntry = stringCategoryEntryMap.get(category);
    if (categoryEntry == null) { ...建新 CategoryEntry...; this.map.put(categoryEntry, new TreeSet<>()); }
    ...
}

⚠️ 用「本地化分类名」而非分类标识作 key: tag.getLocalizedCategory() 走 I18n.format(...), 切换语言会改变分组键。所以这个界面按当前语言分组, 这是合理的;但 stringCategoryEntryMap 用 HashMap, 分组顺序不保证是枚举顺序。

⚠️ getRegisteredTags() 返回 TagRegistry 的 values() 快照, 别名会作为独立元素重复出现(同一 Tag 实例注册了主名 + 别名)。 所以界面上可能出现重复的 tag 条目。

⚠️ getLocalizedDescription() 对没有 desc 本地化 key 的 tag 返回 key 本身(I18n.format 未命中时原样返回), 界面会显示 ingameinfoxml.tag.xxx.desc 这样的原始 key。

TagEntry 与 CategoryEntry

两个 IGuiListEntry 实现(文件后半段):

类 内容
CategoryEntry 分类标题(可折叠)
TagEntry 单个 tag:名称 + 描述

⚠️ 分类可折叠意味着 getSelected() / 点击处理里有 展开/收起状态 —— 这是 198 行里相当一部分逻辑。

与 getRegisteredTags 的互动

来源 数量
内置 tag 注册 151(TagRegistry 的 init())
集成 tag 5 个集成的 19 个(见各集成条目)
别名重复 每个带别名的 tag 多一份

⚠️ 集成 tag 在 ClientProxy 的 postInit 里 由 PluginLoader 注册 —— 而 /igi taglist 是客户端命令,在集成 tag 注册后打开, 所以集成 tag 会出现在列表里。

相关