View | Details | Raw Unified | Return to bug 144260 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jface/internal/databinding/internal/swt/TextObservableValue.java (-45 / +213 lines)
Lines 11-20 Link Here
11
package org.eclipse.jface.internal.databinding.internal.swt;
11
package org.eclipse.jface.internal.databinding.internal.swt;
12
12
13
import org.eclipse.jface.internal.databinding.provisional.observable.Diffs;
13
import org.eclipse.jface.internal.databinding.provisional.observable.Diffs;
14
import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
14
import org.eclipse.jface.internal.databinding.provisional.observable.value.AbstractVetoableValue;
15
import org.eclipse.jface.internal.databinding.provisional.observable.value.AbstractVetoableValue;
15
import org.eclipse.swt.SWT;
16
import org.eclipse.swt.SWT;
16
import org.eclipse.swt.events.KeyEvent;
17
import org.eclipse.swt.events.KeyEvent;
17
import org.eclipse.swt.events.KeyListener;
18
import org.eclipse.swt.events.KeyListener;
19
import org.eclipse.swt.events.TraverseEvent;
20
import org.eclipse.swt.events.TraverseListener;
18
import org.eclipse.swt.events.VerifyEvent;
21
import org.eclipse.swt.events.VerifyEvent;
19
import org.eclipse.swt.events.VerifyListener;
22
import org.eclipse.swt.events.VerifyListener;
20
import org.eclipse.swt.widgets.Event;
23
import org.eclipse.swt.widgets.Event;
Lines 22-83 Link Here
22
import org.eclipse.swt.widgets.Text;
25
import org.eclipse.swt.widgets.Text;
23
26
24
/**
27
/**
25
 * @since 1.0
28
 * {@link IObservable} implementation that manages the binding of a model
29
 * property to a {@link Text} widget. The time at which communication of the
30
 * value change event is specified by the consumer on construction.
31
 * 
32
 * <dl>
33
 * <dt>Events:</dt>
34
 * <dd> If the update event type (specified on construction) is
35
 * <code>SWT.Modify</code> a value change event will be fired on every key
36
 * stroke. If the update event type is <code>SWT.FocusOut</code> a value
37
 * change event will be fired on focus out. When in either mode if the user is
38
 * entering text and presses [Escape] the value will be reverted back to the
39
 * previous, unedited, model value. Regardless of the update event type a value
40
 * changing event will fire on verify.</dd>
41
 * </dl>
42
 * 
43
 * <p>
44
 * <strong>EXPERIMENTAL</strong>. This class or interface has been added as
45
 * part of a work in progress. There is no guarantee that this API will remain
46
 * unchanged during the 3.2 release cycle. Please do not use this API without
47
 * consulting with the Platform/UI team.
48
 * </p>
26
 * 
49
 * 
50
 * @since 1.0
27
 */
51
 */
28
public class TextObservableValue extends AbstractVetoableValue {
52
public class TextObservableValue extends AbstractVetoableValue {
29
53
	/**
54
	 * {@link Text} widget that this is being observed.
55
	 */
30
	private final Text text;
56
	private final Text text;
31
57
58
	/**
59
	 * Flag to track when the model is updating the widget. When
60
	 * <code>true</code> the handlers for the SWT events should not process
61
	 * the event as this would cause an infinite loop.
62
	 */
32
	private boolean updating = false;
63
	private boolean updating = false;
33
64
34
	private int updatePolicy;
65
	/**
66
	 * SWT event that on firing this observable will fire change events in an
67
	 * attempt to update the model.
68
	 */
69
	private final int updateEventType;
70
71
	/**
72
	 * Valid types for the {@link #updateEventType}.
73
	 */
74
	private static final int[] validUpdateEventTypes = new int[] { SWT.Modify,
75
			SWT.FocusOut, SWT.NONE };
35
76
77
	/**
78
	 * Previous value from the model. It is maintained so that when entering
79
	 * text if the consumer were to press [Escape] the value can be reverted
80
	 * back to the last known model value.
81
	 */
36
	private String bufferedValue;
82
	private String bufferedValue;
37
83
38
	private Listener updateListener = new Listener() {
84
	private Listener updateListener;
39
		public void handleEvent(Event event) {
85
40
			if (!updating) {
86
	private VerifyListener verifyListener;
41
				String oldValue = bufferedValue;
87
42
				String newValue = text.getText();
88
	private KeyListener keyListener;
43
89
44
				// If we are updating on focus lost then when we fire the change
90
	private TraverseListener traverseListener;
45
				// event change the buffered value
91
46
				if (updatePolicy == SWT.FocusOut) {
92
	/**
47
					bufferedValue = text.getText();
93
	 * Private constructor for constructing a new instance.
94
	 * 
95
	 * @param text
96
	 * @param updateEventType
97
	 *            -1 if not specified
98
	 * @param traversalDetail
99
	 *            -1 if not specified
100
	 * @throws IllegalArgumentException if both <code>updateEventType</code> and <code>traverseEventType</code> == -1.
101
	 * @throws IllegalArgumentException if <code>updateEventType</code> is unsupported
102
	 */
103
	private TextObservableValue(final Text text, final int updateEventType,
104
			final int traversalDetail) {
105
		if (text == null) {
106
			throw new NullPointerException("Parameter " + text + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
107
		}
108
109
		if (updateEventType == -1 && traversalDetail == -1) {
110
			throw new IllegalArgumentException(
111
					"Update event type or traversal event must be set."); //$NON-NLS-1$
112
		}
113
		
114
		if (updateEventType > -1) {
115
			boolean eventValid = false;
116
			for (int i = 0; !eventValid && i < validUpdateEventTypes.length; i++) {
117
				eventValid = (updateEventType == validUpdateEventTypes[i]);
118
			}
119
			if (!eventValid) {
120
				throw new IllegalArgumentException(
121
						"UpdateEventType [" + updateEventType + "] is unsupported."); //$NON-NLS-1$//$NON-NLS-2$
122
			}
123
			
124
			setupLifecycleHandling(text, updateEventType);
125
		}
126
127
		if (traversalDetail > -1) {
128
			setupTraverseHandling(text, traversalDetail);
129
		}
130
131
		this.text = text;
132
		this.updateEventType = updateEventType;
133
134
		keyListener = new KeyListener() {
135
			public void keyPressed(KeyEvent e) {
136
				if (e.character == SWT.ESC && bufferedValue != null) {
137
					// Revert the value in the text field to the model value
138
					text.setText(bufferedValue);
139
				}
140
			}
141
142
			public void keyReleased(KeyEvent e) {
143
			}
144
		};
145
		text.addKeyListener(keyListener);
146
	}
147
148
	/**
149
	 * Performs setup for firing value change events on traversal.
150
	 * 
151
	 * @param text
152
	 * @param traverseEventTypes
153
	 */
154
	private void setupTraverseHandling(final Text text,
155
			final int traverseEventTypes) {
156
		traverseListener = new TraverseListener() {
157
			public void keyTraversed(TraverseEvent e) {
158
				if ((e.detail & traverseEventTypes) != 0) {
159
					String oldValue = bufferedValue;
160
					String newValue = text.getText();
161
48
					if (!newValue.equals(oldValue)) {
162
					if (!newValue.equals(oldValue)) {
49
						fireValueChange(Diffs.createValueDiff(oldValue,
163
						fireValueChange(Diffs.createValueDiff(oldValue,
50
								newValue));
164
								newValue));
51
					}
165
					}
52
				} else {
53
					fireValueChange(Diffs.createValueDiff(oldValue, text
54
							.getText()));
55
				}
166
				}
56
			}
167
			}
57
		}
168
		};
58
	};
169
		text.addTraverseListener(traverseListener);
59
170
	}
60
	private VerifyListener verifyListener;
61
62
	private KeyListener keyListener;
63
171
64
	/**
172
	/**
173
	 * Performs validation and setup for listeners of lifecycle events like
174
	 * modify and focus out.
175
	 * 
65
	 * @param text
176
	 * @param text
66
	 * @param updatePolicy
177
	 * @param event
178
	 * @param updateListener
67
	 */
179
	 */
68
	public TextObservableValue(final Text text, int updatePolicy) {
180
	private void setupLifecycleHandling(final Text text, int event) {
69
		this.text = text;
181
		if (event != SWT.None) {
70
		this.updatePolicy = updatePolicy;
182
			updateListener = new Listener() {
71
		if (updatePolicy != SWT.None) {
183
				public void handleEvent(Event event) {
72
			text.addListener(updatePolicy, updateListener);
184
					if (!updating) {
185
						String oldValue = bufferedValue;
186
						String newValue = text.getText();
187
188
						// If we are updating on focus lost then when we fire
189
						// the change
190
						// event change the buffered value
191
						if (updateEventType == SWT.FocusOut) {
192
							bufferedValue = text.getText();
193
							if (!newValue.equals(oldValue)) {
194
								fireValueChange(Diffs.createValueDiff(oldValue,
195
										newValue));
196
							}
197
						} else {
198
							fireValueChange(Diffs.createValueDiff(oldValue,
199
									text.getText()));
200
						}
201
					}
202
				}
203
			};
204
			text.addListener(event, updateListener);
73
		}
205
		}
74
		// If the update policy is TIME_EARLY then the model is notified of
206
		// If the update policy is SWT.Modify then the model is notified of
75
		// changed on key stroke by key stroke
207
		// changed on key stroke by key stroke
76
		// When escape is pressed we need to rollback to the previous value
208
		// When escape is pressed we need to rollback to the previous value
77
		// which is done with a key listener, however
209
		// which is done with a key listener, however
78
		// the bufferedValue (the last remembered change value) must be changed
210
		// the bufferedValue (the last remembered change value) must be changed
79
		// on focus lost
211
		// on focus lost
80
		if (updatePolicy == SWT.Modify) {
212
		if (event == SWT.Modify) {
81
			text.addListener(SWT.FocusOut, new Listener() {
213
			text.addListener(SWT.FocusOut, new Listener() {
82
				public void handleEvent(Event event) {
214
				public void handleEvent(Event event) {
83
					if (!updating) {
215
					if (!updating) {
Lines 101-120 Link Here
101
			}
233
			}
102
		};
234
		};
103
		text.addVerifyListener(verifyListener);
235
		text.addVerifyListener(verifyListener);
104
		keyListener = new KeyListener() {
236
	}
105
			public void keyPressed(KeyEvent e) {
106
				if (e.character == SWT.ESC && bufferedValue != null) {
107
					// Revert the value in the text field to the model value
108
					text.setText(bufferedValue);
109
				}
110
			}
111
237
112
			public void keyReleased(KeyEvent e) {
238
	/**
113
			}
239
	 * Constructs a new instance bound to <code>text</code> and configured to
114
		};
240
	 * fire change events at the time of the <code>updateEventType</code>.
115
		text.addKeyListener(keyListener);
241
	 * 
242
	 * @param text
243
	 * @param updateEventType
244
	 *            SWT event constant as to what SWT event to update the model in
245
	 *            response to. Appropriate values are: <code>SWT.Modify</code>,
246
	 *            <code>SWT.FocusOut</code>, <code>SWT.NONE</code>.
247
	 * @throws IllegalArgumentException
248
	 *             if <code>updateEventType</code> is an incorrect type.
249
	 */
250
	public TextObservableValue(final Text text, final int updateEventType) {
251
		this(text, updateEventType, -1);
116
	}
252
	}
117
253
254
	/**
255
	 * Sets the bound {@link Text Text's} text to the passed <code>value</code>.
256
	 * 
257
	 * @param value
258
	 *            new value, String expected
259
	 * @see org.eclipse.jface.internal.databinding.provisional.observable.value.AbstractVetoableValue#doSetValue(java.lang.Object)
260
	 * @throws ClassCastException
261
	 *             if the value is anything other than a String
262
	 */
118
	public void doSetValue(final Object value) {
263
	public void doSetValue(final Object value) {
119
		try {
264
		try {
120
			updating = true;
265
			updating = true;
Lines 135-146 Link Here
135
280
136
	public void dispose() {
281
	public void dispose() {
137
		if (!text.isDisposed()) {
282
		if (!text.isDisposed()) {
138
			text.removeKeyListener(keyListener);
283
			if (keyListener != null) {
139
			if (updatePolicy != SWT.None) {
284
				text.removeKeyListener(keyListener);
140
				text.removeListener(updatePolicy, updateListener);
285
			}
286
			if (updateListener != null) {
287
				text.removeListener(updateEventType, updateListener);
288
			}
289
290
			if (verifyListener != null) {
291
				text.removeVerifyListener(verifyListener);
292
			}
293
294
			if (traverseListener != null) {
295
				text.removeTraverseListener(traverseListener);
141
			}
296
			}
142
			text.removeVerifyListener(verifyListener);
143
		}
297
		}
144
		super.dispose();
298
		super.dispose();
145
	}
299
	}
300
301
	/**
302
	 * Constructs a TextObservableValue whose update policy is defined for
303
	 * traversal events rather than lifecycle events like Modify and FocusOut.
304
	 * 
305
	 * @param text
306
	 * @param details
307
	 *            traversal detail values or'd "|" together
308
	 * @return TextObservableValue
309
	 */
310
	public static TextObservableValue asTraversalObservable(Text text,
311
			int details) {
312
		return new TextObservableValue(text, -1, details);
313
	}
146
}
314
}
(-)src/org/eclipse/jface/internal/databinding/provisional/viewers/ViewersObservableFactory.java (+21 lines)
Lines 10-15 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.jface.internal.databinding.provisional.viewers;
11
package org.eclipse.jface.internal.databinding.provisional.viewers;
12
12
13
import org.eclipse.jface.internal.databinding.internal.swt.TextObservableValue;
13
import org.eclipse.jface.internal.databinding.internal.viewers.AbstractListViewerObservableCollectionWithLabels;
14
import org.eclipse.jface.internal.databinding.internal.viewers.AbstractListViewerObservableCollectionWithLabels;
14
import org.eclipse.jface.internal.databinding.internal.viewers.StructuredViewerObservableValue;
15
import org.eclipse.jface.internal.databinding.internal.viewers.StructuredViewerObservableValue;
15
import org.eclipse.jface.internal.databinding.internal.viewers.TableViewerObservableCollectionWithLabels;
16
import org.eclipse.jface.internal.databinding.internal.viewers.TableViewerObservableCollectionWithLabels;
Lines 17-24 Link Here
17
import org.eclipse.jface.internal.databinding.provisional.factories.IObservableFactory;
18
import org.eclipse.jface.internal.databinding.provisional.factories.IObservableFactory;
18
import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
19
import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
19
import org.eclipse.jface.viewers.AbstractListViewer;
20
import org.eclipse.jface.viewers.AbstractListViewer;
21
import org.eclipse.jface.viewers.CellEditor;
20
import org.eclipse.jface.viewers.StructuredViewer;
22
import org.eclipse.jface.viewers.StructuredViewer;
21
import org.eclipse.jface.viewers.TableViewer;
23
import org.eclipse.jface.viewers.TableViewer;
24
import org.eclipse.jface.viewers.TextCellEditor;
25
import org.eclipse.swt.SWT;
26
import org.eclipse.swt.widgets.Text;
22
27
23
/**
28
/**
24
 * A factory that supports binding to JFace viewers. This factory supports the
29
 * A factory that supports binding to JFace viewers. This factory supports the
Lines 36-41 Link Here
36
 * ViewersProperties.CONTENT</li>
41
 * ViewersProperties.CONTENT</li>
37
 * </ul>
42
 * </ul>
38
 * </li>
43
 * </li>
44
 * <li>TextCellEditor</li>
39
 * </ul>
45
 * </ul>
40
 * TODO complete the list
46
 * TODO complete the list
41
 * 
47
 * 
Lines 85-91 Link Here
85
		} else if (description instanceof TableViewer) {
91
		} else if (description instanceof TableViewer) {
86
			return new TableViewerObservableCollectionWithLabels(
92
			return new TableViewerObservableCollectionWithLabels(
87
					(TableViewer) description);
93
					(TableViewer) description);
94
95
		} else if (description instanceof CellEditor) {
96
			CellEditor editor = (CellEditor) description;
97
98
			if (editor.getControl() == null) {
99
				throw new IllegalArgumentException(
100
						"The CellEditor's control has not been constructed. The editor must have a control to bind.  Use the editor contructor that accepts a parent."); //$NON-NLS-1$
101
			}
102
103
			if (description instanceof TextCellEditor) {
104
				return TextObservableValue.asTraversalObservable(
105
						(Text) editor.getControl(), SWT.TRAVERSE_RETURN
106
								| SWT.TRAVERSE_TAB_NEXT);
107
			}
88
		}
108
		}
109
89
		return null;
110
		return null;
90
	}
111
	}
91
}
112
}
(-)src/org/eclipse/jface/internal/databinding/provisional/viewers/TableViewerEditorManager.java (+257 lines)
Added Link Here
1
package org.eclipse.jface.internal.databinding.provisional.viewers;
2
3
import org.eclipse.jface.internal.databinding.provisional.BindSpec;
4
import org.eclipse.jface.internal.databinding.provisional.Binding;
5
import org.eclipse.jface.internal.databinding.provisional.DataBindingContext;
6
import org.eclipse.jface.internal.databinding.provisional.description.Property;
7
import org.eclipse.jface.internal.databinding.provisional.description.TableModelDescription;
8
import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
9
import org.eclipse.jface.util.Assert;
10
import org.eclipse.jface.viewers.CellEditor;
11
import org.eclipse.jface.viewers.ICellModifier;
12
import org.eclipse.jface.viewers.TableViewer;
13
14
/**
15
 * Manages the process of binding editors to a <code>TableViewer</code>. When
16
 * using the manager manipulation of the cell modifier, column properties, or
17
 * editors on the viewer is forbidden.
18
 * 
19
 * @since 3.3
20
 */
21
public class TableViewerEditorManager {
22
	/**
23
	 * TableViewer whose editors are being managed.
24
	 */
25
	private final TableViewer tableViewer;
26
27
	/**
28
	 * Describes the model of the viewer, used to determine columns to edit.
29
	 */
30
	private final TableModelDescription tableModelDescription;
31
32
	/**
33
	 * Used to create observables for cell editors and to bind editors to the
34
	 * model.
35
	 */
36
	private final DataBindingContext dataBindingContext;
37
38
	/**
39
	 * IObservable that provides the ability to observe selection of the
40
	 * TableViewer. All editors observe the same instance.
41
	 */
42
	private IObservable selectionObservable;
43
44
	/**
45
	 * Constructs a new instance.
46
	 * 
47
	 * @param tableViewer
48
	 *            viewer to associate editors with
49
	 * @param tableModelDescription
50
	 *            description of the model to apply to editing
51
	 * @param dataBindingContext
52
	 *            context to use when binding
53
	 */
54
	public TableViewerEditorManager(TableViewer tableViewer,
55
			TableModelDescription tableModelDescription,
56
			DataBindingContext dataBindingContext) {
57
		if (tableViewer == null) {
58
			throw new NullPointerException(
59
					"Parameter " + tableViewer + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
60
		}
61
		if (tableModelDescription == null) {
62
			throw new NullPointerException(
63
					"Parameter " + tableModelDescription + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
64
		}
65
		if (dataBindingContext == null) {
66
			throw new NullPointerException(
67
					"Parameter " + dataBindingContext + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
68
		}
69
70
		this.tableViewer = tableViewer;
71
		this.tableModelDescription = tableModelDescription;
72
		this.dataBindingContext = dataBindingContext;
73
74
		tableViewer.setCellModifier(new CellModifier(tableViewer));
75
76
		Object[] columnIDs = tableModelDescription.getColumnIDs();
77
		int columnCount = (columnIDs != null) ? columnIDs.length : 0;
78
79
		tableViewer.setCellEditors(new CellEditor[columnCount]);
80
81
		String[] properties = new String[columnCount];
82
		tableViewer.setColumnProperties(properties);
83
84
		for (int i = 0; i < columnCount; i++) {
85
			properties[i] = columnIDs[i].toString();
86
		}
87
	}
88
89
	/**
90
	 * @return Returns the dataBindingContext.
91
	 */
92
	public DataBindingContext getDataBindingContext() {
93
		return dataBindingContext;
94
	}
95
96
	/**
97
	 * @return Returns the tableModelDescription.
98
	 */
99
	public TableModelDescription getTableModelDescription() {
100
		return tableModelDescription;
101
	}
102
103
	/**
104
	 * @return Returns the tableViewer.
105
	 */
106
	public TableViewer getTableViewer() {
107
		return tableViewer;
108
	}
109
110
	/**
111
	 * ICellModifier implementation that mostly ignores it's duty of being the
112
	 * translator between an editor on the value being edited. The binding
113
	 * framework takes place of the ICellModifier but editing can't occur in
114
	 * viewers without an ICellModifier.
115
	 * 
116
	 * @since 3.3
117
	 */
118
	private static class CellModifier implements ICellModifier {
119
		private final TableViewer viewer;
120
121
		private CellModifier(TableViewer viewer) {
122
			this.viewer = viewer;
123
		}
124
125
		/**
126
		 * Returns the editor for the property.
127
		 * 
128
		 * @param property
129
		 * @return editor, <code>null</code> if not found
130
		 */
131
		private CellEditor getEditor(String property) {
132
			Assert.isNotNull(property);
133
134
			if (property == null)
135
				return null;
136
137
			CellEditor editor = null;
138
			Object[] properties = viewer.getColumnProperties();
139
			for (int i = 0; i < properties.length; i++) {
140
				if (property.equals(properties[i])) {
141
					editor = viewer.getCellEditors()[i];
142
					break;
143
				}
144
			}
145
			return editor;
146
		}
147
148
		/*
149
		 * (non-Javadoc)
150
		 * 
151
		 * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object,
152
		 *      java.lang.String)
153
		 */
154
		public boolean canModify(Object element, String property) {
155
			return getEditor(property) != null;
156
		}
157
158
		/*
159
		 * (non-Javadoc)
160
		 * 
161
		 * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object,
162
		 *      java.lang.String)
163
		 */
164
		public Object getValue(Object element, String property) {
165
			/*
166
			 * this is a workaround. if we return null the CellEditor will throw
167
			 * an exception. the binding framework will set the appropriate
168
			 * value after this method is invoked.
169
			 */
170
			CellEditor editor = getEditor(property);
171
172
			Assert.isTrue(editor != null);
173
174
			return editor.getValue();
175
		}
176
177
		/*
178
		 * (non-Javadoc)
179
		 * 
180
		 * @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object,
181
		 *      java.lang.String, java.lang.Object)
182
		 */
183
		public void modify(Object element, String property, Object value) {
184
			// modifies are handled by the binding framework
185
		}
186
	}
187
188
	/**
189
	 * Assigns an editor to the viewer.
190
	 * 
191
	 * @param cellEditor
192
	 * @param columnID
193
	 *            value that corresponds to the column specified in the
194
	 *            TableModelDescription
195
	 * @param columnIDType
196
	 *            type of the attribute to bind the editor to
197
	 * @param bindSpec
198
	 *            spec that contains validators, converters, etc. to employ when
199
	 *            updating the observables, can be <code>null</code>.
200
	 * @return binding
201
	 * @throws IllegalArgumentException
202
	 *             if the columnID is not found in the TableModelDescription's
203
	 *             columnIDs.
204
	 */
205
	public Binding bind(CellEditor cellEditor, Object columnID,
206
			Class columnIDType, BindSpec bindSpec) {
207
		if (cellEditor == null) {
208
			throw new NullPointerException(
209
					"Parameter " + cellEditor + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
210
		}
211
		if (columnID == null) {
212
			throw new NullPointerException(
213
					"Parameter " + columnID + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
214
		}
215
		if (columnIDType == null) {
216
			throw new NullPointerException(
217
					"Parameter " + columnIDType + " was null."); //$NON-NLS-1$ //$NON-NLS-2$
218
		}
219
220
		int columnIndex = -1;
221
		Object[] columnIDs = tableModelDescription.getColumnIDs();
222
		for (int i = 0; columnIndex == -1 && i < columnIDs.length; i++) {
223
			if (columnID.equals(columnIDs[i])) {
224
				columnIndex = i;
225
			}
226
		}
227
228
		if (columnIndex == -1) {
229
			throw new IllegalArgumentException(
230
					"Column with ID [" + columnID + "] not found in TableModelDescription."); //$NON-NLS-1$//$NON-NLS-2$
231
		}
232
233
		tableViewer.getCellEditors()[columnIndex] = cellEditor;
234
235
		if (selectionObservable == null) {
236
			selectionObservable = dataBindingContext
237
					.createObservable(new Property(tableViewer,
238
							ViewersProperties.SINGLE_SELECTION));
239
			Assert.isNotNull(selectionObservable);
240
		}
241
242
		if (cellEditor.getControl() == null) {
243
			cellEditor.create(tableViewer.getTable());
244
		}
245
246
		return dataBindingContext.bind(cellEditor, new Property(
247
				selectionObservable, columnID, columnIDType, Boolean.FALSE),
248
				bindSpec);
249
	}
250
251
	/**
252
	 * @return Returns the viewerSelectionObservable.
253
	 */
254
	public IObservable getSelectionObservable() {
255
		return selectionObservable;
256
	}
257
}
(-)src/org/eclipse/jface/tests/databinding/scenarios/TableScenarios.java (-300 / +473 lines)
Lines 10-27 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.jface.tests.databinding.scenarios;
11
package org.eclipse.jface.tests.databinding.scenarios;
12
12
13
import java.util.ArrayList;
14
import java.util.List;
15
13
import org.eclipse.jface.examples.databinding.model.Account;
16
import org.eclipse.jface.examples.databinding.model.Account;
14
import org.eclipse.jface.examples.databinding.model.Catalog;
17
import org.eclipse.jface.examples.databinding.model.Catalog;
15
import org.eclipse.jface.examples.databinding.model.Category;
18
import org.eclipse.jface.examples.databinding.model.Category;
16
import org.eclipse.jface.examples.databinding.model.SampleData;
19
import org.eclipse.jface.examples.databinding.model.SampleData;
17
import org.eclipse.jface.internal.databinding.provisional.description.Property;
20
import org.eclipse.jface.internal.databinding.provisional.description.Property;
18
import org.eclipse.jface.internal.databinding.provisional.description.TableModelDescription;
21
import org.eclipse.jface.internal.databinding.provisional.description.TableModelDescription;
22
import org.eclipse.jface.internal.databinding.provisional.observable.list.AbstractObservableList;
23
import org.eclipse.jface.internal.databinding.provisional.viewers.TableViewerEditorManager;
19
import org.eclipse.jface.viewers.ITableLabelProvider;
24
import org.eclipse.jface.viewers.ITableLabelProvider;
25
import org.eclipse.jface.viewers.StructuredSelection;
20
import org.eclipse.jface.viewers.TableViewer;
26
import org.eclipse.jface.viewers.TableViewer;
27
import org.eclipse.jface.viewers.TextCellEditor;
21
import org.eclipse.swt.SWT;
28
import org.eclipse.swt.SWT;
22
import org.eclipse.swt.graphics.Image;
29
import org.eclipse.swt.graphics.Image;
23
import org.eclipse.swt.layout.FillLayout;
30
import org.eclipse.swt.layout.FillLayout;
31
import org.eclipse.swt.widgets.Event;
24
import org.eclipse.swt.widgets.TableColumn;
32
import org.eclipse.swt.widgets.TableColumn;
33
import org.eclipse.swt.widgets.Text;
25
34
26
/**
35
/**
27
 * To run the tests in this class, right-click and select "Run As JUnit Plug-in
36
 * To run the tests in this class, right-click and select "Run As JUnit Plug-in
Lines 35-41 Link Here
35
	private TableViewer tableViewer;
44
	private TableViewer tableViewer;
36
45
37
	private Catalog catalog;
46
	private Catalog catalog;
38
	
47
39
	private Category category;
48
	private Category category;
40
49
41
	private TableColumn firstNameColumn;
50
	private TableColumn firstNameColumn;
Lines 57-70 Link Here
57
		firstNameColumn = new TableColumn(tableViewer.getTable(), SWT.NONE);
66
		firstNameColumn = new TableColumn(tableViewer.getTable(), SWT.NONE);
58
		firstNameColumn.setWidth(50);
67
		firstNameColumn.setWidth(50);
59
		lastNameColumn = new TableColumn(tableViewer.getTable(), SWT.NONE);
68
		lastNameColumn = new TableColumn(tableViewer.getTable(), SWT.NONE);
60
		lastNameColumn.setWidth(50);		
69
		lastNameColumn.setWidth(50);
61
		stateColumn = new TableColumn(tableViewer.getTable(), SWT.NONE);
70
		stateColumn = new TableColumn(tableViewer.getTable(), SWT.NONE);
62
		stateColumn.setWidth(50);		
71
		stateColumn.setWidth(50);
63
		fancyColumn = new TableColumn(tableViewer.getTable(), SWT.NONE);
72
		fancyColumn = new TableColumn(tableViewer.getTable(), SWT.NONE);
64
		fancyColumn.setWidth(250);		
73
		fancyColumn.setWidth(250);
65
74
66
		catalog = SampleData.CATALOG_2005; // Lodging source
75
		catalog = SampleData.CATALOG_2005; // Lodging source
67
		category = SampleData.WINTER_CATEGORY; 
76
		category = SampleData.WINTER_CATEGORY;
68
77
69
		images = new Image[] {
78
		images = new Image[] {
70
				getShell().getDisplay().getSystemImage(SWT.ICON_ERROR),
79
				getShell().getDisplay().getSystemImage(SWT.ICON_ERROR),
Lines 83-106 Link Here
83
	}
92
	}
84
93
85
	private String getValue(String text) {
94
	private String getValue(String text) {
86
		if (text==null)
95
		if (text == null)
87
			return "";
96
			return "";
88
		return text;
97
		return text;
89
	}
98
	}
90
	
99
91
	public void testScenario01() {
100
	public void testScenario01() {
92
		// Show that a TableViewer with three columns renders the accounts
101
		// Show that a TableViewer with three columns renders the accounts
93
		Account[] accounts = catalog.getAccounts();
102
		Account[] accounts = catalog.getAccounts();
94
103
95
		TableModelDescription tableModelDescription = new TableModelDescription(new Property(catalog, "accounts"),new String[]{"firstName","lastName","state"});
104
		TableModelDescription tableModelDescription = new TableModelDescription(
96
		getDbc().bind(tableViewer,
105
				new Property(catalog, "accounts"), new String[] { "firstName",
97
				tableModelDescription, null);
106
						"lastName", "state" });
107
		getDbc().bind(tableViewer, tableModelDescription, null);
98
108
99
		// Verify the data in the table columns matches the accounts
109
		// Verify the data in the table columns matches the accounts
100
		for (int i = 0; i < accounts.length; i++) {
110
		for (int i = 0; i < accounts.length; i++) {
101
			Account account = catalog.getAccounts()[i];
111
			Account account = catalog.getAccounts()[i];
102
			String col_0 = ((ITableLabelProvider) tableViewer
112
			String col_0 = ((ITableLabelProvider) tableViewer
103
					.getLabelProvider()).getColumnText(account, 0); 
113
					.getLabelProvider()).getColumnText(account, 0);
104
			assertEquals(getValue(account.getFirstName()), col_0);
114
			assertEquals(getValue(account.getFirstName()), col_0);
105
			String col_1 = ((ITableLabelProvider) tableViewer
115
			String col_1 = ((ITableLabelProvider) tableViewer
106
					.getLabelProvider()).getColumnText(account, 1);
116
					.getLabelProvider()).getColumnText(account, 1);
Lines 112-412 Link Here
112
		}
122
		}
113
	}
123
	}
114
124
115
	public void testScenario02() throws SecurityException, IllegalArgumentException {
125
	public void testEditColumnWithTextCellEditor() throws Exception {
126
		TableModelDescription description = new TableModelDescription(
127
				new Property(catalog, "accounts", Account.class, Boolean.TRUE),
128
				new String[] { "firstName", "lastName" });
129
130
		getDbc().bind(tableViewer, description, null);
131
132
		TableViewerEditorManager manager = new TableViewerEditorManager(
133
				tableViewer, description, getDbc());
134
		TextCellEditor editor = new TextCellEditor();
135
		manager.bind(editor, "firstName", String.class, null);
136
137
		Account account = catalog.getAccounts()[0];
138
		String originalValue = account.getFirstName();
139
140
		tableViewer.editElement(account, 0);
141
		assertEquals(account,
142
				((StructuredSelection) tableViewer.getSelection())
143
						.getFirstElement());
144
145
		String newValue = editor.getValue().toString() + ","
146
				+ editor.getValue().toString();
147
		editor.setValue(newValue);
148
149
		// Value shouldn't yet change
150
		assertEquals(originalValue, account.getFirstName());
151
152
		getShell().open();
153
154
		// Apply value
155
		Text text = (Text) editor.getControl();
156
		Event event = new Event();
157
		event.detail = SWT.TRAVERSE_RETURN;
158
		text.notifyListeners(SWT.Traverse, event);
159
		tableViewer.getTable().setFocus();
160
161
		assertEquals(newValue, account.getFirstName());
162
	}
163
164
	public void testCancelEditOfTextCellEditor() throws Exception {
165
		TableModelDescription description = new TableModelDescription(
166
				new Property(catalog, "accounts", Account.class, Boolean.TRUE),
167
				new String[] { "firstName", "lastName" });
168
169
		getDbc().bind(tableViewer, description, null);
170
171
		TableViewerEditorManager manager = new TableViewerEditorManager(
172
				tableViewer, description, getDbc());
173
		TextCellEditor editor = new TextCellEditor();
174
		manager.bind(editor, "firstName", String.class, null);
175
176
		Account account = catalog.getAccounts()[0];
177
		String originalValue = account.getFirstName();
178
179
		tableViewer.editElement(account, 0);
180
		assertEquals(account,
181
				((StructuredSelection) tableViewer.getSelection())
182
						.getFirstElement());
183
184
		String newValue = editor.getValue().toString() + ","
185
				+ editor.getValue().toString();
186
		editor.setValue(newValue);
187
188
		// Value shouldn't yet change
189
		assertEquals(originalValue, account.getFirstName());
190
191
		// Aborts the edit
192
		tableViewer.getTable().setFocus();
193
194
		assertEquals(originalValue, account.getFirstName());
195
	}
196
197
	private class ObservableList extends AbstractObservableList {
198
		private List list;
199
200
		private Object elementType;
201
202
		private ObservableList(Object elementType) {
203
			list = new ArrayList();
204
			this.elementType = elementType;
205
		}
206
207
		/*
208
		 * (non-Javadoc)
209
		 * 
210
		 * @see org.eclipse.jface.internal.databinding.provisional.observable.list.AbstractObservableList#add(java.lang.Object)
211
		 */
212
		public boolean add(Object o) {
213
			return list.add(o);
214
		}
215
216
		/*
217
		 * (non-Javadoc)
218
		 * 
219
		 * @see org.eclipse.jface.internal.databinding.provisional.observable.list.AbstractObservableList#doGetSize()
220
		 */
221
		protected int doGetSize() {
222
			return list.size();
223
		}
224
225
		/*
226
		 * (non-Javadoc)
227
		 * 
228
		 * @see java.util.AbstractList#get(int)
229
		 */
230
		public Object get(int index) {
231
			return list.get(index);
232
		}
233
234
		/*
235
		 * (non-Javadoc)
236
		 * 
237
		 * @see org.eclipse.jface.internal.databinding.provisional.observable.list.IObservableList#getElementType()
238
		 */
239
		public Object getElementType() {
240
			return elementType;
241
		}
242
	}
243
244
	public void testScenario02() throws SecurityException,
245
			IllegalArgumentException {
116
		// Show that a TableViewer with three columns can be used to update
246
		// Show that a TableViewer with three columns can be used to update
117
		// columns
247
		// columns
118
//		Account[] accounts = catalog.getAccounts();
248
		// Account[] accounts = catalog.getAccounts();
119
//
249
		//
120
//		TableModelDescription tableModelDescription = new TableModelDescription(new Property(catalog, "accounts"), new String[]{"firstName","lastName","state"});
250
		// TableModelDescription tableModelDescription = new
121
////		tableViewerDescription.addEditableColumn("firstName");
251
		// TableModelDescription(new
122
////		tableViewerDescription.addEditableColumn("lastName", null, null, new PhoneConverter());
252
		// Property(catalog, "accounts"), new
123
////		tableViewerDescription.addEditableColumn("state", null, null, new StateConverter());
253
		// String[]{"firstName","lastName","state"});
124
//		getDbc().bind(tableViewer,
254
		// // tableViewerDescription.addEditableColumn("firstName");
125
//				tableModelDescription, null);
255
		// // tableViewerDescription.addEditableColumn("lastName", null, null,
126
//
256
		// new
127
//		Account account = accounts[0];
257
		// PhoneConverter());
128
//		// Select the first item in the table
258
		// // tableViewerDescription.addEditableColumn("state", null, null, new
129
//		tableViewer.editElement(account, 0);
259
		// StateConverter());
130
//		// Set the text property of the cell editor which is now active over the "firstName" column
260
		// getDbc().bind(tableViewer,
131
//		CellEditor[] cellEditors = tableViewer.getCellEditors();
261
		// tableModelDescription, null);
132
//		TextCellEditor firstNameEditor = (TextCellEditor) cellEditors[0];
262
		//
133
//		// Change the firstName and test it goes to the model
263
		// Account account = accounts[0];
134
//		enterText((Text) firstNameEditor.getControl(), "Bill");
264
		// // Select the first item in the table
135
//		// Check whether the model has changed
265
		// tableViewer.editElement(account, 0);
136
//		assertEquals("Bill",account.getFirstName());
266
		// // Set the text property of the cell editor which is now active over
267
		// the
268
		// "firstName" column
269
		// CellEditor[] cellEditors = tableViewer.getCellEditors();
270
		// TextCellEditor firstNameEditor = (TextCellEditor) cellEditors[0];
271
		// // Change the firstName and test it goes to the model
272
		// enterText((Text) firstNameEditor.getControl(), "Bill");
273
		// // Check whether the model has changed
274
		// assertEquals("Bill",account.getFirstName());
137
	}
275
	}
138
	
276
139
	public void testScenario04() {
277
	public void testScenario04() {
140
//		// Show that when an item is added to a collection the table gets an extra item
278
		// // Show that when an item is added to a collection the table gets an
141
//		Account[] accounts = catalog.getAccounts();	
279
		// extra
142
//		
280
		// item
143
//		TableViewerDescription tableViewerDescription = new TableViewerDescription(
281
		// Account[] accounts = catalog.getAccounts();
144
//				tableViewer);
282
		//		
145
//		tableViewerDescription.addColumn("firstName");
283
		// TableViewerDescription tableViewerDescription = new
146
//		tableViewerDescription.addColumn("lastName");
284
		// TableViewerDescription(
147
//		tableViewerDescription.addColumn("state");
285
		// tableViewer);
148
//		tableViewerDescription.addColumn(null,new IConverter(){
286
		// tableViewerDescription.addColumn("firstName");
149
//			
287
		// tableViewerDescription.addColumn("lastName");
150
//			public Class getModelType() {
288
		// tableViewerDescription.addColumn("state");
151
//				return Account.class;
289
		// tableViewerDescription.addColumn(null,new IConverter(){
152
//			}
290
		//			
153
//			
291
		// public Class getModelType() {
154
//			public Class getTargetType() {
292
		// return Account.class;
155
//				return ViewerLabel.class;
293
		// }
156
//			}
294
		//			
157
//			
295
		// public Class getTargetType() {
158
//			public Object convertTargetToModel(Object targetObject) {
296
		// return ViewerLabel.class;
159
//				return null;
297
		// }
160
//			}
298
		//			
161
//			
299
		// public Object convertTargetToModel(Object targetObject) {
162
//			public Object convertModelToTarget(Object modelObject) {
300
		// return null;
163
//				Account account = (Account) modelObject;
301
		// }
164
//				return new ViewerLabel(account.toString(), images[new Random().nextInt(images.length)]);
302
		//			
165
//			}});
303
		// public Object convertModelToTarget(Object modelObject) {
166
//		getDbc().bind(tableViewerDescription,
304
		// Account account = (Account) modelObject;
167
//				new Property(catalog, "accounts"), null);
305
		// return new ViewerLabel(account.toString(), images[new
168
//
306
		// Random().nextInt(images.length)]);
169
//		//interact();
307
		// }});
170
//		
308
		// getDbc().bind(tableViewerDescription,
171
//		// Verify the number of accounts matches the number of items in the table
309
		// new Property(catalog, "accounts"), null);
172
//		assertEquals(tableViewer.getTable().getItemCount(),accounts.length);
310
		//
173
//		// Add a new account and verify that the number of items in the table increases
311
		// //interact();
174
//		Account newAccount = new Account();
312
		//		
175
//		newAccount.setFirstName("Finbar");
313
		// // Verify the number of accounts matches the number of items in the
176
//		newAccount.setLastName("McGoo");
314
		// table
177
//		newAccount.setLastName("NC");
315
		// assertEquals(tableViewer.getTable().getItemCount(),accounts.length);
178
//		catalog.addAccount(newAccount);
316
		// // Add a new account and verify that the number of items in the table
179
//		// The number of items should have gone up by one
317
		// increases
180
//		assertEquals(tableViewer.getTable().getItemCount(),accounts.length + 1);
318
		// Account newAccount = new Account();
181
//		// The number of items should still match the number of accounts (i.e. test the model)
319
		// newAccount.setFirstName("Finbar");
182
//		assertEquals(tableViewer.getTable().getItemCount(),catalog.getAccounts().length);
320
		// newAccount.setLastName("McGoo");
183
//		// Remove the account that was just added
321
		// newAccount.setLastName("NC");
184
//		catalog.removeAccount(newAccount);
322
		// catalog.addAccount(newAccount);
185
//		// The number of items should match the original
323
		// // The number of items should have gone up by one
186
//		assertEquals(tableViewer.getTable().getItemCount(),accounts.length);
324
		// assertEquals(tableViewer.getTable().getItemCount(),accounts.length +
187
//		// The number of items should still match the number of accounts (i.e. test the model is reset)
325
		// 1);
188
//		assertEquals(tableViewer.getTable().getItemCount(),catalog.getAccounts().length);		
326
		// // The number of items should still match the number of accounts
189
//		
327
		// (i.e. test
190
//		// Test adding and removing to the model on a non UI thread
328
		// the model)
191
//		int numberOfAccounts = catalog.getAccounts().length;
329
		// assertEquals(tableViewer.getTable().getItemCount(),catalog.getAccounts().length);
192
//		final Account barney = new Account();
330
		// // Remove the account that was just added
193
//		barney.setFirstName("Barney");
331
		// catalog.removeAccount(newAccount);
194
//		barney.setLastName("Smith");
332
		// // The number of items should match the original
195
//		barney.setLastName("CA");
333
		// assertEquals(tableViewer.getTable().getItemCount(),accounts.length);
196
//		invokeNonUI(new Runnable(){
334
		// // The number of items should still match the number of accounts
197
//			public void run(){
335
		// (i.e. test
198
//				catalog.addAccount(barney);
336
		// the model is reset)
199
//			}
337
		// assertEquals(tableViewer.getTable().getItemCount(),catalog.getAccounts().length);
200
//		});
338
		//		
201
//		spinEventLoop(0);
339
		// // Test adding and removing to the model on a non UI thread
202
//		// The number of items should have gone up by one		
340
		// int numberOfAccounts = catalog.getAccounts().length;
203
//		assertEquals(tableViewer.getTable().getItemCount(),numberOfAccounts + 1);
341
		// final Account barney = new Account();
204
//		
342
		// barney.setFirstName("Barney");
205
//		invokeNonUI(new Runnable(){
343
		// barney.setLastName("Smith");
206
//			public void run(){
344
		// barney.setLastName("CA");
207
//				catalog.removeAccount(barney);
345
		// invokeNonUI(new Runnable(){
208
//			}
346
		// public void run(){
209
//		});
347
		// catalog.addAccount(barney);
210
//		spinEventLoop(0);
348
		// }
211
//		// The number of items should have reverted to the original number before barney was added and removed		
349
		// });
212
//		assertEquals(tableViewer.getTable().getItemCount(),numberOfAccounts);
350
		// spinEventLoop(0);
213
//		
351
		// // The number of items should have gone up by one
352
		// assertEquals(tableViewer.getTable().getItemCount(),numberOfAccounts +
353
		// 1);
354
		//		
355
		// invokeNonUI(new Runnable(){
356
		// public void run(){
357
		// catalog.removeAccount(barney);
358
		// }
359
		// });
360
		// spinEventLoop(0);
361
		// // The number of items should have reverted to the original number
362
		// before
363
		// barney was added and removed
364
		// assertEquals(tableViewer.getTable().getItemCount(),numberOfAccounts);
365
		//		
214
	}
366
	}
215
		
367
216
	public void testScenario03() {
368
	public void testScenario03() {
217
//		// Show that converters work for table columns
369
		// // Show that converters work for table columns
218
//		Account[] accounts = catalog.getAccounts();
370
		// Account[] accounts = catalog.getAccounts();
219
//
371
		//
220
//		TableViewerDescription tableViewerDescription = new TableViewerDescription(
372
		// TableViewerDescription tableViewerDescription = new
221
//				tableViewer);
373
		// TableViewerDescription(
222
//		tableViewerDescription.addEditableColumn("lastName");
374
		// tableViewer);
223
//		tableViewerDescription.addEditableColumn("phone", null, null ,
375
		// tableViewerDescription.addEditableColumn("lastName");
224
//				new PhoneConverter());
376
		// tableViewerDescription.addEditableColumn("phone", null, null ,
225
//		tableViewerDescription.addEditableColumn("state", null, null ,
377
		// new PhoneConverter());
226
//				new StateConverter());
378
		// tableViewerDescription.addEditableColumn("state", null, null ,
227
//		getDbc().bind(tableViewerDescription,
379
		// new StateConverter());
228
//				new Property(catalog, "accounts"), null);
380
		// getDbc().bind(tableViewerDescription,
229
//
381
		// new Property(catalog, "accounts"), null);
230
//		// Verify that the data in the the table columns matches the expected
382
		//
231
//		// What we are looking for is that the phone numbers are converterted to
383
		// // Verify that the data in the the table columns matches the expected
232
//		// nnn-nnn-nnnn and that
384
		// // What we are looking for is that the phone numbers are converterted
233
//		// the state letters are converted to state names
385
		// to
234
//		// Verify the data in the table columns matches the accounts
386
		// // nnn-nnn-nnnn and that
235
//		PhoneConverter phoneConverter = new PhoneConverter();
387
		// // the state letters are converted to state names
236
//		StateConverter stateConverter = new StateConverter();
388
		// // Verify the data in the table columns matches the accounts
237
//		for (int i = 0; i < accounts.length; i++) {
389
		// PhoneConverter phoneConverter = new PhoneConverter();
238
//			Account account = catalog.getAccounts()[i];
390
		// StateConverter stateConverter = new StateConverter();
239
//			// Check the phone number
391
		// for (int i = 0; i < accounts.length; i++) {
240
//			String col_phone = ((ITableLabelProvider) tableViewer
392
		// Account account = catalog.getAccounts()[i];
241
//					.getLabelProvider()).getColumnText(account, 1);
393
		// // Check the phone number
242
//			assertEquals(getValue((String)phoneConverter
394
		// String col_phone = ((ITableLabelProvider) tableViewer
243
//					.convertModelToTarget(account.getPhone())), col_phone);
395
		// .getLabelProvider()).getColumnText(account, 1);
244
//			String col_state = ((ITableLabelProvider) tableViewer
396
		// assertEquals(getValue((String)phoneConverter
245
//					.getLabelProvider()).getColumnText(account, 2);
397
		// .convertModelToTarget(account.getPhone())), col_phone);
246
//			assertEquals(getValue((String)stateConverter
398
		// String col_state = ((ITableLabelProvider) tableViewer
247
//					.convertModelToTarget(account.getState())), col_state);
399
		// .getLabelProvider()).getColumnText(account, 2);
248
//		}
400
		// assertEquals(getValue((String)stateConverter
401
		// .convertModelToTarget(account.getState())), col_state);
402
		// }
249
	}
403
	}
250
	
404
251
	public void testScenario05() {
405
	public void testScenario05() {
252
//		// Show that when the model changes then the UI refreshes to reflect this
406
		// // Show that when the model changes then the UI refreshes to reflect
253
//
407
		// this
254
//		TableViewerDescription tableViewerDescription = new TableViewerDescription(
408
		//
255
//				tableViewer);
409
		// TableViewerDescription tableViewerDescription = new
256
//		tableViewerDescription.addColumn("lastName");
410
		// TableViewerDescription(
257
//		tableViewerDescription.addColumn("phone",
411
		// tableViewer);
258
//				new PhoneConverter());
412
		// tableViewerDescription.addColumn("lastName");
259
//		tableViewerDescription.addColumn("state",
413
		// tableViewerDescription.addColumn("phone",
260
//				new StateConverter());
414
		// new PhoneConverter());
261
//		getDbc().bind(tableViewerDescription,
415
		// tableViewerDescription.addColumn("state",
262
//				new Property(catalog, "accounts"), null);
416
		// new StateConverter());
263
//		
417
		// getDbc().bind(tableViewerDescription,
264
//		final Account account = catalog.getAccounts()[0];
418
		// new Property(catalog, "accounts"), null);
265
//		String lastName = tableViewer.getTable().getItem(0).getText(0);
419
		//		
266
//		// Check the firstName in the TableItem is the same as the model
420
		// final Account account = catalog.getAccounts()[0];
267
//		assertEquals(lastName,account.getLastName());
421
		// String lastName = tableViewer.getTable().getItem(0).getText(0);
268
//		// Now change the model and check again
422
		// // Check the firstName in the TableItem is the same as the model
269
//		account.setLastName("Gershwin");
423
		// assertEquals(lastName,account.getLastName());
270
//		lastName = tableViewer.getTable().getItem(0).getText(0);	
424
		// // Now change the model and check again
271
//		assertEquals(lastName,account.getLastName());	
425
		// account.setLastName("Gershwin");
272
//		
426
		// lastName = tableViewer.getTable().getItem(0).getText(0);
273
//		// Test the model update on a non UI thread
427
		// assertEquals(lastName,account.getLastName());
274
//		invokeNonUI(new Runnable(){
428
		//		
275
//			public void run(){
429
		// // Test the model update on a non UI thread
276
//				account.setLastName("Mozart");				
430
		// invokeNonUI(new Runnable(){
277
//			}
431
		// public void run(){
278
//		});
432
		// account.setLastName("Mozart");
279
//		spinEventLoop(0);
433
		// }
280
//		lastName = tableViewer.getTable().getItem(0).getText(0);		
434
		// });
281
//		assertEquals(lastName,account.getLastName());
435
		// spinEventLoop(0);
282
//		
436
		// lastName = tableViewer.getTable().getItem(0).getText(0);
283
	}
437
		// assertEquals(lastName,account.getLastName());
284
	
438
		//		
285
	public void testScenario06(){
439
	}
286
//		// Check that explicit type means that defaulting of converters works
440
287
//		TableViewerDescription tableViewerDescription = new TableViewerDescription(
441
	public void testScenario06() {
288
//				tableViewer);
442
		// // Check that explicit type means that defaulting of converters works
289
//		tableViewerDescription.addEditableColumn("price");
443
		// TableViewerDescription tableViewerDescription = new
290
//		tableViewerDescription.getColumn(0).setPropertyType(Double.TYPE);
444
		// TableViewerDescription(
291
//		getDbc().bind(tableViewerDescription,
445
		// tableViewer);
292
//				new Property(catalog, "transporations"), null);
446
		// tableViewerDescription.addEditableColumn("price");
293
//		Transportation transporation = catalog.getTransporations()[0];
447
		// tableViewerDescription.getColumn(0).setPropertyType(Double.TYPE);
294
//		tableViewer.editElement(transporation, 0);
448
		// getDbc().bind(tableViewerDescription,
295
//		// Set the text property of the cell editor which is now active over the "firstName" column
449
		// new Property(catalog, "transporations"), null);
296
//		CellEditor[] cellEditors = tableViewer.getCellEditors();
450
		// Transportation transporation = catalog.getTransporations()[0];
297
//		TextCellEditor priceEditor = (TextCellEditor) cellEditors[0];
451
		// tableViewer.editElement(transporation, 0);
298
//		// Change the firstName and test it goes to the model
452
		// // Set the text property of the cell editor which is now active over
299
//		enterText((Text) priceEditor.getControl(), "123.45");
453
		// the
300
//		// Verify the model is updated
454
		// "firstName" column
301
//		assertEquals(transporation.getPrice(),123.45,0);
455
		// CellEditor[] cellEditors = tableViewer.getCellEditors();
302
		
456
		// TextCellEditor priceEditor = (TextCellEditor) cellEditors[0];
303
	}
457
		// // Change the firstName and test it goes to the model
304
	
458
		// enterText((Text) priceEditor.getControl(), "123.45");
305
	public void testScenario07(){
459
		// // Verify the model is updated
306
//		// Verify that even when a column's property type is not set, that it is worked out lazily from the target type 
460
		// assertEquals(transporation.getPrice(),123.45,0);
307
//		TableViewerDescription tableViewerDescription = new TableViewerDescription(
461
308
//				tableViewer);
462
	}
309
//		tableViewerDescription.addEditableColumn("price");
463
310
//		// The column's type is not set to be Double.TYPE.  This will be inferred once the first Transportation object is set
464
	public void testScenario07() {
311
//		// into the ObservableCollection
465
		// // Verify that even when a column's property type is not set, that it
312
//		getDbc().bind(tableViewerDescription,
466
		// is
313
//				new Property(catalog, "transporations"), null);
467
		// worked out lazily from the target type
314
//		Transportation transporation = catalog.getTransporations()[0];
468
		// TableViewerDescription tableViewerDescription = new
315
//		tableViewer.editElement(transporation, 0);
469
		// TableViewerDescription(
316
//		// Set the text property of the cell editor which is now active over the "firstName" column
470
		// tableViewer);
317
//		CellEditor[] cellEditors = tableViewer.getCellEditors();
471
		// tableViewerDescription.addEditableColumn("price");
318
//		TextCellEditor priceEditor = (TextCellEditor) cellEditors[0];
472
		// // The column's type is not set to be Double.TYPE. This will be
319
//		// Change the firstName and test it goes to the model
473
		// inferred once
320
//		enterText((Text) priceEditor.getControl(), "123.45");
474
		// the first Transportation object is set
321
//		// Verify the model is updated
475
		// // into the ObservableCollection
322
//		assertEquals(transporation.getPrice(),123.45,0);
476
		// getDbc().bind(tableViewerDescription,
323
//		
477
		// new Property(catalog, "transporations"), null);
324
	}
478
		// Transportation transporation = catalog.getTransporations()[0];
325
	
479
		// tableViewer.editElement(transporation, 0);
326
	public void testScenario08_00(){
480
		// // Set the text property of the cell editor which is now active over
327
//		// Verify that binding to a Collection property (rather than an array) works when specifying data type
481
		// the
328
//		TableViewerDescription tableViewerDescription = new TableViewerDescription(
482
		// "firstName" column
329
//				tableViewer);
483
		// CellEditor[] cellEditors = tableViewer.getCellEditors();
330
//		tableViewerDescription.addEditableColumn("userId");
484
		// TextCellEditor priceEditor = (TextCellEditor) cellEditors[0];
331
//		tableViewerDescription.addEditableColumn("password");	
485
		// // Change the firstName and test it goes to the model
332
//		getDbc().bind(tableViewerDescription,
486
		// enterText((Text) priceEditor.getControl(), "123.45");
333
//				new Property(catalog, "signons", Signon.class, null), null);	
487
		// // Verify the model is updated
334
//		Signon firstSignon = (Signon) catalog.getSignons().get(0);	
488
		// assertEquals(transporation.getPrice(),123.45,0);
335
//		// Verify the UI matches the model
489
		//		
336
//		TableItem firstTableItem = tableViewer.getTable().getItem(0);
490
	}
337
//		assertEquals(firstTableItem.getText(1),firstSignon.getPassword());
491
338
//		// Change the model and ensure the UI refreshes
492
	public void testScenario08_00() {
339
//		firstSignon.setPassword("Eclipse123Rocks");
493
		// // Verify that binding to a Collection property (rather than an
340
//		assertEquals("Eclipse123Rocks",firstSignon.getPassword());		
494
		// array) works
341
//		assertEquals(firstTableItem.getText(1),firstSignon.getPassword());
495
		// when specifying data type
342
//		// Change the GUI and ensure the model refreshes
496
		// TableViewerDescription tableViewerDescription = new
343
//		tableViewer.editElement(firstSignon, 1);
497
		// TableViewerDescription(
344
//		CellEditor[] cellEditors = tableViewer.getCellEditors();
498
		// tableViewer);
345
//		TextCellEditor passwordEditor = (TextCellEditor) cellEditors[1];
499
		// tableViewerDescription.addEditableColumn("userId");
346
//		enterText((Text) passwordEditor.getControl(), "Cricket11Players");
500
		// tableViewerDescription.addEditableColumn("password");
347
//		assertEquals("Cricket11Players",firstSignon.getPassword());
501
		// getDbc().bind(tableViewerDescription,
348
//		
502
		// new Property(catalog, "signons", Signon.class, null), null);
349
	}
503
		// Signon firstSignon = (Signon) catalog.getSignons().get(0);
350
	
504
		// // Verify the UI matches the model
351
	public void testScenario08_01(){
505
		// TableItem firstTableItem = tableViewer.getTable().getItem(0);
352
//		// Verify that binding to a Collection property (rather than an array) works without specifying data type
506
		// assertEquals(firstTableItem.getText(1),firstSignon.getPassword());
353
//		TableViewerDescription tableViewerDescription = new TableViewerDescription(
507
		// // Change the model and ensure the UI refreshes
354
//				tableViewer);
508
		// firstSignon.setPassword("Eclipse123Rocks");
355
//		tableViewerDescription.addEditableColumn("userId");
509
		// assertEquals("Eclipse123Rocks",firstSignon.getPassword());
356
//		tableViewerDescription.addEditableColumn("password");	
510
		// assertEquals(firstTableItem.getText(1),firstSignon.getPassword());
357
//		getDbc().bind(tableViewerDescription,
511
		// // Change the GUI and ensure the model refreshes
358
//				new Property(catalog, "signons"), null);	
512
		// tableViewer.editElement(firstSignon, 1);
359
//		Signon firstSignon = (Signon) catalog.getSignons().get(0);	
513
		// CellEditor[] cellEditors = tableViewer.getCellEditors();
360
//		// Verify the UI matches the model
514
		// TextCellEditor passwordEditor = (TextCellEditor) cellEditors[1];
361
//		TableItem firstTableItem = tableViewer.getTable().getItem(0);
515
		// enterText((Text) passwordEditor.getControl(), "Cricket11Players");
362
//		assertEquals(firstTableItem.getText(1),firstSignon.getPassword());
516
		// assertEquals("Cricket11Players",firstSignon.getPassword());
363
//		// Change the model and ensure the UI refreshes
517
		//		
364
//		firstSignon.setPassword("Eclipse123Rocks");
518
	}
365
//		assertEquals("Eclipse123Rocks",firstSignon.getPassword());		
519
366
//		assertEquals(firstTableItem.getText(1),firstSignon.getPassword());
520
	public void testScenario08_01() {
367
//		// Change the GUI and ensure the model refreshes
521
		// // Verify that binding to a Collection property (rather than an
368
//		tableViewer.editElement(firstSignon, 1);
522
		// array) works
369
//		CellEditor[] cellEditors = tableViewer.getCellEditors();
523
		// without specifying data type
370
//		TextCellEditor passwordEditor = (TextCellEditor) cellEditors[1];
524
		// TableViewerDescription tableViewerDescription = new
371
//		enterText((Text) passwordEditor.getControl(), "Cricket11Players");
525
		// TableViewerDescription(
372
//		assertEquals("Cricket11Players",firstSignon.getPassword());
526
		// tableViewer);
373
//		
527
		// tableViewerDescription.addEditableColumn("userId");
374
	}
528
		// tableViewerDescription.addEditableColumn("password");
375
	
529
		// getDbc().bind(tableViewerDescription,
376
	public void testScenario09(){
530
		// new Property(catalog, "signons"), null);
377
//		// Verify that nested properties work.  Catalog has adventures.  Adventure has defaultLodging.  Loding has name.
531
		// Signon firstSignon = (Signon) catalog.getSignons().get(0);
378
//		TableViewerDescription tableViewerDescription = new TableViewerDescription(tableViewer);
532
		// // Verify the UI matches the model
379
//		tableViewerDescription.addColumn("name");
533
		// TableItem firstTableItem = tableViewer.getTable().getItem(0);
380
//		tableViewerDescription.addColumn("defaultLodging.name");
534
		// assertEquals(firstTableItem.getText(1),firstSignon.getPassword());
381
//		getDbc().bind(tableViewerDescription,new Property(category, "adventures"),null);
535
		// // Change the model and ensure the UI refreshes
382
//		
536
		// firstSignon.setPassword("Eclipse123Rocks");
383
	}
537
		// assertEquals("Eclipse123Rocks",firstSignon.getPassword());
384
/**	
538
		// assertEquals(firstTableItem.getText(1),firstSignon.getPassword());
385
	public void testScenario10(){
539
		// // Change the GUI and ensure the model refreshes
386
		// Verify that for TIME_EARLY updating occurs on a per key basic for a TextCellEditor
540
		// tableViewer.editElement(firstSignon, 1);
387
		// Show that converters work for table columns
541
		// CellEditor[] cellEditors = tableViewer.getCellEditors();
388
		Account[] accounts = catalog.getAccounts();
542
		// TextCellEditor passwordEditor = (TextCellEditor) cellEditors[1];
389
		Account firstAccount = accounts[0];
543
		// enterText((Text) passwordEditor.getControl(), "Cricket11Players");
390
		SampleData.getSWTObservableFactory().setUpdateTime(DataBindingContext.TIME_EARLY);
544
		// assertEquals("Cricket11Players",firstSignon.getPassword());
391
		TableViewerDescription tableViewerDescription = new TableViewerDescription(tableViewer);
545
		//		
392
		tableViewerDescription.addEditableColumn("lastName");
546
	}
393
		tableViewerDescription.addColumn("lastName");
547
394
		getDbc().bind(tableViewerDescription,new Property(catalog, "accounts"), null);
548
	public void testScenario09() {
395
		
549
		// // Verify that nested properties work. Catalog has adventures.
396
		// Verify that the first account is shown in the first row with the last name correctly
550
		// Adventure has
397
		assertEquals(tableViewer.getTable().getItem(0).getData(),firstAccount);
551
		// defaultLodging. Loding has name.
398
		assertEquals(tableViewer.getTable().getItem(0).getText(0),firstAccount.getLastName());
552
		// TableViewerDescription tableViewerDescription = new
399
		assertEquals(tableViewer.getTable().getItem(0).getText(1),firstAccount.getLastName());
553
		// TableViewerDescription(tableViewer);
400
		// Create a cell editor over the first column
554
		// tableViewerDescription.addColumn("name");
401
		tableViewer.editElement(firstAccount, 0);
555
		// tableViewerDescription.addColumn("defaultLodging.name");
402
		// Set the text property of the cell editor which is now active over the "firstName" column
556
		// getDbc().bind(tableViewerDescription,new Property(category,
403
		CellEditor[] cellEditors = tableViewer.getCellEditors();
557
		// "adventures"),null);
404
		TextCellEditor lastNameCellEditor = (TextCellEditor) cellEditors[0];
558
		//		
405
		((Text)lastNameCellEditor.getControl()).setText("E");
559
	}
406
		// Verify that the key press goes to the model
560
407
		assertEquals(firstAccount.getLastName(),"E");
561
	/**
408
		
562
	 * public void testScenario10(){ // Verify that for TIME_EARLY updating
409
	}
563
	 * occurs on a per key basic for a TextCellEditor // Show that converters
410
 **/	
564
	 * work for table columns Account[] accounts = catalog.getAccounts();
565
	 * Account firstAccount = accounts[0];
566
	 * SampleData.getSWTObservableFactory().setUpdateTime(DataBindingContext.TIME_EARLY);
567
	 * TableViewerDescription tableViewerDescription = new
568
	 * TableViewerDescription(tableViewer);
569
	 * tableViewerDescription.addEditableColumn("lastName");
570
	 * tableViewerDescription.addColumn("lastName");
571
	 * getDbc().bind(tableViewerDescription,new Property(catalog, "accounts"),
572
	 * null); // Verify that the first account is shown in the first row with
573
	 * the last name correctly
574
	 * assertEquals(tableViewer.getTable().getItem(0).getData(),firstAccount);
575
	 * assertEquals(tableViewer.getTable().getItem(0).getText(0),firstAccount.getLastName());
576
	 * assertEquals(tableViewer.getTable().getItem(0).getText(1),firstAccount.getLastName()); //
577
	 * Create a cell editor over the first column
578
	 * tableViewer.editElement(firstAccount, 0); // Set the text property of the
579
	 * cell editor which is now active over the "firstName" column CellEditor[]
580
	 * cellEditors = tableViewer.getCellEditors(); TextCellEditor
581
	 * lastNameCellEditor = (TextCellEditor) cellEditors[0];
582
	 * ((Text)lastNameCellEditor.getControl()).setText("E"); // Verify that the
583
	 * key press goes to the model assertEquals(firstAccount.getLastName(),"E"); }
584
	 */
411
}
585
}
412
(-)src/org/eclipse/jface/tests/internal/databinding/viewers/ViewersObservableFactoryTests.java (+65 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.tests.internal.databinding.viewers;
13
14
import junit.framework.TestCase;
15
16
import org.eclipse.jface.internal.databinding.internal.swt.TextObservableValue;
17
import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
18
import org.eclipse.jface.internal.databinding.provisional.viewers.ViewersObservableFactory;
19
import org.eclipse.jface.viewers.TableViewer;
20
import org.eclipse.jface.viewers.TextCellEditor;
21
import org.eclipse.swt.SWT;
22
import org.eclipse.swt.widgets.Shell;
23
24
/**
25
 * @since 3.2
26
 *
27
 */
28
public class ViewersObservableFactoryTests extends TestCase {
29
	private ViewersObservableFactory factory;
30
	private TableViewer viewer;
31
	
32
	/* (non-Javadoc)
33
	 * @see junit.framework.TestCase#setUp()
34
	 */
35
	protected void setUp() throws Exception {
36
		super.setUp();
37
		
38
		factory = new ViewersObservableFactory();
39
		
40
		Shell shell = new Shell();
41
		viewer = new TableViewer(shell, SWT.NONE);
42
	}
43
	
44
	public void testCreateTextCellEditorObservable() throws Exception {
45
		TextCellEditor editor = new TextCellEditor(viewer.getTable());
46
		IObservable observable = factory.createObservable(editor);
47
		assertNotNull(observable);
48
		assertTrue(observable instanceof TextObservableValue);
49
	}
50
	
51
	/**
52
	 * TextCellEditor must have been constructed with a parent.
53
	 * 
54
	 * @throws Exception
55
	 */
56
	public void testCreateTextCellEditorObservableWithoutViewerException() throws Exception {
57
		try {
58
			TextCellEditor editor = new TextCellEditor();
59
			factory.createObservable(editor);
60
			fail("Exception should have been thrown.");
61
		} catch (IllegalArgumentException e) {
62
			assertTrue(true);
63
		}
64
	}
65
}
(-)src/org/eclipse/jface/tests/internal/databinding/viewers/EditorBindingManagerTests.java (+163 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.jface.tests.internal.databinding.viewers;
13
14
import junit.framework.TestCase;
15
16
import org.eclipse.jface.examples.databinding.model.SampleData;
17
import org.eclipse.jface.internal.databinding.internal.ValueBinding;
18
import org.eclipse.jface.internal.databinding.provisional.Binding;
19
import org.eclipse.jface.internal.databinding.provisional.DataBindingContext;
20
import org.eclipse.jface.internal.databinding.provisional.description.Property;
21
import org.eclipse.jface.internal.databinding.provisional.description.TableModelDescription;
22
import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
23
import org.eclipse.jface.internal.databinding.provisional.viewers.TableViewerEditorManager;
24
import org.eclipse.jface.viewers.CellEditor;
25
import org.eclipse.jface.viewers.TableViewer;
26
import org.eclipse.jface.viewers.TextCellEditor;
27
import org.eclipse.swt.SWT;
28
import org.eclipse.swt.widgets.Shell;
29
30
/**
31
 * @since 3.2
32
 */
33
public class EditorBindingManagerTests extends TestCase {
34
	private TableViewer viewer;
35
36
	private DataBindingContext context;
37
38
	private TableModelDescription description;
39
	private TableViewerEditorManager manager;
40
41
	protected void setUp() throws Exception {
42
		Shell shell = new Shell();
43
44
		viewer = new TableViewer(shell, SWT.NONE);
45
		context = SampleData.getDatabindingContext(shell);
46
		description = new TableModelDescription(new Property(null, null),
47
				new String[] { "firstName", "middleName", "lastName" });
48
		manager = new TableViewerEditorManager(viewer, description, context);
49
	}
50
51
	public void testConstruction() throws Exception {
52
		assertEquals(viewer, manager.getTableViewer());
53
		assertEquals(description, manager.getTableModelDescription());
54
		assertEquals(context, manager.getDataBindingContext());
55
	}
56
57
	public void testConstructionExceptions() throws Exception {
58
		try {
59
			manager = new TableViewerEditorManager(null, description, context);
60
			fail("Exception should have been thrown.");
61
		} catch (NullPointerException e) {
62
			assertTrue(true);
63
		}
64
65
		try {
66
			manager = new TableViewerEditorManager(viewer, null, context);
67
			fail("Exception should have been thrown.");
68
		} catch (NullPointerException e) {
69
			assertTrue(true);
70
		}
71
72
		try {
73
			manager = new TableViewerEditorManager(viewer, description, null);
74
			fail("Exception should have been thrown.");
75
		} catch (NullPointerException e) {
76
			assertTrue(true);
77
		}
78
	}
79
80
	public void testCellModifierCreation() throws Exception {
81
		assertNotNull(viewer.getCellModifier());
82
	}
83
84
	public void testCellEditorArrayCreation() throws Exception {
85
		CellEditor[] editors = viewer.getCellEditors();
86
		assertNotNull(editors);
87
		assertEquals(description.getColumnIDs().length, editors.length);
88
	}
89
90
	public void testSetColumnProperties() throws Exception {
91
		Object[] properties = viewer.getColumnProperties();
92
		Object[] columnIDs = description.getColumnIDs();
93
		assertNotNull(properties);
94
		assertEquals(columnIDs.length, properties.length);
95
96
		for (int i = 0; i < properties.length; i++) {
97
			assertEquals(columnIDs[i], properties[i]);
98
		}
99
	}
100
101
	public void testBindEditor() throws Exception {
102
		Binding binding = manager.bind(new TextCellEditor(), "firstName", String.class,
103
				null);
104
		assertNotNull(binding);
105
		assertTrue(binding instanceof ValueBinding);
106
	}
107
	
108
	public void testSetEditorOnViewer() throws Exception {
109
		CellEditor editor = new TextCellEditor();
110
		manager.bind(editor, "firstName", String.class, null);
111
		assertEquals(editor, viewer.getCellEditors()[0]);
112
	}
113
114
	public void testBindEditorNullPointerExceptions() throws Exception {
115
		try {
116
			manager.bind(null, "firstName", String.class, null);
117
			fail("Exception should have been thrown.");
118
		} catch (NullPointerException e) {
119
			assertTrue(true);
120
		}
121
		
122
		try {
123
			manager.bind(new TextCellEditor(viewer.getTable()), null, String.class, null);
124
			fail("Exception should have been thrown.");
125
		} catch (NullPointerException e) {
126
			assertTrue(true);
127
		}
128
		
129
		try {
130
			manager.bind(new TextCellEditor(viewer.getTable()), "firstName", null, null);
131
			fail("Exception should have been thrown.");
132
		} catch (NullPointerException e) {
133
			assertTrue(true);
134
		}
135
	}
136
	
137
	public void testCreateControlIfNullWhenBound() throws Exception {
138
		TextCellEditor editor = new TextCellEditor();
139
		assertNull(editor.getControl());
140
		manager.bind(editor, "firstName", String.class, null);
141
		assertNotNull(editor.getControl());
142
	}
143
	
144
	public void testIAEIfColumnIDNotFound() throws Exception {
145
		try {
146
			manager.bind(new TextCellEditor(viewer.getTable()), "invalid column ID", String.class, null);
147
			fail("Exception should have been thrown.");
148
		} catch (IllegalArgumentException e) {
149
			assertTrue(true);
150
		}
151
	}
152
	
153
	public void testReuseSelectionAcrossBindings() throws Exception {
154
		manager.bind(new TextCellEditor(),	"firstName", String.class, null);
155
		IObservable selection1 = manager.getSelectionObservable();
156
		assertNotNull(selection1);
157
		
158
		manager.bind(new TextCellEditor(), "lastName", String.class, null);
159
		IObservable selection2 = manager.getSelectionObservable();
160
		assertNotNull(selection2);
161
		assertSame(selection1, selection2);
162
	}
163
}
(-)src/org/eclipse/jface/tests/databinding/swt/TextObservableValueTests.java (+132 lines)
Added Link Here
1
package org.eclipse.jface.tests.databinding.swt;
2
3
import junit.framework.TestCase;
4
5
import org.eclipse.jface.internal.databinding.internal.swt.TextObservableValue;
6
import org.eclipse.jface.internal.databinding.provisional.observable.value.IObservableValue;
7
import org.eclipse.jface.internal.databinding.provisional.observable.value.IValueChangeListener;
8
import org.eclipse.jface.internal.databinding.provisional.observable.value.ValueDiff;
9
import org.eclipse.swt.SWT;
10
import org.eclipse.swt.widgets.Event;
11
import org.eclipse.swt.widgets.Shell;
12
import org.eclipse.swt.widgets.Text;
13
14
/**
15
 * Tests for TextObservableValue.
16
 * 
17
 * @since 3.2
18
 */
19
public class TextObservableValueTests extends TestCase {
20
	private Shell shell;
21
22
	private Text text;
23
24
	protected void setUp() throws Exception {
25
		super.setUp();
26
27
		shell = new Shell();
28
		text = new Text(shell, SWT.NONE);
29
	}
30
31
	/**
32
	 * Asserts that if the a <code>null</code> Text is passed TextObservableValue throws a NPE.
33
	 */
34
	public void testConstructor() {
35
		try {
36
			new TextObservableValue(null, SWT.NONE);
37
			fail();
38
		} catch (NullPointerException e) {
39
			assertTrue(true);
40
		}
41
	}
42
	
43
	/**
44
	 * Asserts that only valid SWT event types are accepted on construction of TextObservableValue.
45
	 */
46
	public void testConstructorUpdateEventTypes() {
47
		try {
48
			new TextObservableValue(text, SWT.NONE);
49
			new TextObservableValue(text, SWT.FocusOut);
50
			new TextObservableValue(text, SWT.Modify);
51
			assertTrue(true);
52
		} catch (IllegalArgumentException e) {
53
			fail();
54
		}
55
		
56
		try {
57
			new TextObservableValue(text, SWT.Verify);
58
			fail();
59
		} catch (IllegalArgumentException e) {
60
			assertTrue(true);
61
		}
62
	}
63
	
64
	public void testFireValueChangeEventsOnFocusOut() {
65
		TextObservableValue observable = new TextObservableValue(text,
66
				SWT.FocusOut);
67
		ValueChangeCounter counter = new ValueChangeCounter();
68
		observable.addValueChangeListener(counter);
69
70
		text.setText("value");
71
		assertEquals(0, counter.count);
72
		text.notifyListeners(SWT.FocusOut, null);
73
		assertEquals(1, counter.count);
74
	}
75
76
	public void testFireValueChangeEventsOnModify() {
77
		TextObservableValue observable = new TextObservableValue(text,
78
				SWT.Modify);
79
		ValueChangeCounter counter = new ValueChangeCounter();
80
		observable.addValueChangeListener(counter);
81
82
		text.setText("value");
83
		assertEquals(1, counter.count);
84
	}
85
86
	public void testSuppressFireValueChangeEvents() {
87
		TextObservableValue observable = new TextObservableValue(text, SWT.NONE);
88
		ValueChangeCounter counter = new ValueChangeCounter();
89
		observable.addValueChangeListener(counter);
90
91
		text.setText("value");
92
		assertEquals(0, counter.count);
93
		text.notifyListeners(SWT.Modify, null);
94
		assertEquals(0, counter.count);
95
		text.notifyListeners(SWT.FocusOut, null);
96
		assertEquals(0, counter.count);
97
	}
98
99
	public void testFireChangeEventsOnTraversal() {
100
		TextObservableValue observable = TextObservableValue.asTraversalObservable(text, SWT.TRAVERSE_RETURN | SWT.TRAVERSE_TAB_NEXT);
101
		
102
		ValueChangeCounter counter = new ValueChangeCounter();
103
		observable.addValueChangeListener(counter);
104
		
105
		text.setText("value");
106
		assertEquals(0, counter.count);
107
		text.notifyListeners(SWT.Modify, null);
108
		assertEquals(0, counter.count);
109
		text.notifyListeners(SWT.FocusOut, null);
110
		assertEquals(0, counter.count);
111
		
112
		Event event = new Event();
113
		event.detail = SWT.TRAVERSE_RETURN;
114
		
115
		text.notifyListeners(SWT.Traverse, event);
116
		assertEquals(1, counter.count);
117
		
118
		event = new Event();
119
		event.detail = SWT.TRAVERSE_TAB_NEXT;
120
		
121
		text.notifyListeners(SWT.Traverse, event);
122
		assertEquals(2, counter.count);
123
	}
124
125
	private class ValueChangeCounter implements IValueChangeListener {
126
		private int count;
127
128
		public void handleValueChange(IObservableValue source, ValueDiff diff) {
129
			count++;
130
		}
131
	}
132
}

Return to bug 144260