Vaadin Web应用开发教程(43): 使用Item接口管理一组Property

jerry VaadinWeb 2015年11月25日 收藏

Item接口用来管理一组命名的Property对象。每个Property由一个标识符(PID)来定义,Item通过PID使用方法getItemProperty()来读写其中的Property。
使用Item的地方例如Table的一行,每个属性(Property)对应行的每个字段(列column)。或者是Tree的一个节点,以及绑定到表单From的数据,此时Item中的每个属性对应的表单中的一个输入域(Field)。
使用在面向对象概念来说,Item 对应到一个对象,但Item可以支持配置及通过事件处理机制(主要是数据变化事件)。
使用Item的最简单的方法是使用Vaadin的一些内置实现,比如PropertysetItem 或BeanItem。此外Form也实现了Item接口因此可当作Item对象来使用。Form可以通过Item自动创建其中的UI组件,可以参见Vaadin Web应用开发教程(23):UI组件-Form组件
Item 接口定义了一些接口来管理其中的Property或监听Property值变化事件。

使用PropertysetItem
PropertysetItem 是实现了Item接口的通用实现,可以用来存放属性值。属性通过addItemProperty添加到集合中。

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);

使用BeanItem
BeanItem也实现了Item接口可以用来包容一个JavaBean对象。实际上只使用Java Bean规范中的setter 和getter而未使用其它JavaBean功能,因此BeanItem也可以用在一般的Java对象(POJO)上。

// Here is a bean (or more exactly a POJO)
class Person {
    String name;
    int    age;
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public Integer getAge() {
        return age;
    }
    
    public void setAge(Integer age) {
        this.age = age.intValue();
    }
}

// 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);

嵌套使用Bean
在使用聚合类,某个类包含其它某个类,比如下面的Planet类定义了一个发现人Discovery(为Person 类)

// 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));

当需要在Form显示时,你可以希望在显示Planet属性的同时显示Disoveryer的一些属性,可以通过MethodProperty或NestedMethodProperty单独绑定这些属性,通常此时需要隐藏嵌套类本身被绑定到属性,可以在构造函数中只列出需要绑定的属性,比如只绑定Planet的Name 属性。

// 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(),
                                "born"));

NestedMethodProperty 和MethodProperty 不同点在于NestedMethodProperty只在需要访问属性值时才访问嵌套类,而MethodProperty则是在创建这个Method Property就访问嵌套类(如Person)。

下面代码将Item 绑定到一个Form

// Bind it to a component
Form form = new Form();
form.setItemDataSource(item);
    
// Nicer captions
form.getField("discoverername").setCaption("Discoverer");
form.getField("discovererborn").setCaption("Born");