Skip to content

文本组件 (Component)

前言

参见Wiki 文本组件格式 以及Wiki 文本组件教程 。 本文不会重复叙述以上内容,即默认已阅读以上内容,而是着重叙述代码实现等方面。

文本组件 (Component)是一个原生原味的 Minecraft 类,它的 KJS 包装类为ComponentKJS,但实际上却是被可变文本组件 (MutableComponet)继承。 尽管大部分情况下它们并无差别,但也不要将两者混淆。

注意:KJS 中的全局类Component实际上是TextWrapper,部分Component内原有的内容需要通过导入该类来实现。 本文中会用 $Component 标识。

表示

文本组件的内部维护着一个组件内容 (ComponentContents),这是文本组件实际存储的内容。 文本组件只作为一个包装。

本文所述的表示实际上是组件内容。

纯文本 (LiteralContents)

纯文本只是单纯的文本,不包含各种变量和参数。

js
// 字符串形式常用作参数等
"对,就是纯粹的字符串。";
js
Component.literal("这是一个文本组件"); // 注意:传参为null时会报错
$Component.nullToEmpty("这是一个文本组件"); // 等同于上一行,但当传参为null时会返回空文本

翻译文本 (TranslatableContents)

该组件内容是可以加入参数的。依赖于客户端的语言文件 。 在不同的语言下会呈现出不一样的结果。

本文会给出语言文件的内容和示例代码以供更好的理解。

Tips:翻译键一般以该规则命名category.modid.id

js
// 在英语(en_us)下显示为:“This is a text without any args”
// 在中文(zh_cn)下显示为:“这是一个不带参数的文本”
// 以下几行以此类推
Component.translatable("key.example.example_text1");

// 用以下的方式将语言文件中的“%s”替换为“100%”,甚至是你想要的其他内容
// 参数可以有多个
Component.translatable("key.example.example_text2", "100%");

// 该方法会在找不到翻译键的情况下用fallback(即第二个参数)代替所呈现的内容
// 在英语下效果等同于第一行,显示为:“Test Text 0”
// 但由于在中文下没有该翻译键,所以显示为:“找不到该文本”
$Component.translatableWithFallback(
  "key.example.example_text3",
  "找不到该文本"
);

// 同样的,它也可以附带参数。第二个参数为fallback,往后为参数
$Component.translatableWithFallback(
  "key.example.example_text3",
  "找不到该文本",
  "Zero"
);
json
{
  "key.example.example_text1": "这是一个不带参数的文本",
  "key.example.example_text2": "进度条:%s"
}
json
{
  "key.example.example_text1": "This is a text without any args",
  "key.example.example_text2": "Progress: %s",
  "key.example.example_text3": "Test Text 0",
  "key.example.example_text4": "Test Text %s"
}

记分板分数 (ScoreContents)

该组件内容依赖于记分板

js
// 传入一个分数持有者和记分项
Component.score("@s", "test"); // 显示在test记分项下自身的分数

实体名称 (SelectorContents)

该组件内容为目标选择器 找到的实体名称。

js
// 传入一个目标选择器(组件中的selector)和分隔符(组件中的separator)
$Component.selector("@s", $Optional.empty()); // 显示自身的名称

按键绑定 (KeybindContents)

该组件内容依赖于客户端的键位

js
// 传入一个绑定键位标识符(组件中的keybind)
Component.keybind("key.inventory"); // 在默认设置下显示为“E”

NBT 标签值 (NbtContents)

该组件内容依赖于NBT 标签 。 较复杂且不常用,本文只给出大致用法。

js
/*
 * 第一个参数为NBT标签下的路径(即组件中的nbt)
 * 第二个参数为是否解析为文本(即组件中的interpret)
 * 第三个参数为文本组件间的分隔符(即组件中的separator)
 * 第四个参数为NBT的来源(即组件中的source)
 * 该行代码会显示自身的NBT标签
 */
$Component.nbt("", false, $Optional.empty(), new $EntityDataSource("@s"));

样式 (Style)

用于修饰文本组件,比如颜色、点击事件、悬浮事件等。

js
Component.literal("这是一个文本组件").color(0x9400d3); // 颜色为0x9400D3的“这是一个文本组件”
Component.literal("这是一个文本组件").noColor(); // 将一个已有颜色的文本组件设为无色(默认色)

Component.blue("这是一个文本组件"); // 显示为蓝色的“这是一个文本组件”
Component.literal("这是一个文本组件").blue(); // 等同于上一行,将一个已有的文本组件设为蓝色
// 另外还有更多颜色都是类似的使用方式
js
Component.bold(true); // 将一个已有的文本组件设为粗体
Component.bold(); // 等同于上一行
// 下面的方法以此类推
Component.italic(); // 斜体
Component.underlined(); // 下划线
Component.strikethrough(); // 删除线
Component.obfuscated(); // 随机字符

Component.font("RandomFont"); // 显示该文本组件的字体

Component.hasStyle(); // 判断该文本组件是否有样式
Component.isEmpty(); // 判断该文本组件是否为空

// 单独附加样式
let style = new $Style().withBold(true); // 附加粗体
$Component.withStyle(style);
js
Component.clickRunCommand("/tell @s Harry"); // 点击时执行该命令
Component.clickSuggestCommand("/tell @s Harry"); // 点击时将该命令加入聊天框中
Component.clickCopy("剪贴板"); // 点击时将改内容复制到剪贴板中
Component.clickChangePage("2"); // 点击时改变书的页数
Component.clickOpenUrl("https://docs.mihono.cn"); // 点击时打开一个URL
Component.clickOpenFile("file.txt"); // 点击时打开一个文件

Component.hover("其他东西"); // 将鼠标放到文本上时显示该内容

Component.insertion("其他东西"); // Shift点击时将该内容加入聊天框中

子组件 (Sibling)

子组件继承于父组件的样式,也可以独立覆盖父组件的样式。

js
// 显示为“这是一个文本组件,这是另一个文本组件。”
Component.literal("这是一个文本组件,").append(
  // 这个文本组件可以拥有自己的样式,而不影响上面组件的样式
  Component.literal("这是另一个文本组件。")
);

Component.hasSiblings(); // 该组件是否有子组件

贡献者

页面历史