L'interface Property est à la base du modèle de données de Vaadin. Il fournit une API standardisée pour lire et écrire dans un objet. Une propriété est toujours typée mais peut toutefois supporter des conversions dans certains cas. Le type d'une propriété peut être n'importe quelle classe Java. Optionnellement les propriétés peuvent déclencher des événements de type ValueChangeEvent pour assurer le suivi de leurs modifications.

La valeur d'une propriété est écrite à l'aide de la méthode setValue() et lue avec getValue(). La valeur retournée est une référence sur un Object générique, vous devez donc la caster vers le type approprié. Le type peut être connu grâce à la méthode getType().

final TextField tf = new TextField("Name");
// Ecrit la valeur
tf.setValue("The text field value");
// Lorsque le champ est édité par l'utilisateur
tf.addListener(new Property.ValueChangeListener() {
public void valueChange(ValueChangeEvent event) {
// Lit la valeur et effectue le cast vers le type approprié
String value = (String) tf.getValue();
// Fait quelque chose avec la valeur
layout.addComponent(new Label(value));
}
});

Les changements de la valeur de la propriété déclenchent normalement un ValueChangeEvent, qui peut être géré par un ValueChangeListener. L'objet événement fournit une référence vers la propriété à l'aide de la méthode getProperty().

Les propriété par elles même ne sont pas nommées. Elles sont regroupés en items, qui associe les propriétés à des noms: les Property Identifiers ou PIDs. Les Items peuvent être de plus contenus dans des containers et petre identifiés par des Item Identifiers ou IIDs. En restant dans l'analogie avec la feuille de calcul, les Property Identifierscorrespondrait aux noms des colonnes et les Item Identifiers aux noms des lignes. Les identificateurs peuvent être des objets arbitraires mais doivent implémenter les méthodes equals(Object) et hashCode() afin de pouvoir être utilisés dans n'importe quelle CollectionJava standard.

L'interface Property peut être utilisée soit en implementant l'interface soit en utilisant les implémentations intégrées. Vaadin inclut une implémentation de l'interface Property pour les " arbitrary function pairs" et les propriétés bean avec la classe MethodProperty , et pour les propriétés objet simple par la classe ObjectProperty comme ce sera décrit plus loin.

Comme les composants simples, de nombreux composants à sélection tels que Select, Table et Tree fournissent la sélection courante au travers de la propriété Property. Dans le mode de sélection unique, la propriété est un seul identificateur d'item alors qu'en mode sélection multiple il s'agit d'un ensemble d'identificateurs d'items. Veuillez consulter la documentation des composants à sélection pour de amples détails.

Les composants pouvant être liés à une propriété ont un objet datasource par défaut, typiquement un ObjectProperty qui est décrit plus loin. Comme de tels composants sont des afficheurs ou des éditeurs qui seront également décrit plus loin, vous pouvez effectuer une nouvelle liaison de données avec n'importe quelle source de données avec setPropertyDataSource().

La fonction la plus importante de Property et des autres interfaces du modèle de données est de connecter les classes implémentant l'interface directement avec des classes d'afficheur ou d'éditeur. Cela signifie que l'on connecte une source de données (modèle) à un interface utilisateur (vue) pour permettre l'affichage ou l'édition du modèle de données.

Une propriété peut être lié à un composant en implémentant l'interface Viewer et la méthode setPropertyDataSource().

// Have a data model
ObjectProperty property =
new ObjectProperty("Hello", String.class);
// Prendre un composant qui implémente Viewer
Label viewer = new Label();
// Effectuer sa liaison avec les données
viewer.setPropertyDataSource(property);

Vous pouvez utiliser la même méthode dans l'interface Editor pour lier un composant permettant l'édition particular property type to a property.

// Prendre un modèle de données
ObjectProperty property =
new ObjectProperty("Hello", String.class);
// Définir un composant qui implémente Viewer
TextField editor = new TextField("Edit Greeting");
// Effectuer la liaison aux données
editor.setPropertyDataSource(property);

Comme tous les composants de type champ implémentent l'interface Property vous pouvez lier tout composant implementant l'intercae Viewer à n'importe quel champ à partir du moment ou l'afficheur est capable de déterminer le type du champ. En continuant l'exemple précédent on peut effectuer la liaison d'un Label vers la valeu d'un TextField :

Label viewer = new Label();
viewer.setPropertyDataSource(editor);
// La valeur affichée dans l'afficheur est mise à jour imméditement
// après que la valeur ait étét éditée dans l'éditeur(dès que celui ci a perdu le focus
// a perdu le focus)
editor.setImmediate(true);

Implementation of the Property interface requires defining setters and getters for the value and the read-only mode. Only a getter is needed for the property type, as the type is often fixed in property implementations.

The following example shows a simple implementation of the Property interface:

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

The components get the displayed value by the toString() method, so it is necessary to override it. To allow editing the value, value returned in the toString() must be in a format that is accepted by the setValue() method, unless the property is read-only. The toString() can perform any type conversion necessary to make the internal type a string, and the setValue() must be able to make a reverse conversion.

The implementation example does not notify about changes in the property value or in the read-only mode. You should normally also implement at least the Property.ValueChangeNotifier and Property.ReadOnlyStatusChangeNotifier. See the ObjectProperty class for an example of the implementation.