Eclipse - binding (from Eclipse 3.3)
JFace-Data-Binding from Eclipse 3.3
In a thought example, a model shall consist of these three attributes:
- surname
- first name
- date of birth
binding-method
The binding-method can be implemented for example in the MyFormPart-class.
private void bind(model) { m_bindingContext = new DataBindingContext(); Binding binding; binding = m_bindingContext.bindValue(SWTObservables.observeText(m_lastnameTxt, SWT.Modify), BeansObservables.observeValue(model, MyModel.PROP_LASTNAME), null, null); binding = m_bindingContext.bindValue(SWTObservables.observeText(m_firstnameTxt, SWT.Modify), BeansObservables.observeValue(model, MyModel.PROP_FIRSTNAME), null, null); initUpdateStrategy(); binding = m_bindingContext.bindValue(SWTObservables.observeText(m_birthdateTxt, SWT.Modify), BeansObservables.observeValue(model, MyModel.PROP_BIRTHDAY), m_targetToModelStrategy, m_modelToTargetStrategy); }
The call occurs in the setFormInput(..) method:
@Override public boolean setFormInput(final Object input){ MyModel model = (MyModel)input; bind(model); }
method initUpdateStrategy()
This method is called up from the bind()-method, so it must be reachable for this one.
private void initUpdateStrategy(){ IConverter date2StrConverter = new IConverter() { public Object convert(Object fromObject) { assert fromObject instanceof Date; Date date = (Date) fromObject; SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy"); return sdf.format(date); } public Object getFromType() { return Date.class; } public Object getToType() { return String.class; } }; IConverter str2DateConverter = new IConverter() { public Object convert(Object fromObject) { assert fromObject instanceof String; String str = (String) fromObject; SimpleDateFormat sd = new SimpleDateFormat("dd.MM.yyyy"); Date date = null; try { Date newDate = sd.parse(dateString); } catch (Exception e) { e.printstacktrace(); } return date; } public Object getFromType() { return String.class; } public Object getToType() { return Date.class; } }; IValidator dateFormatValidator = new IValidator() { public IStatus validate(Object value) { assert value instanceof String; IStatus status = Status.OK_STATUS; String str = (String) value; if (str.matches("\\d{2}\\.\\d{2}\\.\\d{4}")) { try { DateConv.toDate(str); }catch(IllegalArgumentException e) { status = ValidationStatus.error("Wrong Date", e); } }else status = ValidationStatus.error("Wrong Format"); return status; } }; IValidator dateBizValidator = new IValidator() { public IStatus validate(Object value) { IStatus status = Status.OK_STATUS; Date inspect = (Date) value; if (null != inspect) { final Date today = new Date(); if (today.before(inspect)) status = ValidationStatus.error("Datum muss vor heute liegen!"); } return status; } }; m_modelToTargetUpdateStrategy1 = new UpdateValueStrategy(); // oder bei spezieller Policy (Default: UpdateValueStrategy.POLICYUPDATE) // m_modelToTargetUpdateStrategy1 = new UpdateValueStrategy(UpdateValueStrategy.NEVER); m_modelToTargetUpdateStrategy1.setConverter(date2StrConverter); m_targetToModelUpdateStrategy = new UpdateValueStrategy(); m_targetToModelUpdateStrategy.setConverter(str2DateConverter); m_targetToModelUpdateStrategy.setAfterGetValidator(dateFormatValidator); m_targetToModelUpdateStrategy.setBeforeSetValidator(dateBizValidator); }
model-class
package com.sowas.demo; import java.beans.PropertyChangeListener; public class MyModel { String PROP_LASTNAME = "lastname"; String PROP_FIRSTNAME = "firstname"; String PROP_BIRTHDAY = "birthday"; private final PropertyChangeSupport m_propertyChangeSupport = new PropertyChangeSupport(); private String m_lastname; private String m_firstname; private Date m_birthday; public MyModel(String lastname, String firstname, Date birthday) { m_lastname = lastname; m_firstname = firstname; m_birthday = birthday; } public String getLastname(){ return m_lastname; } public void setLastname(final String newValue){ String oldValue = getLastname(); m_lastname = newValue; firePropertyChange(PROP_LASTNAME, oldValue, newValue); } public String getFirstname(){ return m_firstname; } public void setFirstname(final String newValue){ String oldValue = getFirstname(); m_firstname = newValue; firePropertyChange(PROP_FIRSTNAME, oldValue, newValue); } public Date getBirthday(){ return m_birthday; } public void setBirthday(final Date newValue){ Date oldValue = getBirthday(); m_birthday = newValue; firePropertyChange(PROP_BIRTHDAY, oldValue, newValue); } protected boolean firePropertyChange(final String propertyName, final Object oldValue, final Object newValue) { return m_propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue); } public void addPropertyChangeListener(final PropertyChangeListener listener, final String... propertyNames) { m_propertyChangeSupport.addPropertyChangeListener(listener, propertyNames); } public void addPropertyChangeListener(final PropertyChangeListener listener) { m_propertyChangeSupport.addPropertyChangeListener(listener); } public void removePropertyChangeListener(final PropertyChangeListener listener, final String... propertyNames) { m_propertyChangeSupport.removePropertyChangeListener(listener, propertyNames); } public void removePropertyChangeListener(final PropertyChangeListener listener) { m_propertyChangeSupport.removePropertyChangeListener(listener); } }
troubleshooting
If a setXYZ(..)-method is not found, you should firstly check the spelling of the property-constants (here: PROP_XXXXX). This one must be written exactly as the get and set-methods. Merely the get and set is left out and the first letter is written small.
Example:
there would be the method getValue() and setValue(), so the constant had to be defined as „value“.
Example:
public static final String PROP_VALUE = "value";
Secondly, you can set a breakpoint in the method ValueBinding#doUpdate(..) (e.g. at the call of the method updateValueStrategy.doSet(..)) to find the bug.
Careful! In Eclipse 3.3 there is a bug: The propertymethod/ property-constant is not allowed to begin with two capital letters (so, not: getVAlue() with „vAlue“)!!