Databinding and setter cancellation.

SWT Designer allows you to create the views, editors, perspectives, pref pages, composites, etc. that comprise Eclipse SWT & RCP applications and plug-ins.

Moderators: Konstantin.Scheglov, gnebling, Alexander.Mitin, jwren, Eric Clayberg

Databinding and setter cancellation.

Postby hyshyshys » Fri Aug 15, 2008 6:39 am

Hi all,

I'm pretty new to WindowBuilder and DataBinding and have some basic questions about databinding and the source bean model. I posted my questions here but I'm not sure it's the right place for this discussion but could be helpful...

Suppose for example the following:

1- I have a simple view (MyView) with a combobox (MyCombo) on it and a bean (myModel) with the corresponding property (myComboValue).
2- I setup a databinding between the combobox and the property.
3- See the code below
4- When I change the value of the combobox, the databinding will call the setter method of my property.
5- Suppose now, that something appends (like an exception) during the execution of the setter method.
6- How could I cancel the the UI value change. In my model, it easy to cancel the change operation, but in the target UI, it looks that it's too late.
What is the best way to do this?
7- I tried many differents ways without success:
  • throw an exception out of the setter method : nothing appends
  • call the firenotification method with the oldvalue instead of the new value : nothing appends
  • call the firenotification methods with the oldvalue and then call the dataBinding.updateTarget() method : it doesn't work correctly. here is why
    • suppose the current value is value1
    • I change the combobox value to value2 but exception occurs
    • the firenotification is called with oldvalue
    • the updateTarget method is called
    • the combobox value goes automatically to value1 (so it works the first time)
    • I change the combobox value again to value 2 but exception again
    • the firenotification is called with oldvalue
    • the updateTarget method is called
    • the combobox value stay to value 2 (so it doesn't work the second time when I try the same value).
  • I also tried many variations of the above but without success.

Any suggestion will be appreciate.
Thanks.
Vincent


Here is the code of my view:
Code: Select all
package test2;

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.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;

public class MyView extends ViewPart {

   private Text text;
   private DataBindingContext m_bindingContext;
   private Combo myCombo;
   public static final String ID = "test2.MyView"; //$NON-NLS-1$

   private MyModel myModel = new MyModel();
   
   /**
    * Create contents of the view part
    * @param parent
    */
   @Override
   public void createPartControl(Composite parent) {
      Composite container = new Composite(parent, SWT.NONE);
      final GridLayout gridLayout = new GridLayout();
      gridLayout.numColumns = 2;
      container.setLayout(gridLayout);

      final Label mycomboboxLabel = new Label(container, SWT.NONE);
      mycomboboxLabel.setText("Item control:");

      myCombo = new Combo(container, SWT.NONE);
      myCombo.select(0);
      myCombo.setItems(new String[] {"Item1", "Item2", "Item3"});
      final GridData gd_myCombo = new GridData(SWT.LEFT, SWT.CENTER, true, false);
      myCombo.setLayoutData(gd_myCombo);

      final Label myitemdisplayLabel = new Label(container, SWT.NONE);
      myitemdisplayLabel.setText("Item display:");

      text = new Text(container, SWT.BORDER);
      text.setEditable(false);
      text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
      
      
      //
      createActions();
      initializeToolBar();
      initializeMenu();
      m_bindingContext = initDataBindings();
   }

   /**
    * Create the actions
    */
   private void createActions() {
      // Create the actions
   }

   /**
    * Initialize the toolbar
    */
   private void initializeToolBar() {
      IToolBarManager toolbarManager = getViewSite().getActionBars()
            .getToolBarManager();
   }

   /**
    * Initialize the menu
    */
   private void initializeMenu() {
      IMenuManager menuManager = getViewSite().getActionBars()
            .getMenuManager();
   }

   @Override
   public void setFocus() {
      // Set the focus
   }
   protected DataBindingContext initDataBindings() {
      IObservableValue textTextObserveWidget = SWTObservables.observeText(text, SWT.Modify);
      IObservableValue myModelMyComboValueObserveValue = BeansObservables.observeValue(myModel, "myComboValue");
      IObservableValue comboTextObserveWidget = SWTObservables.observeText(myCombo);
      IObservableValue myModelMyComboValueObserveValue_1 = BeansObservables.observeValue(myModel, "myComboValue");
      //
      //
      DataBindingContext bindingContext = new DataBindingContext();
      //
      bindingContext.bindValue(textTextObserveWidget, myModelMyComboValueObserveValue_1, null, null);
      bindingContext.bindValue(comboTextObserveWidget, myModelMyComboValueObserveValue, null, null);
      //
      return bindingContext;
   }

}


Here is the code of my data model:
Code: Select all
package test2;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

public class MyModel {

   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);
   }
   
   private String myComboValue = "Item1";

   public String getMyComboValue() {
      return myComboValue;
   }   
   
   public void setMyComboValue(String myComboValue) {
      String oldMyComboValue = this.myComboValue;
      
      
      if (changeValue(myComboValue) == true) {
         this.myComboValue = myComboValue;
         firePropertyChange("myComboValue", oldMyComboValue, myComboValue);
      }
      else {
         // What should I do here to cancel the changes in the UI ???
         // ???
      }
   }
   
   public boolean changeValue(String myComboValue) {
      
      try {
         // try to set the value.
         int a = 1 / 0;

      }
      catch (Exception e) {
         // something appends. we need to cancel changes
         return false;
      }
      // if success, apply changes       
      return true;
      
   }
}
hyshyshys
 
Posts: 37
Joined: Thu Jul 03, 2008 12:27 pm

Re: Databinding and setter cancellation.

Postby Eric Clayberg » Fri Aug 15, 2008 12:14 pm

hyshyshys wrote:I posted my questions here but I'm not sure it's the right place for this discussion

In general, questions about how to use the Eclipse Data Binding API should be posted to the eclipse.platform newsgroup. This forum is for questions about how to use SWT Designer itself.

hyshyshys wrote:How could I cancel the the UI value change. In my model, it easy to cancel the change operation, but in the target UI, it looks that it's too late.
What is the best way to do this?

There is no need to validate the value in the model object (setter). You should use UpdateValueStrategy.setBeforeSetValidator()...

Code: Select all
    package test2;

    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.action.IMenuManager;
    import org.eclipse.jface.action.IToolBarManager;
    import org.eclipse.jface.databinding.swt.SWTObservables;
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.layout.GridData;
    import org.eclipse.swt.layout.GridLayout;
    import org.eclipse.swt.widgets.Combo;
    import org.eclipse.swt.widgets.Composite;
    import org.eclipse.swt.widgets.Label;
    import org.eclipse.swt.widgets.Text;
    import org.eclipse.ui.part.ViewPart;
    import org.eclipse.core.databinding.UpdateValueStrategy;
    import org.eclipse.core.databinding.validation.IValidator;
    import org.eclipse.core.runtime.IStatus;

    public class MyView extends ViewPart {

       private Text text;
       private DataBindingContext m_bindingContext;
       private Combo myCombo;
       public static final String ID = "test2.MyView"; //$NON-NLS-1$

       private MyModel myModel = new MyModel();
       
       /**
        * Create contents of the view part
        * @param parent
        */
       @Override
       public void createPartControl(Composite parent) {
          Composite container = new Composite(parent, SWT.NONE);
          final GridLayout gridLayout = new GridLayout();
          gridLayout.numColumns = 2;
          container.setLayout(gridLayout);

          final Label mycomboboxLabel = new Label(container, SWT.NONE);
          mycomboboxLabel.setText("Item control:");

          myCombo = new Combo(container, SWT.NONE);
          myCombo.select(0);
          myCombo.setItems(new String[] {"Item1", "Item2", "Item3"});
          final GridData gd_myCombo = new GridData(SWT.LEFT, SWT.CENTER, true, false);
          myCombo.setLayoutData(gd_myCombo);

          final Label myitemdisplayLabel = new Label(container, SWT.NONE);
          myitemdisplayLabel.setText("Item display:");

          text = new Text(container, SWT.BORDER);
          text.setEditable(false);
          text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
         
         
          //
          createActions();
          initializeToolBar();
          initializeMenu();
          m_bindingContext = initDataBindings();
       }

       /**
        * Create the actions
        */
       private void createActions() {
          // Create the actions
       }

       /**
        * Initialize the toolbar
        */
       private void initializeToolBar() {
          IToolBarManager toolbarManager = getViewSite().getActionBars()
                .getToolBarManager();
       }

       /**
        * Initialize the menu
        */
       private void initializeMenu() {
          IMenuManager menuManager = getViewSite().getActionBars()
                .getMenuManager();
       }

       @Override
       public void setFocus() {
          // Set the focus
       }
       protected DataBindingContext initDataBindings() {
          IObservableValue textTextObserveWidget = SWTObservables.observeText(text, SWT.Modify);
          IObservableValue myModelMyComboValueObserveValue = BeansObservables.observeValue(myModel, "myComboValue");
          IObservableValue comboTextObserveWidget = SWTObservables.observeText(myCombo);
          IObservableValue myModelMyComboValueObserveValue_1 = BeansObservables.observeValue(myModel, "myComboValue");
          //
          //
          DataBindingContext bindingContext = new DataBindingContext();
          //
          UpdateValueStrategy textToModelStrategy = new UpdateValueStrategy();
          textToModelStrategy.setBeforeSetValidator(new MyValidator());
          bindingContext.bindValue(textTextObserveWidget, myModelMyComboValueObserveValue_1, textToModelStrategy, null);
          //
          UpdateValueStrategy comboToModelStrategy = new UpdateValueStrategy();
          comboToModelStrategy.setBeforeSetValidator(new MyValidator());
          bindingContext.bindValue(comboTextObserveWidget, myModelMyComboValueObserveValue, comboToModelStrategy, null);
          //
          return bindingContext;
       }

       private static class MyValidator implements IValidator {
      public IStatus validate(Object value) {
         if (!"test".equals(value)) {
            return IStatus.ERROR;
         }
         return IStatus.OK;
      }
       }
    }

Code: Select all
    package test2;

    import java.beans.PropertyChangeListener;
    import java.beans.PropertyChangeSupport;

    public class MyModel {

       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);
       }
       
       private String myComboValue = "Item1";

       public String getMyComboValue() {
          return myComboValue;
       }   
       
       public void setMyComboValue(String myComboValue) {
          String oldMyComboValue = this.myComboValue;
          this.myComboValue = myComboValue;
          firePropertyChange("myComboValue", oldMyComboValue, myComboValue);
       }
    }
Eric Clayberg
Software Engineering Manager
Google
http://code.google.com/webtoolkit/download.html

Author: "Eclipse Plug-ins"
http://www.qualityeclipse.com
Eric Clayberg
Moderator
 
Posts: 4503
Joined: Tue Sep 30, 2003 6:39 am
Location: Boston, MA USA


Return to SWT Designer

Who is online

Users browsing this forum: No registered users and 2 guests