JFace Data binding
JFace permet de mettre en place un système permettant de mettre à jour les interfaces sur modification du modèle, et de mettre à jour le modèle, depuis la modification d'une interface :
-- Création du modèle
Sur le principe, chaque modèle va émettre un évènement sur modification de ses membres, évènement communiqué aux listeners associés au modèle.
-- Classe de base AbstractModel
La classe AbstractModel va permettre d'ajouter des listeners associés à des membres, et de déclencher des événements. Toute classe intégrée au modèle et utilisant le Data binding devra hériter de AbstractModel.
public abstract class AbstractModel {
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(
this);
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
public void addPropertyChangeListener(String propertyName,
PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
public void removePropertyChangeListener(String propertyName,
PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(propertyName,
listener);
}
protected void firePropertyChange(String propertyName, Object oldValue,
Object newValue) {
propertyChangeSupport.firePropertyChange(propertyName, oldValue,
newValue);
}
}
-- Création d'un Model
Création d'une classe Utilisateur :
- Utilisateur doit être un Bean (constructeur+getters/setters)
- Hériter de AbstractModel
- Appeler firePropertyChange sur la modification de ses membres
public class Utilisateur extends AbstractModel {
private String nom;
private int age;
public Utilisateur() {
}
public Utilisateur(String nom, int age) {
this.nom = nom;
this.age = age;
}
/**
* @return the nom
*/
public String getNom() {
return nom;
}
/**
* @param nom
* the nom to set
*/
public void setNom(String nom) {
String oldValue = this.nom;
this.nom = nom;
firePropertyChange("nom", oldValue, nom);
}
/**
* @return the age
*/
public int getAge() {
return age;
}
/**
* @param age
* the age to set
*/
public void setAge(int age) {
int oldValue = this.age;
this.age = age;
firePropertyChange("age", oldValue, age);
}
}
-- Création d'une vue
- Créer la classe FormUtilisateur, à partir de l'assistant SWT/window Application
- Ajouter le membre Utilisateur user
- Instancier le dans le constructeur
-- Implémentation du code
Implémenter les méthodes suivantes, puis tester l'interface
btnNewButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
user.setNom("DUPONT-LAJOIE");
user.setAge(25);
}
});
btnAfficher.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
lblUtilisateur.setText(user.toString());
}
});
-- Définition du binding
Ajouter les bindings suivants :
Code généré :
protected DataBindingContext initDataBindings() {
DataBindingContext bindingContext = new DataBindingContext();
//
IObservableValue observeTextTextNameObserveWidget = WidgetProperties.text(SWT.Modify).observe(textName);
IObservableValue namePersonObserveValue = BeanProperties.value("nom").observe(user);
bindingContext.bindValue(observeTextTextNameObserveWidget, namePersonObserveValue, null, null);
//
IObservableValue observeSelectionSpinnerObserveWidget = WidgetProperties.selection().observe(spinnerAge);
IObservableValue ageUserObserveValue = BeanProperties.value("age").observe(user);
bindingContext.bindValue(observeSelectionSpinnerObserveWidget, ageUserObserveValue, null, null);
//
return bindingContext;
}
Tester l'interface créée et son comportement
-- Binding sur listes d'objets
-- création du model
Implémenter le model Utilisateurs, permettant de gérer une liste d'instances d'Utilisateur :
public class Utilisateurs extends AbstractModel {
private final List<Utilisateur> items = new ArrayList<>();
public void add(Utilisateur utilisateur) {
items.add(utilisateur);
firePropertyChange("items", null, items);
}
public void remove(Utilisateur utilisateur) {
items.remove(utilisateur);
firePropertyChange("items", null, items);
}
/**
* @return the items
*/
public List<Utilisateur> getItems() {
return items;
}
}
-- Modification de la vue
- Ajouter à la vue les widgets manquants
- Ajouter le membre Utilisateurs users
- Instancier le dans le constructeur
-- Implémentation du comportement
Implémenter les méthodes suivantes, puis tester l'interface
btnAjouter.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
users.add(new Utilisateur(textName.getText(), spinnerAge.getSelection()));
}
});
btnSupprimer.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
IStructuredSelection selection = (IStructuredSelection) listViewer.getSelection();
if (selection != null)
for (Iterator it = selection.iterator(); it.hasNext();) {
Utilisateur aUser = (Utilisateur) it.next();
users.remove(aUser);
}
}
});


