3.5.2.1.47. 文本控件

在线示例

API 文档

TextField 是用于文本编辑的控件。它可以用于处理实体属性,也可用于输入/显示任何文本信息。

该组件对应的 XML 名称:textField

  • 从本地消息包中获取标题(caption)的文本控件示例:

    1. <textField id="nameField" caption="msg://name"/>

    下图展示了一个简单文本控件示例:

    gui textField data

  • Web Client 使用 Halo-based 主题时,在 XML 描述或者界面控制器中可以使用 stylename 属性给文本框组件设置预定义的样式 :

    1. <textField id="textField"
    2. stylename="borderless"/>

    如果使用编程的方式设置样式,可以选择一个前缀为 TEXTFIELD_HaloTheme class 常量。

    1. textField.setStyleName(HaloTheme.TEXTFIELD_INLINE_ICON);

    TextField 样式:

    • align-center - 使文本在文本框中居中显示。
  1. - `align-right` - 使文本在文本框中居右显示。
  2. - `borderless` - 移除文本框的边框和背景。
  3. - `inline-icon` - 使标题图标显示在文本框里面。
  4. 文本框支持自动大小写转换。 `caseConvertion` 属性包含下列取值:
  5. - `UPPER` - 转换为大写,
  6. - `LOWER` - 转换为小写,
  7. - `NONE` - 不转换(默认值)。用这个选项来支持在输入法连续输入(比如,在输入中文、日文、韩文的时候)
  • 要创建连接数据的文本框,使用数据容器property 属性。

    1. <data>
    2. <instance id="customerDc" class="com.company.sales.entity.Customer" view="_local">
    3. <loader/>
    4. </instance>
    5. </data>
    6. <layout>
    7. <textField dataContainer="customerDc" property="name" caption="msg://name"/>
    8. </layout>

    如上所示,界面描述中为实体 Customer 定义了数据容器 customerDc ,并且 Customer 实体有一个 name 属性。文本控件通过 dataContainer 属性连接到数据容器;property 属性设置为要显示在控件中的实体属性的名称。

  • 如果文本控件没有连接到任何实体属性 (即,未设置数据容器和属性名称),可以使用 datatype 属性设置数据类型,数据类型用来格式化控件值。datatype 属性值可以是应用程序元数据中注册的任何数据类型 – 见 数据类型接口。通常,TextField 使用下面的数据类型:

    • decimal

    • double

    • int

    • long

  1. 如果该字段有 `datatype` 属性,并且用户输入了一个错误的值,则会显示默认的转换错误消息。
  2. 下面是一个数据类型是 `Integer` 的文本控件示例。
  3. ```
  4. <textField id="integerField" datatype="int" caption="msg://integerFieldName"/>
  5. ```
  6. 如果用户输入的字符不能解析为整数,当该控件失去焦点时,应用程序将显示错误消息。
  7. ![gui datatype default message](/projects/cuba-7.2-zh/829971b8a0a83b155332e6ea8909a31d.png)
  8. 默认的消息是在[主语言包]($11fb4862914e4969.md)中定义的,有这样的模板:`databinding.conversion.error.<type>`,比如:
  9. ```
  10. databinding.conversion.error.int = Must be Integer
  11. ```
  • 可以在界面 XML 描述中声明式的定义自己的类型转换错误消息,使用 conversionErrorMessage 属性:

    1. <textField conversionErrorMessage="This field can work only with Integers" datatype="int"/>

    或者在界面控制器中通过便层的方式创建:

    1. textField.setConversionErrorMessage("This field can work only with Integers");
  • 可以为文本控件分配一个验证器 - 实现了 Field.Validator 接口的类。在 datatype 对输入的字符格式进行验证后,验证器进行进一步的验证。例如,要创建一个正整数输入控件,需要创建一个验证器类:

    1. public class PositiveIntegerValidator implements Field.Validator {
    2. @Override
    3. public void validate(Object value) throws ValidationException {
    4. Integer i = (Integer) value;
    5. if (i <= 0)
    6. throw new ValidationException("Value must be positive");
    7. }
    8. }

    同时设置它为数据类型是 int 的文本控件的验证器:

    1. <textField id="integerField" datatype="int">
    2. <validator class="com.sample.sales.gui.PositiveIntegerValidator"/>
    3. </textField>

    与数据类型的输入时检查不同,验证不是在控件失去焦点时执行,而是在调用控件的 validate() 方法之后执行。这意味着控件(和连接的实体属性)可能暂时包含不满足验证条件的值(上例中的非正数)。这应该不是问题,因为要验证的控件通常用在编辑界面中,它会在提交之前自动调用所有控件的验证。如果该控件不在编辑界面中,则应在控制器中显式调用该控件的 validate() 方法。

  • TextField 支持其实现的 TextInputField 接口中定义的 TextChangeListener。为了不阻塞用户输入,文本变化事件的处理是异步进行的。

    1. textField.addTextChangeListener(event -> {
    2. int length = event.getText().length();
    3. textFieldLabel.setValue(length + " of " + textField.getMaxLength());
    4. });
    5. textField.setTextChangeEventMode(TextInputField.TextChangeEventMode.LAZY);

    gui textfield 2

  • The TextChangeEventMode 定义文本的变化被发送到服务器并触发服务端事件的方式。有 3 种预定义的事件模式:

    • LAZY (默认) - 文件输入暂停时触发事件。暂停时间可以通过 setInputEventTimeout() 修改。即使用户在输入文本时没有发生暂停,也会在可能发生的 ValueChangeEvent 之前强制触发文本更改事件。

    • TIMEOUT - 超时后触发事件。如果在超时周期内进行了多次更改,则将周期内自最后一次更改后发生的更改发送到服务端。可以使用 setInputEventTimeout() 设置超时时长。

      如果在超时期限之前发生 ValueChangeEvent,则在它之前触发 TextChangeEvent,条件是文本内容自上一个 TextChangeEvent 以来已经发生改变。

    • EAGER - 对于文本内容的每次更改,都会立即触发 TextChangeEvent 事件,通常是由按键触发。请求是独立且一个接一个地顺序处理。文本变化事件以异步方式与服务器交互,因此可以在处理事件请求的同时继续输入。

  • EnterPressListener 允许定义一个在 Enter 键按下时被执行的操作

    1. textField.addEnterPressListener(enterPressEvent ->
    2. notifications.create()
    3. .withCaption("Enter pressed")
    4. .show());
  • ValueChangeListener 当用户完成文本输入时,即在按下 Enter 键或组件失去焦点时,将触发 ValueChangeListenerValueChangeEvent 类型的事件对象被传递给监听器,它有以下方法:

    • getPrevValue() 返回组件之前的值。

    • getValue() 返回组件的当前值。

      1. textField.addValueChangeListener(stringValueChangeEvent ->
      2. notifications.create()
      3. .withCaption("Before: " + stringValueChangeEvent.getPrevValue() +
      4. ". After: " + stringValueChangeEvent.getValue())
      5. .show());

      可以使用 isUserOriginated() 方法跟踪 ValueChangeEvent 的来源。

  • 如果文本控件连接到实体属性(通过 datasourceproperty),并且实体属性具有定义在 @Column JPA 注解中的 length 参数,那么 TextField 将相应地限制输入文本的最大长度。

    如果文本控件未链接到属性,或者属性未定义 length 值,或者需要覆盖此值,则可以使用 maxLength 属性限制输入文本的最大长度。值 “-1” 表示没有限制。 例如:

    1. <textField id="shortTextField" maxLength="10"/>
  • 默认情况下,文本控件截去字符串的前后空格。即,如果用户输入 “ aaa bbb “,则 getValue() 方法返回并保存到连接实体属性的控件值将为 “aaa bbb”。可以通过将 trim 属性设置为 false 来禁用空格去除。

    应该注意的是,去除空格仅在用户输入新值时起作用。如果连接属性的值中已包含空格,则将显示空格,直到用户编辑该值。

  • 文本控件始终返回 null 而不是输入的空字符串。因此,启用 trim 属性后,任何只包含空格的字符串都将转换为 null

  • setCursorPosition() 方法可使控件获得焦点并将光标位置设置为指定索引,索引基于 0。


textField 的属性

align - caption - captionAsHtml - caseConversion - contextHelpText - contextHelpTextHtmlEnabled - conversionErrorMessage - css - dataContainer - datasource - datatype - description - descriptionAsHtml - editable - enable - box.expandRatio - height - icon - id - inputPrompt - maxLength - property - required - requiredMessage - stylename - tabIndex - trim - visible - width

textField 的元素

validator

textField 的预定义样式

align-center - align-right - borderless - huge - inline-icon - large - small - tiny

API

addEnterPressListener - addTextChangeListener - addValueChangeListener - commit - discard - isModified - setContextHelpIconClickHandler