Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

components-fields.asciidoc 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. ---
  2. title: Field Components
  3. order: 4
  4. layout: page
  5. ---
  6. [[components.fields]]
  7. = Field Components
  8. ((("[classname]#Field#", id="term.components.fields", range="startofrange")))
  9. _Fields_ are components that have a value that the user can change through the
  10. user interface. <<figure.components.fields>> illustrates the inheritance relationships
  11. and the important interfaces and base classes.
  12. [[figure.components.fields]]
  13. .Field Components
  14. image::img/field-class-hierarchy.png[width=100%, scaledwidth=100%]
  15. Field components are built upon the framework defined in the [classname]#HasValue#
  16. interface.
  17. [classname]#AbstractField# is the base class for all field components,
  18. except those components that allow the user to select a value.
  19. (see <<components-selection.asciidoc#components.selection,"Selection Components">>).
  20. In addition to the component features inherited from
  21. [classname]#AbstractComponent#, it implements the features defined in the
  22. [interfacename]#HasValue# and [classname]#Component.Focusable# interfaces.
  23. [[figure.components.fields.hasvalue]]
  24. .Field components having values
  25. image::img/field-interface-v8-hi.png[width=60%, scaledwidth=100%]
  26. The description of the [interfacename]#HasValue# interface and field components extending [classname]#AbstractField] is broken down in the following sections.
  27. [[components.fields.field]]
  28. == The [interfacename]#HasValue# Interface
  29. The [interfacename]#HasValue# interface marks a component that has a user editable value.
  30. The type parameter in the interface is the type of the value that the component is editing.
  31. You can set the value with the [methodname]#setValue()# and read it with the
  32. [methodname]#getValue()# method defined in the [classname]#HasValue# interface.
  33. The [classname]#HasValue# interface defines a number of properties, which you can
  34. access with the corresponding setters and getters.
  35. [methodname]#readOnly#:: Set the component to be read-only, meaning that the value is not editable.
  36. [methodname]#requiredIndicatorVisible#:: When enabled, a required indicator
  37. (the asterisk * character) is displayed on the left, above, or right the field,
  38. depending on the containing layout and whether the field has a caption.
  39. When the component is used in a form (see <<../datamodel/datamodel-forms.asciidoc#datamodel.forms.validation,"Validation">>),
  40. it can be set to be required, which will automatically show the required indicator,
  41. and validate that the value is not empty. Without validation, the required indicator
  42. is merely a visual guide.
  43. [methodname]#emptyValue#:: The initial empty value of the component.
  44. [methodname]#clear#:: Clears the value to the empty value.
  45. [[components.fields.valuechanges]]
  46. == Handling Value Changes
  47. [interfacename]#HasValue# provides [methodname]#addValueChangeListener# method for listening to changes to the field value. This method returns a [classname]#Registration# object that can be used to later
  48. remove the added listener if necessary.
  49. [source, java]
  50. ----
  51. TextField textField = new TextField();
  52. Label echo = new Label();
  53. textField.addValueChangeListener(event -> {
  54. String origin = event.isUserOriginated()
  55. ? "user"
  56. : "application";
  57. String message = origin
  58. + " entered the following: "
  59. + event.getValue();
  60. Notification.show(message);
  61. });
  62. ----
  63. [[components.fields.databinding]]
  64. == Binding Fields to Data
  65. Fields can be grouped into _forms_ and coupled with business data objects with
  66. the [classname]#Binder# class. When a field is bound to a property using
  67. [classname]#Binder#, it gets its default value from the property, and
  68. is stored to the property either manually via the [methodname]#Binder.save# method,
  69. or automatically every time the value changes.
  70. [source, java]
  71. ----
  72. class Person {
  73. private String name;
  74. public String getName() { /* ... */ }
  75. public void setName(String) { /* ... */ }
  76. }
  77. TextField nameField = new TextField();
  78. Binder<Person> binder = new Binder<>();
  79. // Bind nameField to the Person.name property
  80. // by specifying its getter and setter
  81. binder.bind(nameField, Person::getName, Person::setName);
  82. // Bind an actual concrete Person instance.
  83. // After this, whenever the user changes the value
  84. // of nameField, p.setName is automatically called.
  85. Person p = new Person();
  86. binder.setBean(p);
  87. ----
  88. For more information on data binding, see <<../datamodel/datamodel-forms.asciidoc#datamodel.forms,"Binding Data to Forms">>
  89. == Validating Field Values
  90. User input may be syntactically or semantically invalid.
  91. [classname]#Binder# allows adding a chain of one or more __validators__ for
  92. automatically checking the validity of the input before storing it to the data
  93. object. You can add validators to fields by calling the [methodname]#withValidator#
  94. method on the [interfacename]#Binding# object returned by [methodname]#Binder.forField#.
  95. There are several built-in validators in the Framework, such as the [classname]#StringLengthValidator# used below.
  96. [source, java]
  97. ----
  98. binder.forField(nameField)
  99. .withValidator(new StringLengthValidator(
  100. "Name must be between 2 and 20 characters long",
  101. 2, 20))
  102. .bind(Person::getName, Person::setName);
  103. ----
  104. Failed validation is by default indicated with the error indicator of the field, described in
  105. <<../application/application-errors#application.errors.error-indicator,"Error
  106. Indicator and Message">>. Hovering mouse on the field displays the error message
  107. returned by the validator. If any value in a set of bound fields fails validation,
  108. none of the field values are saved into the bound property until the validation
  109. passes.
  110. === Implementing Custom Validators
  111. Validators implement the [interfacename]#Validator# interface that simply
  112. extends [interfacename]#java.util.function.Function#, returning a special type
  113. called [interfacename]#Result#. This return type represents the validation outcome:
  114. whether or not the given input was valid.
  115. [source, java]
  116. ----
  117. class MyValidator implements Validator<String> {
  118. @Override
  119. public ValidationResult apply(String value, ValueContext context) {
  120. if(value.length() == 6) {
  121. return ValidationResult.ok();
  122. } else {
  123. return ValidationResult.error(
  124. "Must be exactly six characters long");
  125. }
  126. }
  127. }
  128. ----
  129. Since [interfacename]#Validator# is a functional
  130. interface, you can often simply write a lambda expression instead of a full class
  131. declaration. There is also an [methodname]#withValidator# overload that creates a
  132. validator from a boolean function and an error message. If the application requires
  133. more sophisticated validation diagnostics (e.g. locale-specific), there is a
  134. method [methodname]#withValidator#, which uses a boolean function and an [classname]#ErrorMessageProvider#.
  135. The [classname]#ErrorMessageProvider# can compose diagnostic messages based on the locale of the validation
  136. and the source component value, which are provided with the [classname]#ValueContext#.
  137. [source, java]
  138. ----
  139. binder.forField(nameField)
  140. .withValidator(name -> name.length() < 20,
  141. "Name must be less than 20 characters long")
  142. .bind(Person::getName, Person::setName);
  143. ----
  144. == Converting Field Values
  145. Field values are always of some particular type. For example,
  146. [classname]#TextField# allows editing [classname]#String# values. When bound to
  147. a data source, the type of the source property can be something different,
  148. say an [classname]#Integer#. __Converters__ are used for converting the values
  149. between the presentation and the model. Their usage is described in
  150. <<../datamodel/datamodel-forms.asciidoc#datamodel.forms.conversion,"Conversion">>.
  151. (((range="endofrange", startref="term.components.fields")))