1 /*
2 * Scope: a generic MVC framework.
3 * Copyright (c) 2000-2002, The Scope team
4 * All rights reserved.
5 *
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * Neither the name "Scope" nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 *
36 * $Id: SListSelectionModel.java,v 1.6 2002/09/05 15:41:49 ludovicc Exp $
37 */
38 package org.scopemvc.view.swing;
39
40
41 import java.util.HashSet;
42 import java.util.Iterator;
43 import javax.swing.DefaultListSelectionModel;
44 import org.apache.commons.logging.Log;
45 import org.apache.commons.logging.LogFactory;
46 import org.scopemvc.core.Selector;
47 import org.scopemvc.view.util.ModelBindable;
48
49 /***
50 * <P>
51 *
52 * A ListSelectionModel bound to a model property that will contain a reference
53 * to the current selection. This implementation allows read-only properties to
54 * disable the parent JList or JTable. SINGLE_SELECTION and
55 * SINGLE_INTERVAL_SELECTION are supported. </P> <P>
56 *
57 * The bound property can be an Object of the type being selected in which case
58 * the topmost single selection is updated. If the property is a HashSet then it
59 * is updated with all selections. </P>
60 *
61 * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A>
62 * @created 05 September 2002
63 * @version $Revision: 1.6 $ $Date: 2002/09/05 15:41:49 $
64 * @see SList
65 * @see STable
66 */
67 public class SListSelectionModel extends DefaultListSelectionModel
68 implements ModelBindable, Refreshable {
69
70 private final static Log LOG = LogFactory.getLog(SListSelectionModel.class);
71
72 /***
73 * Helper to manage model to view binding.
74 */
75 private SwingBoundModel boundModel = new SwingBoundModel(this);
76
77 /***
78 * Parent so we can find the currently selected object and pass on
79 * validation failures.
80 */
81 private ListSelectionParent parent;
82
83 /***
84 * Is selection disabled?
85 */
86 private boolean disabled;
87
88
89 /***
90 * Create for a parent SingleListSelectionParent.
91 *
92 * @param inParent TODO: Describe the Parameter
93 */
94 public SListSelectionModel(ListSelectionParent inParent) {
95
96 super();
97
98 if (inParent == null) {
99 throw new IllegalArgumentException("Create SListSelectionModel with a SingleListSelectionParent");
100 }
101
102 parent = inParent;
103
104 parent.setEnabled(false);
105 }
106
107
108 // ------------------- Delegate to BoundModel -------------------
109
110 /***
111 * Gets the bound model
112 *
113 * @return The boundModel value
114 */
115 public final Object getBoundModel() {
116 return boundModel.getBoundModel();
117 }
118
119
120 /***
121 * Gets the selector
122 *
123 * @return The selector value
124 */
125 public final Selector getSelector() {
126 return boundModel.getSelector();
127 }
128
129
130 /***
131 * Gets the view value
132 *
133 * @return The viewValue value
134 */
135 public Object getViewValue() {
136
137 // Figure out the type of the bound property
138 Class propertyClass = boundModel.getPropertyClass();
139
140 // Populate appropriately
141 if (HashSet.class.equals(propertyClass)) {
142 HashSet elements = new HashSet();
143 for (int i = getMinSelectionIndex(); i <= getMaxSelectionIndex(); ++i) {
144 Object element = parent.findElementAt(i);
145 if (element != null) {
146 elements.add(parent.findElementAt(i));
147 }
148 }
149 if (LOG.isDebugEnabled()) {
150 LOG.debug("getViewValue: " + elements);
151 }
152 return elements;
153 } else {
154 int index = getMinSelectionIndex();
155 if (LOG.isDebugEnabled()) {
156 LOG.debug("getViewValue: " + parent.findElementAt(index));
157 }
158 return parent.findElementAt(index);
159 }
160 }
161
162
163 /***
164 * Sets the bound model
165 *
166 * @param inModel The new boundModel value
167 */
168 public final void setBoundModel(Object inModel) {
169 boundModel.setBoundModel(inModel);
170 }
171
172
173 /***
174 * Sets the selector
175 *
176 * @param inSelector The new selector value
177 */
178 public final void setSelector(Selector inSelector) {
179 boundModel.setSelector(inSelector);
180 }
181
182
183 /***
184 * Sets the selector string
185 *
186 * @param inSelectorString The new selectorString value
187 */
188 public final void setSelectorString(String inSelectorString) {
189 boundModel.setSelectorString(inSelectorString);
190 }
191
192
193 /***
194 * Sets the selection mode
195 *
196 * @param selectionMode The new selectionMode value
197 */
198 public void setSelectionMode(int selectionMode) {
199 switch (selectionMode) {
200 case SINGLE_SELECTION:
201 case SINGLE_INTERVAL_SELECTION:
202 super.setSelectionMode(selectionMode);
203 break;
204 default:
205 throw new IllegalArgumentException("invalid selectionMode");
206 }
207 }
208
209
210 // --------------------- Implement ModelBindable ----------------------
211
212 /***
213 * Incoming value is null, an Object or a java.util.HashSet.
214 *
215 * @param inValue TODO: Describe the Parameter
216 * @param inReadOnly TODO: Describe the Parameter
217 */
218 public void updateFromProperty(Object inValue, boolean inReadOnly) {
219 if (LOG.isDebugEnabled()) {
220 LOG.debug("updateFromProperty: " + inValue + ", " + inReadOnly);
221 }
222
223 parent.setEnabled(!inReadOnly);
224
225 if (inValue == null) {
226 super.clearSelection();
227 return;
228 }
229
230 if (inValue instanceof HashSet) {
231 updateFromHashSet((HashSet) inValue);
232 } else {
233 updateFromObject(inValue);
234 }
235 }
236
237
238 /***
239 * If selection fails, make validation fail on parent.
240 *
241 * @param inException TODO: Describe the Parameter
242 */
243 public void validationFailed(Exception inException) {
244 parent.validationFailed(inException);
245 }
246
247
248 /***
249 * If selection fails, make validation fail on parent.
250 */
251 public void validationSuccess() {
252 parent.validationSuccess();
253 }
254
255
256 // ------------------ Refreshable -------------------------
257
258 /***
259 * TODO: document the method
260 */
261 public void refresh() {
262 Object propertyValue = boundModel.getPropertyValue();
263 boolean propertyReadOnly = boundModel.getPropertyReadOnly();
264 updateFromProperty(propertyValue, propertyReadOnly);
265 }
266
267
268 /***
269 * TODO: document the method
270 *
271 * @param inValue TODO: Describe the Parameter
272 */
273 protected void updateFromObject(Object inValue) {
274 if (LOG.isDebugEnabled()) {
275 LOG.debug("updateFromObject: " + inValue);
276 }
277
278 if (inValue == null) {
279 if (!isSelectionEmpty()) {
280 clearSelection();
281 }
282 return;
283 }
284
285 int index = parent.findIndexFor(inValue);
286 if (index < 0) {
287 if (LOG.isDebugEnabled()) {
288 LOG.debug("updateFromObject: null");
289 }
290 if (!isSelectionEmpty()) {
291 clearSelection();
292 }
293 } else {
294 if (getMinSelectionIndex() != index) {
295 if (LOG.isDebugEnabled()) {
296 LOG.debug("updateFromObject: " + index);
297 }
298 setSelectionInterval(index, index);
299 }
300 }
301 }
302
303
304 /***
305 * TODO: document the method
306 *
307 * @param inValue TODO: Describe the Parameter
308 */
309 protected void updateFromHashSet(HashSet inValue) {
310 if (LOG.isDebugEnabled()) {
311 LOG.debug("updateFromHashSet: " + inValue);
312 }
313
314 if (inValue == null || inValue.size() < 1) {
315 if (!isSelectionEmpty()) {
316 clearSelection();
317 }
318 return;
319 }
320
321 int i0 = -1;
322 int i1 = -1;
323 for (Iterator i = inValue.iterator(); i.hasNext(); ) {
324 int index = parent.findIndexFor(i.next());
325 i1 = Math.max(i1, index);
326 if (i0 < 0) {
327 i0 = i1;
328 } else {
329 i0 = Math.min(i0, index);
330 }
331 }
332
333 if (i0 < 0) {
334 if (!isSelectionEmpty()) {
335 clearSelection();
336 }
337 } else {
338 if (getMinSelectionIndex() != i0 || getMaxSelectionIndex() != i1) {
339 setSelectionInterval(i0, i1);
340 }
341 }
342 }
343
344
345 // ---------------------- View to model ----------------------
346
347 /***
348 * When selection changes, update the bound model.
349 *
350 * @param firstIndex TODO: Describe the Parameter
351 * @param lastIndex TODO: Describe the Parameter
352 * @param isAdjusting TODO: Describe the Parameter
353 */
354 protected void fireValueChanged(int firstIndex, int lastIndex, boolean isAdjusting) {
355 if (LOG.isDebugEnabled()) {
356 LOG.debug("fireValueChanged: " + firstIndex + "," + lastIndex + "," + isAdjusting);
357 }
358
359 super.fireValueChanged(firstIndex, lastIndex, isAdjusting);
360
361 // If final change in a sequence then adjust bound model
362 // ... and make the parent list issue a control.
363 if (!isAdjusting) {
364 if (LOG.isDebugEnabled()) {
365 LOG.debug("fireValueChanged: " + firstIndex);
366 }
367 boundModel.updateModel();
368 parent.issueChangeSelectionControl();
369 }
370 }
371 }
This page was automatically generated by Maven