Differenze tra le versioni di "Programmazione:Java/Eclipse RCP/Model databinding"
| Riga 50: | Riga 50: | ||
</code>  | </code>  | ||
| − | Gli ultimi due '''null''' passati in fondo alla funzione '''bindValue''' sono implementazioni della classe '''UpdateValueStrategy''' che permettono di definire l'accesso al modello e al dato  | + | Gli ultimi due '''null''' passati in fondo alla funzione '''bindValue''' sono implementazioni della classe '''UpdateValueStrategy''' che permettono di definire l'accesso al modello e al dato.  | 
| + | |||
| + | Nel caso di bisogni particolari è possibile anche definire dei '''CustoObserve''', l'esempio che segue è relativo ad una serie di RadioButton che hanno il valore inserito nel data dell'oggetto.  | ||
| + | |||
| + | <code java>  | ||
| + | import java.util.ArrayList;  | ||
| + | import java.util.Iterator;  | ||
| + | import java.util.List;  | ||
| + | |||
| + | import org.eclipse.core.databinding.observable.Diffs;  | ||
| + | import org.eclipse.jface.internal.databinding.provisional.swt.AbstractSWTVetoableValue;  | ||
| + | import org.eclipse.swt.SWT;  | ||
| + | import org.eclipse.swt.widgets.Button;  | ||
| + | import org.eclipse.swt.widgets.Composite;  | ||
| + | import org.eclipse.swt.widgets.Control;  | ||
| + | import org.eclipse.swt.widgets.Event;  | ||
| + | import org.eclipse.swt.widgets.Listener;  | ||
| + | |||
| + | @SuppressWarnings("restriction")  | ||
| + | public class RadioGroupObservableValue extends AbstractSWTVetoableValue implements Listener {  | ||
| + |    private final Composite group;  | ||
| + | |||
| + |    private String oldValue, newValue;  | ||
| + | |||
| + |    private boolean updating = false;  | ||
| + | |||
| + |    private List<Button> childs = new ArrayList<Button>();  | ||
| + | |||
| + |    public RadioGroupObservableValue(final Composite group) {  | ||
| + |       super(group);  | ||
| + |       this.group = group;  | ||
| + |    }  | ||
| + | |||
| + |    /**  | ||
| + |     * Tipo di valore gestito (java.lang.String)  | ||
| + |     */  | ||
| + |    @Override  | ||
| + |    public Object getValueType() {  | ||
| + |       return String.class;  | ||
| + |    }  | ||
| + | |||
| + |    /**  | ||
| + |     * Funzione richiamata per ribaltare il model nel controllo  | ||
| + |     */  | ||
| + |    @Override  | ||
| + |    protected void doSetApprovedValue(final Object value) {  | ||
| + |       try {  | ||
| + |          updating = true;  | ||
| + |          for (Iterator<Button> iter = childs.iterator(); iter.hasNext();) {  | ||
| + |             iter.next().setSelection(((String) ctrl.getData("VALUE")).equals(value));  | ||
| + |          }  | ||
| + |          oldValue = newValue = (String) value;  | ||
| + |       } finally {  | ||
| + |          updating = false;  | ||
| + |       }  | ||
| + |    }  | ||
| + | |||
| + |    /**  | ||
| + |     * Funzione richiamata per ribaltare il valore del controllo nel modello  | ||
| + |     */  | ||
| + |    @Override  | ||
| + |    protected Object doGetValue() {  | ||
| + |       return oldValue = newValue;  | ||
| + |    }  | ||
| + | |||
| + |    /**  | ||
| + |     * Rilegge e registra i figli del composite di tipo Button  | ||
| + |     */  | ||
| + |    public void reloadRadio() {  | ||
| + |       for (Iterator<Button> iter = childs.iterator(); iter.hasNext();) {  | ||
| + |          Button ctrl = iter.next();  | ||
| + |          ctrl.removeListener(SWT.Selection, this);  | ||
| + |       }  | ||
| + |       childs.clear();  | ||
| + |       for (int i = 0; i < group.getChildren().length; i++) {  | ||
| + |          Control ctrl = group.getChildren()[i];  | ||
| + |          if (ctrl instanceof Button) {  | ||
| + |             Button button = (Button) ctrl;  | ||
| + |             if (oldValue == null) {  | ||
| + |                newValue = (String) button.getData("VALUE");  | ||
| + |             }  | ||
| + |             button.addListener(SWT.Selection, this);  | ||
| + |             childs.add(button);  | ||
| + |             button.setSelection(((String) button.getData("VALUE")).equals(oldValue));  | ||
| + |          }  | ||
| + |       }  | ||
| + |       if (oldValue == null) {  | ||
| + |          fireValueChange(Diffs.createValueDiff(oldValue, newValue));  | ||
| + |          oldValue = newValue;  | ||
| + |       }  | ||
| + |    }  | ||
| + | |||
| + |    /**  | ||
| + |     * Gestione selezione RadioButton  | ||
| + |     */  | ||
| + |    public void handleEvent(Event event) {  | ||
| + |       if (!updating) {  | ||
| + |          newValue = (String) event.widget.getData("VALUE");  | ||
| + |          if (!newValue.equals(oldValue)) {  | ||
| + |             fireValueChange(Diffs.createValueDiff(oldValue, newValue));  | ||
| + |             oldValue = newValue;  | ||
| + |          }  | ||
| + |       }  | ||
| + |    }  | ||
| + | |||
| + |    @Override  | ||
| + |    public void dispose() {  | ||
| + |       for (Iterator<Button> iter = childs.iterator(); iter.hasNext();) {  | ||
| + |          iter.next().removeListener(SWT.Selection, this);  | ||
| + |       }  | ||
| + |       childs.clear();  | ||
| + |       super.dispose();  | ||
| + |    }  | ||
| + | }  | ||
| + | </code>  | ||
Versione delle 14:46, 27 mag 2008
Per poter collegare il modello all'interfaccia grafica bisogna prima di tutto inserire tra le dipendenze i plugin:
- org.eclipse.core.databinding
 - org.eclipse.core.databinding.beans
 - org.eclipse.jface.databinding
 
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
public class TestBinding extends WizardPage {
  public class Model {
     String value;
     public void setValue(String s) { value = s; }
     public String setValue() { return value; }
  }
  private Model model = new Model();
  private DataBindingContext dbc;
  public TestBinding(String pageName, String title, ImageDescriptor titleImage) {
     super(pageName, title, titleImage);
     dbc = new DataBindingContext();
  }
  public TestBinding(String pageName) {
     super(pageName);
     dbc = new DataBindingContext();
  }
  public void createControl(Composite parent) {
     Composite ctrl= new Composite(parent, SWT.BORDER);
     setControl(ctrl);
     Text test_binding = new Text(ctrl, SWT.NONE);
     IObservableValue modelObservable = BeansObservables.observeValue(model, "value");
     dbc.bindValue(SWTObservables.observeText(test_binding, SWT.Modify), modelObservable, null, null);
  }
}
Gli ultimi due null passati in fondo alla funzione bindValue sono implementazioni della classe UpdateValueStrategy che permettono di definire l'accesso al modello e al dato.
Nel caso di bisogni particolari è possibile anche definire dei CustoObserve, l'esempio che segue è relativo ad una serie di RadioButton che hanno il valore inserito nel data dell'oggetto.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.databinding.observable.Diffs;
import org.eclipse.jface.internal.databinding.provisional.swt.AbstractSWTVetoableValue;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
@SuppressWarnings("restriction")
public class RadioGroupObservableValue extends AbstractSWTVetoableValue implements Listener {
  private final Composite group;
  private String oldValue, newValue;
  private boolean updating = false;
  private List<Button> childs = new ArrayList<Button>();
  public RadioGroupObservableValue(final Composite group) {
     super(group);
     this.group = group;
  }
  /**
   * Tipo di valore gestito (java.lang.String)
   */
  @Override
  public Object getValueType() {
     return String.class;
  }
  /**
   * Funzione richiamata per ribaltare il model nel controllo
   */
  @Override
  protected void doSetApprovedValue(final Object value) {
     try {
        updating = true;
        for (Iterator<Button> iter = childs.iterator(); iter.hasNext();) {
           iter.next().setSelection(((String) ctrl.getData("VALUE")).equals(value));
        }
        oldValue = newValue = (String) value;
     } finally {
        updating = false;
     }
  }
  /**
   * Funzione richiamata per ribaltare il valore del controllo nel modello
   */
  @Override
  protected Object doGetValue() {
     return oldValue = newValue;
  }
  /**
   * Rilegge e registra i figli del composite di tipo Button
   */
  public void reloadRadio() {
     for (Iterator<Button> iter = childs.iterator(); iter.hasNext();) {
        Button ctrl = iter.next();
        ctrl.removeListener(SWT.Selection, this);
     }
     childs.clear();
     for (int i = 0; i < group.getChildren().length; i++) {
        Control ctrl = group.getChildren()[i];
        if (ctrl instanceof Button) {
           Button button = (Button) ctrl;
           if (oldValue == null) {
              newValue = (String) button.getData("VALUE");
           }
           button.addListener(SWT.Selection, this);
           childs.add(button);
           button.setSelection(((String) button.getData("VALUE")).equals(oldValue));
        }
     }
     if (oldValue == null) {
        fireValueChange(Diffs.createValueDiff(oldValue, newValue));
        oldValue = newValue;
     }
  }
  /**
   * Gestione selezione RadioButton
   */
  public void handleEvent(Event event) {
     if (!updating) {
        newValue = (String) event.widget.getData("VALUE");
        if (!newValue.equals(oldValue)) {
           fireValueChange(Diffs.createValueDiff(oldValue, newValue));
           oldValue = newValue;
        }
     }
  }
  @Override
  public void dispose() {
     for (Iterator<Button> iter = childs.iterator(); iter.hasNext();) {
        iter.next().removeListener(SWT.Selection, this);
     }
     childs.clear();
     super.dispose();
  }
}