Community
Participate
Working Groups
Konstantin Scheglov reported the following problem (originally in bug 104570): I think I found problem with this version: eclipse-SDK-I20051116-1332-win32.zip When I try to bind "double" property to Text it throws exception: org.eclipse.jface.databinding.BindingException: Converter does not apply to model type. Expected: double, actual: class java.lang.String at org.eclipse.jface.databinding.internal.ValueBinding.<init>(ValueBinding.java:61) at org.eclipse.jface.databinding.internal.DataBindingContext.bind(DataBindingContext.java:399) at org.eclipse.jface.databinding.internal.DataBindingContext.bind(DataBindingContext.java:454) at org.eclipse.jface.databinding.internal.DataBindingContext.bind(DataBindingContext.java:511) at ru.nlmk.Test.createContents(Test.java:87) at ru.nlmk.Test.open(Test.java:45) at ru.nlmk.Test.main(Test.java:34) I am not sure, but problem can be in ValueBinding, because when I change this: if (!converter.getModelType().equals(model.getValueType())) { throw new BindingException( "Converter does not apply to model type. Expected: " + model.getValueType() + ", actual: " + converter.getModelType()); //$NON-NLS-1$ //$NON-NLS-2$ } if (!converter.getTargetType().equals(target.getValueType())) { throw new BindingException( "Converter does not apply to target type. Expected: " + target.getValueType() + ", actual: " + converter.getTargetType()); //$NON-NLS-1$ //$NON-NLS-2$ } to this: if (!converter.getTargetType().equals(model.getValueType())) { throw new BindingException( "Converter does not apply to model type. Expected: " + model.getValueType() + ", actual: " + converter.getTargetType()); //$NON-NLS-1$ //$NON-NLS-2$ } if (!converter.getModelType().equals(target.getValueType())) { throw new BindingException( "Converter does not apply to target type. Expected: " + target.getValueType() + ", actual: " + converter.getModelType()); //$NON-NLS-1$ //$NON-NLS-2$ } it works. See also source code for bean and GUI below. import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; public class User { private String m_firstName; private String m_lastName; private double m_age; private PropertyChangeSupport m_propertyListeners = new PropertyChangeSupport( this); public String getFirstName() { return m_firstName; } public void setFirstName(String firstName) { m_firstName = firstName; } public String getLastName() { return m_lastName; } public void setLastName(String lastName) { String oldLastName = m_lastName; m_lastName = lastName; m_propertyListeners.firePropertyChange("lastName", oldLastName, m_lastName); } public double getAge() { return m_age; } public void setAge(double age) { Double oldAge = new Double(m_age); m_age = age; m_propertyListeners .firePropertyChange("age", oldAge, new Double(m_age)); } @Override public String toString() { return "(" + m_firstName + ", " + m_lastName + ", " + m_age + ")"; } public void addPropertyChangeListener(PropertyChangeListener listener) { m_propertyListeners.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { m_propertyListeners.removePropertyChangeListener(listener); } } import org.eclipse.jface.databinding.DataBinding; import org.eclipse.jface.databinding.IDataBindingContext; import org.eclipse.jface.databinding.PropertyDescription; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; public class Test { private Text m_txtAge; private Text m_txtLast; private Text m_txtFirst; protected Shell shell; /** * Launch the application * * @param args */ public static void main(String[] args) { try { Test window = new Test(); window.open(); } catch (Exception e) { e.printStackTrace(); } } /** * Open the window */ public void open() { final Display display = Display.getDefault(); createContents(); shell.open(); shell.layout(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } } /** * Create contents of the window */ protected void createContents() { shell = new Shell(); shell.setLayout(new GridLayout()); shell.setSize(439, 312); shell.setText("SWT Application"); final User user = new User(); user.setFirstName("Konstantin"); user.setLastName("Scheglov"); user.setAge(12); System.out.println("before: " + user); m_txtFirst = new Text(shell, SWT.BORDER); m_txtFirst.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); m_txtLast = new Text(shell, SWT.BORDER); m_txtLast.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); m_txtAge = new Text(shell, SWT.BORDER); m_txtAge.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); IDataBindingContext bindingContext = DataBinding.createContext(shell); try { bindingContext.bind(m_txtFirst, new PropertyDescription(user, "firstName"), null); bindingContext.bind(m_txtLast, new PropertyDescription(user, "lastName"), null); bindingContext.bind(m_txtAge, new PropertyDescription(user, "age"), null); } catch (Throwable e) { e.printStackTrace(); } final Button showButton = new Button(shell, SWT.NONE); showButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { System.out.println("current: " + user); } }); showButton.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); showButton.setText("Show!"); final Button changeButton = new Button(shell, SWT.NONE); changeButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { user.setLastName("" + System.currentTimeMillis()); user.setAge(18); } }); changeButton.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false)); changeButton.setText("Change!"); } }
The converters use the target/model designation given that they work both way. The IBindSupportFactory, and IDataBindingContext use the from/to designation for validators given that they work one way. It will make it less confusing if it is consistent - as the construction or the defaulting to one, an 2 arg. lookup.
This should be fixed now that we have only one-way converters, and support for converting to and from primitive types. Please reopen if I am wrong.