123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- ---
- title: Holding properties in Items
- order: 3
- layout: page
- ---
-
- [[datamodel.items]]
- = Holding properties in Items
-
- The [classname]#Item# interface provides access to a set of named properties.
- Each property is identified by a __property identifier__ (PID) and a reference
- to such a property can be queried from an [classname]#Item# with
- [methodname]#getItemProperty()# using the identifier.
-
- Examples on the use of items include rows in a [classname]#Table#, with the
- properties corresponding to table columns, nodes in a [classname]#Tree#, and the
- the data bound to a [classname]#Form#, with item's properties bound to
- individual form fields.
-
- Items are generally equivalent to objects in the object-oriented model, but with
- the exception that they are configurable and provide an event handling
- mechanism. The simplest way to utilize [classname]#Item# interface is to use
- existing implementations. Provided utility classes include a configurable
- property set ( [classname]#PropertysetItem#) and a bean-to-item adapter (
- [classname]#BeanItem#). Also, a [classname]#Form# implements the interface and
- can therefore be used directly as an item.
-
- In addition to being used indirectly by many user interface components, items
- provide the basic data model underlying the [classname]#Form# component. In
- simple cases, forms can even be generated automatically from items. The
- properties of the item correspond to the fields of the form.
-
- The [classname]#Item# interface defines inner interfaces for maintaining the
- item property set and listening changes made to it.
- [classname]#PropertySetChangeEvent# events can be emitted by a class
- implementing the [classname]#PropertySetChangeNotifier# interface. They can be
- received through the [classname]#PropertySetChangeListener# interface.
-
- ifdef::web[]
- [[datamodel.items.propertysetitem]]
- == The [classname]#PropertysetItem# Implementation
-
- The [classname]#PropertysetItem# is a generic implementation of the
- [classname]#Item# interface that allows storing properties. The properties are
- added with [methodname]#addItemProperty()#, which takes a name and the property
- as parameters.
-
- The following example demonstrates a typical case of collecting
- [classname]#ObjectProperty# properties in an item:
-
-
- ----
- PropertysetItem item = new PropertysetItem();
- item.addItemProperty("name", new ObjectProperty("Zaphod"));
- item.addItemProperty("age", new ObjectProperty(42));
-
- // Bind it to a component
- Form form = new Form();
- form.setItemDataSource(item);
- ----
-
- endif::web[]
-
- [[datamodel.items.beanitem]]
- == Wrapping a Bean in a [classname]#BeanItem#
-
- The [classname]#BeanItem# implementation of the [classname]#Item# interface is a
- wrapper for Java Bean objects. In fact, only the setters and getters are
- required while serialization and other bean features are not, so you can wrap
- almost any POJOs with minimal requirements.
-
-
- ----
- // Here is a bean (or more exactly a POJO)
- public class Person {
- String name;
- int yearOfBirth;
-
- public Person(String name, int yearOfBirth) {
- this.name = name;
- this.yearOfBirth = yearOfBirth;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getYearOfBirth() {
- return yearOfBirth;
- }
-
- public void setYearOfBirth(int yearOfBirth) {
- this.yearOfBirth = yearOfBirth;
- }
- }
-
- // Create an instance of the bean
- Person bean = new Person();
-
- // Wrap it in a BeanItem
- BeanItem<Person> item = new BeanItem<Person>(bean);
-
- // Bind it to a component
- Form form = new Form();
- form.setItemDataSource(item);
- ----
-
- You can use the [methodname]#getBean()# method to get a reference to the
- underlying bean.
-
- [[datamodel.items.beanitem.nested]]
- === Nested Beans
-
- You may often have composite classes where one class "has a" another class. For
- example, consider the following [classname]#Planet# class which "has a"
- discoverer:
-
-
- ----
- // Here is a bean with two nested beans
- public class Planet implements Serializable {
- String name;
- Person discoverer;
-
- public Planet(String name, Person discoverer) {
- this.name = name;
- this.discoverer = discoverer;
- }
-
- ... getters and setters ...
- }
-
- ...
- // Create an instance of the bean
- Planet planet = new Planet("Uranus",
- new Person("William Herschel", 1738));
- ----
-
- When shown in a [classname]#Form#, for example, you would want to list the
- properties of the nested bean along the properties of the composite bean. You
- can do that by binding the properties of the nested bean individually with a
- [classname]#MethodProperty# or [classname]#NestedMethodProperty#. You should
- usually hide the nested bean from binding as a property by listing only the
- bound properties in the constructor.
-
-
- ----
- // Wrap it in a BeanItem and hide the nested bean property
- BeanItem<Planet> item = new BeanItem<Planet>(planet,
- new String[]{"name"});
-
- // Bind the nested properties.
- // Use NestedMethodProperty to bind using dot notation.
- item.addItemProperty("discoverername",
- new NestedMethodProperty(planet, "discoverer.name"));
-
- // The other way is to use regular MethodProperty.
- item.addItemProperty("discovererborn",
- new MethodProperty<Person>(planet.getDiscoverer(),
- "yearOfBirth"));
- ----
-
- The difference is that [classname]#NestedMethodProperty# does not access the
- nested bean immediately but only when accessing the property values, while when
- using [classname]#MethodProperty# the nested bean is accessed when creating the
- method property. The difference is only significant if the nested bean can be
- null or be changed later.
-
- You can use such a bean item for example in a [classname]#Form# as follows:
-
-
- ----
- // Bind it to a component
- Form form = new Form();
- form.setItemDataSource(item);
-
- // Nicer captions
- form.getField("discoverername").setCaption("Discoverer");
- form.getField("discovererborn").setCaption("Born");
- ----
-
- [[figure.datamodel.items.beanitem.nested]]
- .A [classname]#Form# with Nested Bean Properties
- image::img/beanitem-nested-beans.png[]
-
- The [classname]#BeanContainer# and [classname]#BeanItemContainer# allow easy
- definition of nested bean properties with
- [methodname]#addNestedContainerProperty()#, as described in
- <<dummy/../../../framework/datamodel/datamodel-container#datamodel.container.beancontainer.nestedproperties,"Nested
- Properties">>.
-
-
-
-
|