You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

datamodel-items.asciidoc 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. ---
  2. title: Holding properties in Items
  3. order: 3
  4. layout: page
  5. ---
  6. [[datamodel.items]]
  7. = Holding properties in Items
  8. The [classname]#Item# interface provides access to a set of named properties.
  9. Each property is identified by a __property identifier__ (PID) and a reference
  10. to such a property can be queried from an [classname]#Item# with
  11. [methodname]#getItemProperty()# using the identifier.
  12. Examples on the use of items include rows in a [classname]#Table#, with the
  13. properties corresponding to table columns, nodes in a [classname]#Tree#, and the
  14. the data bound to a [classname]#Form#, with item's properties bound to
  15. individual form fields.
  16. Items are generally equivalent to objects in the object-oriented model, but with
  17. the exception that they are configurable and provide an event handling
  18. mechanism. The simplest way to utilize [classname]#Item# interface is to use
  19. existing implementations. Provided utility classes include a configurable
  20. property set ( [classname]#PropertysetItem#) and a bean-to-item adapter (
  21. [classname]#BeanItem#). Also, a [classname]#Form# implements the interface and
  22. can therefore be used directly as an item.
  23. In addition to being used indirectly by many user interface components, items
  24. provide the basic data model underlying the [classname]#Form# component. In
  25. simple cases, forms can even be generated automatically from items. The
  26. properties of the item correspond to the fields of the form.
  27. The [classname]#Item# interface defines inner interfaces for maintaining the
  28. item property set and listening changes made to it.
  29. [classname]#PropertySetChangeEvent# events can be emitted by a class
  30. implementing the [classname]#PropertySetChangeNotifier# interface. They can be
  31. received through the [classname]#PropertySetChangeListener# interface.
  32. ifdef::web[]
  33. [[datamodel.items.propertysetitem]]
  34. == The [classname]#PropertysetItem# Implementation
  35. The [classname]#PropertysetItem# is a generic implementation of the
  36. [classname]#Item# interface that allows storing properties. The properties are
  37. added with [methodname]#addItemProperty()#, which takes a name and the property
  38. as parameters.
  39. The following example demonstrates a typical case of collecting
  40. [classname]#ObjectProperty# properties in an item:
  41. ----
  42. PropertysetItem item = new PropertysetItem();
  43. item.addItemProperty("name", new ObjectProperty("Zaphod"));
  44. item.addItemProperty("age", new ObjectProperty(42));
  45. // Bind it to a component
  46. Form form = new Form();
  47. form.setItemDataSource(item);
  48. ----
  49. endif::web[]
  50. [[datamodel.items.beanitem]]
  51. == Wrapping a Bean in a [classname]#BeanItem#
  52. The [classname]#BeanItem# implementation of the [classname]#Item# interface is a
  53. wrapper for Java Bean objects. In fact, only the setters and getters are
  54. required while serialization and other bean features are not, so you can wrap
  55. almost any POJOs with minimal requirements.
  56. ----
  57. // Here is a bean (or more exactly a POJO)
  58. public class Person {
  59. String name;
  60. int yearOfBirth;
  61. public Person(String name, int yearOfBirth) {
  62. this.name = name;
  63. this.yearOfBirth = yearOfBirth;
  64. }
  65. public String getName() {
  66. return name;
  67. }
  68. public void setName(String name) {
  69. this.name = name;
  70. }
  71. public int getYearOfBirth() {
  72. return yearOfBirth;
  73. }
  74. public void setYearOfBirth(int yearOfBirth) {
  75. this.yearOfBirth = yearOfBirth;
  76. }
  77. }
  78. // Create an instance of the bean
  79. Person bean = new Person();
  80. // Wrap it in a BeanItem
  81. BeanItem<Person> item = new BeanItem<Person>(bean);
  82. // Bind it to a component
  83. Form form = new Form();
  84. form.setItemDataSource(item);
  85. ----
  86. You can use the [methodname]#getBean()# method to get a reference to the
  87. underlying bean.
  88. [[datamodel.items.beanitem.nested]]
  89. === Nested Beans
  90. You may often have composite classes where one class "has a" another class. For
  91. example, consider the following [classname]#Planet# class which "has a"
  92. discoverer:
  93. ----
  94. // Here is a bean with two nested beans
  95. public class Planet implements Serializable {
  96. String name;
  97. Person discoverer;
  98. public Planet(String name, Person discoverer) {
  99. this.name = name;
  100. this.discoverer = discoverer;
  101. }
  102. ... getters and setters ...
  103. }
  104. ...
  105. // Create an instance of the bean
  106. Planet planet = new Planet("Uranus",
  107. new Person("William Herschel", 1738));
  108. ----
  109. When shown in a [classname]#Form#, for example, you would want to list the
  110. properties of the nested bean along the properties of the composite bean. You
  111. can do that by binding the properties of the nested bean individually with a
  112. [classname]#MethodProperty# or [classname]#NestedMethodProperty#. You should
  113. usually hide the nested bean from binding as a property by listing only the
  114. bound properties in the constructor.
  115. ----
  116. // Wrap it in a BeanItem and hide the nested bean property
  117. BeanItem<Planet> item = new BeanItem<Planet>(planet,
  118. new String[]{"name"});
  119. // Bind the nested properties.
  120. // Use NestedMethodProperty to bind using dot notation.
  121. item.addItemProperty("discoverername",
  122. new NestedMethodProperty(planet, "discoverer.name"));
  123. // The other way is to use regular MethodProperty.
  124. item.addItemProperty("discovererborn",
  125. new MethodProperty<Person>(planet.getDiscoverer(),
  126. "yearOfBirth"));
  127. ----
  128. The difference is that [classname]#NestedMethodProperty# does not access the
  129. nested bean immediately but only when accessing the property values, while when
  130. using [classname]#MethodProperty# the nested bean is accessed when creating the
  131. method property. The difference is only significant if the nested bean can be
  132. null or be changed later.
  133. You can use such a bean item for example in a [classname]#Form# as follows:
  134. ----
  135. // Bind it to a component
  136. Form form = new Form();
  137. form.setItemDataSource(item);
  138. // Nicer captions
  139. form.getField("discoverername").setCaption("Discoverer");
  140. form.getField("discovererborn").setCaption("Born");
  141. ----
  142. [[figure.datamodel.items.beanitem.nested]]
  143. .A [classname]#Form# with Nested Bean Properties
  144. image::img/beanitem-nested-beans.png[]
  145. The [classname]#BeanContainer# and [classname]#BeanItemContainer# allow easy
  146. definition of nested bean properties with
  147. [methodname]#addNestedContainerProperty()#, as described in
  148. <<dummy/../../../framework/datamodel/datamodel-container#datamodel.container.beancontainer.nestedproperties,"Nested
  149. Properties">>.