1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.springframework.richclient.form.binding.swing;
17
18 import java.util.Arrays;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Observable;
24
25 import javax.swing.ComboBoxModel;
26 import javax.swing.DefaultComboBoxModel;
27 import javax.swing.DefaultListModel;
28 import javax.swing.JComboBox;
29 import javax.swing.ListModel;
30 import javax.swing.event.ListDataEvent;
31 import javax.swing.event.ListDataListener;
32
33 import org.springframework.binding.value.ValueModel;
34 import org.springframework.binding.value.support.ValueHolder;
35 import org.springframework.rules.constraint.Constraint;
36 import org.springframework.richclient.form.binding.Binding;
37 import org.springframework.util.comparator.ComparableComparator;
38
39 public class ComboBoxBindingTests extends BindingAbstractTests {
40
41 private static final String[] SELECTABLEITEMS = new String[] { "0", "1", "2", "3", "4" };
42
43 private ValueModel sih;
44
45 private ComboBoxBinding cbb;
46
47 private JComboBox cb;
48
49 private TestDataListener testListener;
50
51 protected String setUpBinding() {
52 cbb = new ComboBoxBinding(fm, "simpleProperty");
53 cb = (JComboBox) cbb.getControl();
54 sih = new ValueHolder(SELECTABLEITEMS);
55 cbb.setSelectableItems(sih);
56 testListener = new TestDataListener();
57 cb.getModel().addListDataListener(testListener);
58 return "simpleProperty";
59 }
60
61 public void testWithListModel() throws Exception {
62 DefaultListModel model = new DefaultListModel();
63 model.addElement("1");
64 model.addElement("2");
65 model.addElement("3");
66 model.addElement("4");
67 cbb.setSelectableItems(model);
68 cbb.doBindControl();
69 ComboBoxModel cbmodel = cb.getModel();
70 assertEquals(model.getSize(), cbmodel.getSize());
71 for (int i = 0, size = model.size(); i < size; i++) {
72 assertEquals(model.getElementAt(i), cbmodel.getElementAt(i));
73 }
74 }
75
76 public void testWithList() throws Exception {
77 List model = Arrays.asList(SELECTABLEITEMS);
78 cbb.setSelectableItems(model);
79 cbb.doBindControl();
80 ComboBoxModel cbmodel = cb.getModel();
81 assertEquals(model.size(), cbmodel.getSize());
82 for (int i = 0, size = model.size(); i < size; i++) {
83 assertEquals(model.get(i), cbmodel.getElementAt(i));
84 }
85 }
86
87 public void testWithArray() throws Exception {
88 Object[] model = SELECTABLEITEMS;
89 cbb.setSelectableItems(model);
90 cbb.doBindControl();
91 ComboBoxModel cbmodel = cb.getModel();
92 assertEquals(model.length, cbmodel.getSize());
93 for (int i = 0, size = model.length; i < size; i++) {
94 assertEquals(model[i], cbmodel.getElementAt(i));
95 }
96 }
97
98 public void testValueModelUpdatesComponent() {
99 TestListDataListener tldl = new TestListDataListener();
100 cb.getModel().addListDataListener(tldl);
101
102 assertEquals(null, cb.getSelectedItem());
103 assertEquals(-1, cb.getSelectedIndex());
104 tldl.assertCalls(0);
105
106 vm.setValue("1");
107 assertEquals("1", cb.getSelectedItem());
108 assertEquals(1, cb.getSelectedIndex());
109 tldl.assertEvent(1, ListDataEvent.CONTENTS_CHANGED, -1, -1);
110
111 vm.setValue("2");
112 assertEquals("2", cb.getSelectedItem());
113 assertEquals(2, cb.getSelectedIndex());
114 tldl.assertEvent(2, ListDataEvent.CONTENTS_CHANGED, -1, -1);
115
116 vm.setValue(null);
117 assertEquals(null, cb.getSelectedItem());
118 assertEquals(-1, cb.getSelectedIndex());
119 tldl.assertEvent(3, ListDataEvent.CONTENTS_CHANGED, -1, -1);
120
121 vm.setValue(null);
122 tldl.assertCalls(3);
123 }
124
125 public void testComponentUpdatesValueModel() {
126 cb.setSelectedIndex(1);
127 assertEquals("1", vm.getValue());
128
129 cb.setSelectedItem("2");
130 assertEquals("2", vm.getValue());
131
132 cb.setSelectedIndex(-1);
133 assertEquals(null, vm.getValue());
134
135 cb.setSelectedItem(null);
136 assertEquals(null, vm.getValue());
137 }
138
139 public void testSelectableValueChangeUpdatesComboBoxModel() {
140 assertEquals("0", cb.getModel().getElementAt(0));
141
142 sih.setValue(new Object[] { "1" });
143 assertEquals("1", cb.getModel().getElementAt(0));
144 }
145
146 public void testComponentTracksEnabledChanges() {
147 assertTrue(cb.isEnabled());
148
149 fm.getFieldMetadata("simpleProperty").setEnabled(false);
150 assertFalse(cb.isEnabled());
151
152 fm.getFieldMetadata("simpleProperty").setEnabled(true);
153 assertTrue(cb.isEnabled());
154 }
155
156 public void testComponentTracksReadOnlyChanges() {
157 assertTrue(cb.isEnabled());
158
159 fm.getFieldMetadata("simpleProperty").setReadOnly(true);
160 assertFalse(cb.isEnabled());
161
162 fm.getFieldMetadata("simpleProperty").setReadOnly(false);
163 assertTrue(cb.isEnabled());
164 }
165
166 public void testSelectableItemHolderNullValue() {
167 ComboBoxBinding binding = new ComboBoxBinding(fm, "simpleProperty");
168 binding.getControl();
169 ValueHolder valueHolder = new ValueHolder();
170 try {
171 binding.setSelectableItems(valueHolder);
172 fail();
173 } catch (IllegalArgumentException e) {
174
175 }
176 }
177
178 public void testExistingModel() {
179 JComboBox cb = new JComboBox(new DefaultComboBoxModel(new Object[] { "1", "2", "3" }));
180 ComboBoxBinder binder = new ComboBoxBinder();
181 Binding binding = binder.bind(cb, fm, "simpleProperty", Collections.EMPTY_MAP);
182 assertEquals(3, ((JComboBox) binding.getControl()).getModel().getSize());
183 }
184
185 public void testFilter() {
186 setUpBinding();
187 ListModel model = cb.getModel();
188 cbb.setFilter(new Constraint() {
189 public boolean test(Object argument) {
190 return "1".equals(argument) || "4".equals(argument);
191 }
192 });
193 assertEquals(2, model.getSize());
194 assertEquals("1", model.getElementAt(0));
195 assertEquals("4", model.getElementAt(1));
196 }
197
198 public void testUpdatingFilter() {
199 setUpBinding();
200 ListModel model = cb.getModel();
201 TestConstraint testConstraint = new TestConstraint();
202 cbb.setFilter(testConstraint);
203 assertEquals(2, model.getSize());
204 assertEquals("1", model.getElementAt(0));
205 assertEquals("4", model.getElementAt(1));
206
207 testConstraint.testCalled = 0;
208 testConstraint.setFilterValues(new Object[] { "2" });
209
210 assertEquals(testConstraint.filterValues.length, model.getSize());
211 assertEquals("2", model.getElementAt(0));
212 }
213
214 public void testFilterWithContext() {
215 ComboBoxBinder binder = new ComboBoxBinder();
216 binder.setSelectableItems(SELECTABLEITEMS);
217 Map context = new HashMap();
218 Constraint filter = new Constraint() {
219 public boolean test(Object argument) {
220 return "1".equals(argument) || "4".equals(argument);
221 }
222 };
223 context.put(ComboBoxBinder.FILTER_KEY, filter);
224 ComboBoxBinding binding = (ComboBoxBinding) binder.bind(fm, "simpleProperty", context);
225 ListModel bindingModel = binding.getBindingModel();
226 assertEquals(filter, binding.getFilter());
227 assertEquals(2, bindingModel.getSize());
228 assertEquals("1", bindingModel.getElementAt(0));
229 assertEquals("4", bindingModel.getElementAt(1));
230 }
231
232 public void testComparator() {
233 ComboBoxBinder binder = new ComboBoxBinder();
234 binder.setSelectableItems(new Object[] { "2", "4", "1", "2", "3" });
235 binder.setComparator(new ComparableComparator());
236 ComboBoxBinding binding = (ComboBoxBinding) binder.bind(fm, "simpleProperty", Collections.EMPTY_MAP);
237 ListModel bindingModel = binding.getBindingModel();
238 assertEquals(5, bindingModel.getSize());
239 assertEquals("1", bindingModel.getElementAt(0));
240 assertEquals("2", bindingModel.getElementAt(1));
241 assertEquals("2", bindingModel.getElementAt(2));
242 assertEquals("3", bindingModel.getElementAt(3));
243 assertEquals("4", bindingModel.getElementAt(4));
244 }
245
246 public void testEmptySelectionValue() throws Exception {
247 ComboBoxModel model = cb.getModel();
248 int modelSize = model.getSize();
249 testListener.contentsChanged = null;
250 testListener.intervalAdded = null;
251 testListener.intervalRemoved = null;
252 String emptyValue = "select a Value";
253 cbb.setEmptySelectionValue(emptyValue);
254 assertEquals(modelSize + 1, model.getSize());
255 assertEquals(emptyValue, model.getElementAt(0));
256 assertNotNull(testListener.contentsChanged);
257 assertNull(testListener.intervalAdded);
258 assertNull(testListener.intervalRemoved);
259 cb.setSelectedItem(SELECTABLEITEMS[0]);
260 assertEquals(SELECTABLEITEMS[0], model.getSelectedItem());
261 assertEquals(SELECTABLEITEMS[0], vm.getValue());
262 cb.setSelectedItem(emptyValue);
263 assertEquals(emptyValue, model.getSelectedItem());
264 assertEquals(null, vm.getValue());
265 cb.setSelectedItem(null);
266 assertEquals(emptyValue, model.getSelectedItem());
267 assertEquals(null, vm.getValue());
268
269 cb.setSelectedItem(emptyValue);
270 testListener.contentsChanged = null;
271 testListener.intervalAdded = null;
272 testListener.intervalRemoved = null;
273 cbb.setEmptySelectionValue(null);
274 assertNotNull(testListener.contentsChanged);
275 assertNull(testListener.intervalAdded);
276 assertNull(testListener.intervalRemoved);
277 assertEquals(modelSize, model.getSize());
278 assertEquals(SELECTABLEITEMS[0], model.getElementAt(0));
279 assertNull(vm.getValue());
280 }
281
282 private static class TestConstraint extends Observable implements Constraint {
283 Object[] filterValues = new Object[] { "1", "4" };
284
285 int testCalled = 0;
286
287 public boolean test(Object argument) {
288 testCalled++;
289 for (int i = 0; i < filterValues.length; i++) {
290 if (filterValues[i].equals(argument))
291 return true;
292 }
293 return false;
294 }
295
296 public void setFilterValues(Object[] objects) {
297 filterValues = objects;
298 setChanged();
299 notifyObservers();
300 }
301 }
302
303 private class TestDataListener implements ListDataListener {
304
305 private ListDataEvent contentsChanged;
306
307 private ListDataEvent intervalAdded;
308
309 private ListDataEvent intervalRemoved;
310
311 public void contentsChanged(ListDataEvent e) {
312 contentsChanged = e;
313 }
314
315 public void intervalAdded(ListDataEvent e) {
316 intervalAdded = e;
317 }
318
319 public void intervalRemoved(ListDataEvent e) {
320 intervalRemoved = e;
321 }
322
323 }
324 }