现在的位置: 首页 > 综合 > 正文

Vaadin Web应用开发教程(42):数据绑定-Property接口

2013年09月19日 ⁄ 综合 ⁄ 共 2785字 ⁄ 字号 评论关闭

Property接口为Vaadin数据模型的基本接口,它提供了读写单个数据对象的标准API。
一个Property对象总是有数据类型的,尽管它支持可选的数据类型转换。Property的数据可以为任意的Java对象,Property 也提供了监听数据变化的事件消息。

Property的读写方法为getValue()和setValue() 。getValue() 返回通用的Object 类型的对象,因此可以强制转换成所需的数据类型。Property的类型可以通过getType()取得。

Property值发生变化说触发ValueChangeEvent事件,可以通过ValueChangeListener监听这个事件。

final TextField tf = new TextField("Name");
        
// Set the value
tf.setValue("The text field value");
        
// When the field value is edited by the user
tf.addListener(new Property.ValueChangeListener() {
    public void valueChange(ValueChangeEvent event) {
        // Get the value and cast it to proper type
        String value = (String) tf.getValue();
        
        // Do something with it
        layout.addComponent(new Label(value));
    }
});

使用Property接口,一是实现Property接口,而是使用Vaadin内置的两个Property接口实现:MethodProperty 主要用于Java Bean,而是ObjectProperty用于简单的Java对象。

与Property接口关系紧密的还有两个接口Property.EditorProperty.Viewer 可以用来显示和编译Property值,大部分的UI组件,尤其是Field组件实现了这两个接口,因此Field组件可以直接绑定到Property对象,用来显示或编辑Property数据。

下例使用Label 来显示一个ObjectProperty 对象

// Have a data model
ObjectProperty property =
    new ObjectProperty("Hello", String.class);
        
// Have a component that implements Viewer
Label viewer = new Label();
        
// Bind it to the data
viewer.setPropertyDataSource(property);

同样可以使用一个TextField来编辑并显示一个ObjectProperty对象

// Have a data model
ObjectProperty property =
    new ObjectProperty("Hello", String.class);
        
// Have a component that implements Viewer
TextField editor = new TextField("Edit Greeting");
        
// Bind it to the data
editor.setPropertyDataSource(property);

前面说过所有Field组件也实现了Property接口,因此也可以把Field组件绑定到实现了Property.Viewer接口的UI组件,如Label。下例把一个Label绑定到一个TextField,因此Label显示的内容会和TextField的值变化而变化。

Label viewer = new Label();
viewer.setPropertyDataSource(editor);
 
// The value shown in the viewer is updated immediately
// after editing the value in the editor (once it
// loses the focus)
editor.setImmediate(true);

此外,你也可以自行实现Property接口,然后绑定到Field组件。

class MyProperty implements Property {
    Integer data     = 0;
    boolean readOnly = false;
    
    // Return the data type of the model
    public Class<?> getType() {
        return Integer.class;
    }

    public Object getValue() {
        return data;
    }
    
    // Override the default implementation in Object
    @Override
    public String toString() {
        return Integer.toHexString(data);
    }

    public boolean isReadOnly() {
        return readOnly;
    }

    public void setReadOnly(boolean newStatus) {
        readOnly = newStatus;
    }

    public void setValue(Object newValue)
            throws ReadOnlyException, ConversionException {
        if (readOnly)
            throw new ReadOnlyException();
            
        // Already the same type as the internal representation
        if (newValue instanceof Integer)
            data = (Integer) newValue;
        
        // Conversion from a string is required
        else if (newValue instanceof String)
            try {
                data = Integer.parseInt((String) newValue, 16);
            } catch (NumberFormatException e) {
                throw new ConversionException();
            }
        else
             // Don't know how to convert any other types
            throw new ConversionException();

        // Reverse decode the hexadecimal value
    }
}
        
// Instantiate the property and set its data
MyProperty property = new MyProperty();
property.setValue(42);
        
// Bind it to a component
final TextField tf = new TextField("Name", property);

抱歉!评论已关闭.