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.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. class Person {
  59. String name;
  60. int age;
  61. public String getName() {
  62. return name;
  63. }
  64. public void setName(String name) {
  65. this.name = name;
  66. }
  67. public Integer getAge() {
  68. return age;
  69. }
  70. public void setAge(Integer age) {
  71. this.age = age.intValue();
  72. }
  73. }
  74. // Create an instance of the bean
  75. Person bean = new Person();
  76. // Wrap it in a BeanItem
  77. BeanItem<Person> item = new BeanItem<Person>(bean);
  78. // Bind it to a component
  79. Form form = new Form();
  80. form.setItemDataSource(item);
  81. ----
  82. You can use the [methodname]#getBean()# method to get a reference to the
  83. underlying bean.
  84. [[datamodel.items.beanitem.nested]]
  85. === Nested Beans
  86. You may often have composite classes where one class "has a" another class. For
  87. example, consider the following [classname]#Planet# class which "has a"
  88. discoverer:
  89. ----
  90. // Here is a bean with two nested beans
  91. public class Planet implements Serializable {
  92. String name;
  93. Person discoverer;
  94. public Planet(String name, Person discoverer) {
  95. this.name = name;
  96. this.discoverer = discoverer;
  97. }
  98. ... getters and setters ...
  99. }
  100. ...
  101. // Create an instance of the bean
  102. Planet planet = new Planet("Uranus",
  103. new Person("William Herschel", 1738));
  104. ----
  105. When shown in a [classname]#Form#, for example, you would want to list the
  106. properties of the nested bean along the properties of the composite bean. You
  107. can do that by binding the properties of the nested bean individually with a
  108. [classname]#MethodProperty# or [classname]#NestedMethodProperty#. You should
  109. usually hide the nested bean from binding as a property by listing only the
  110. bound properties in the constructor.
  111. ----
  112. // Wrap it in a BeanItem and hide the nested bean property
  113. BeanItem<Planet> item = new BeanItem<Planet>(planet,
  114. new String[]{"name"});
  115. // Bind the nested properties.
  116. // Use NestedMethodProperty to bind using dot notation.
  117. item.addItemProperty("discoverername",
  118. new NestedMethodProperty(planet, "discoverer.name"));
  119. // The other way is to use regular MethodProperty.
  120. item.addItemProperty("discovererborn",
  121. new MethodProperty<Person>(planet.getDiscoverer(),
  122. "born"));
  123. ----
  124. The difference is that [classname]#NestedMethodProperty# does not access the
  125. nested bean immediately but only when accessing the property values, while when
  126. using [classname]#MethodProperty# the nested bean is accessed when creating the
  127. method property. The difference is only significant if the nested bean can be
  128. null or be changed later.
  129. You can use such a bean item for example in a [classname]#Form# as follows:
  130. ----
  131. // Bind it to a component
  132. Form form = new Form();
  133. form.setItemDataSource(item);
  134. // Nicer captions
  135. form.getField("discoverername").setCaption("Discoverer");
  136. form.getField("discovererborn").setCaption("Born");
  137. ----
  138. [[figure.datamodel.items.beanitem.nested]]
  139. .A [classname]#Form# with Nested Bean Properties
  140. image::img/beanitem-nested-beans.png[]
  141. The [classname]#BeanContainer# and [classname]#BeanItemContainer# allow easy
  142. definition of nested bean properties with
  143. [methodname]#addNestedContainerProperty()#, as described in
  144. <<dummy/../../../framework/datamodel/datamodel-container#datamodel.container.beancontainer.nestedproperties,"Nested
  145. Properties">>.