组件渲染

您可以通过两种方式实现组件渲染:完全编程式或使用 ANTLR Stringtemplate。严格来说,有一个简单的 Function 渲染器接口,它接受 Context 作为输入并输出 AttributedString 列表。这让您可以在模板和代码之间进行选择。

如果您不需要进行任何复杂操作,或者只是想稍微修改现有组件布局,模板是一个不错的选择。而通过代码进行渲染则提供了您所需的灵活性。

编程式渲染的方式是创建一个 Function

class StringInputCustomRenderer implements Function<StringInputContext, List<AttributedString>> {
	@Override
	public List<AttributedString> apply(StringInputContext context) {
		AttributedStringBuilder builder = new AttributedStringBuilder();
		builder.append(context.getName());
		builder.append(" ");
		if (context.getResultValue() != null) {
			builder.append(context.getResultValue());
		}
		else  {
			String input = context.getInput();
			if (StringUtils.hasText(input)) {
				builder.append(input);
			}
			else {
				builder.append("[Default " + context.getDefaultValue() + "]");
			}
		}
		return Arrays.asList(builder.toAttributedString());
	}
}

然后您可以将其连接到组件

@ShellMethod(key = "component stringcustom", value = "String input", group = "Components")
public String stringInputCustom(boolean mask) {
	StringInput component = new StringInput(getTerminal(), "Enter value", "myvalue",
			new StringInputCustomRenderer());
	component.setResourceLoader(getResourceLoader());
	component.setTemplateExecutor(getTemplateExecutor());
	if (mask) {
		component.setMaskCharacter('*');
	}
	StringInputContext context = component.run(StringInputContext.empty());
	return "Got value " + context.getResultValue();
}

组件拥有自己的上下文,但通常会共享一些来自父组件类型的功能。下表显示了这些上下文变量

表 1. TextComponentContext 模板变量
描述

resultValue

组件渲染结果后的值。

name

组件的名称——即其标题。

message

为组件设置的可能消息。

messageLevel

消息的级别——INFOWARNERROR 中的一个。

hasMessageLevelInfo

如果级别是 INFO,返回 true。否则返回 false。

hasMessageLevelWarn

如果级别是 WARN,返回 true。否则返回 false。

hasMessageLevelError

如果级别是 ERROR,返回 true。否则返回 false。

input

原始用户输入。

表 2. SelectorComponentContext 模板变量
描述

name

组件的名称——即其标题。

input

原始用户输入——主要用于过滤。

itemStates

项目状态的完整列表。

itemStateView

可见的项目状态列表。

isResult

如果上下文处于结果模式,返回 true

cursorRow

选择器中当前的游标行。

表 3. ComponentContext 模板变量
描述

terminalWidth

终端的宽度,类型为 Integer,如果未设置,默认为 NULL