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: SList.java,v 1.12 2002/09/13 17:04:40 ludovicc Exp $
37   */
38  package org.scopemvc.view.swing;
39  
40  
41  import java.awt.event.MouseEvent;
42  import java.awt.event.MouseListener;
43  import javax.swing.JList;
44  import javax.swing.JToolTip;
45  import javax.swing.ListCellRenderer;
46  import javax.swing.ListModel;
47  import javax.swing.ListSelectionModel;
48  import org.apache.commons.logging.Log;
49  import org.apache.commons.logging.LogFactory;
50  import org.scopemvc.core.Control;
51  import org.scopemvc.core.Controller;
52  import org.scopemvc.core.Selector;
53  import org.scopemvc.core.View;
54  
55  /***
56   * <P>
57   *
58   * A JList that uses a {@link SListModel} to bind to model properties, and a
59   * {@link SListSelectionModel} to bind the selected item to a property. Uses a
60   * {@link SListCellRenderer} to draw items in the list. </P> <P>
61   *
62   * SList can issue Controls on selection changes and on double-click. </P> <P>
63   *
64   * SList doesn't itself bind to a model: it delegates all binding to its
65   * SListModel and SListSelectionModel. </P>
66   *
67   * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A>
68   * @created 05 September 2002
69   * @version $Revision: 1.12 $ $Date: 2002/09/13 17:04:40 $
70   * @see SListModel
71   * @see SListSelectionModel
72   * @see SListCellRenderer
73   * @see SAbstractListModel
74   * @see SComboBox
75   */
76  public class SList extends JList
77           implements View, MouseListener, Refreshable, ListSelectionParent {
78  
79      private static final Log LOG = LogFactory.getLog(SList.class);
80  
81      /***
82       * Control to issue on selection change.
83       */
84      private String selectionControlID;
85  
86      /***
87       * Control to issue on double click.
88       */
89      private String doubleClickControlID;
90  
91      // ------------- Support validation failures from selection -------------
92  
93      /***
94       * Helper to manage validation state.
95       */
96      private ValidationHelper validationHelper = new ValidationHelper(this);
97  
98  
99      /***
100      * Constructor for the SList object
101      */
102     public SList() {
103         super();
104         setCellRenderer(new SListCellRenderer());
105         setModel(new SListModel(this));
106         addMouseListener(this);
107         setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
108     }
109 
110 
111     // ---------- Implement View by delegation to SListModel and SListSelectionModel ----------
112 
113     /***
114      * Gets the bound model
115      *
116      * @return The boundModel value
117      */
118     public final Object getBoundModel() {
119         return ((SListModel) getModel()).getBoundModel();
120     }
121 
122 
123     /***
124      * Gets the size selector
125      *
126      * @return The sizeSelector value
127      */
128     public final Selector getSizeSelector() {
129         return ((SListModel) getModel()).getSizeSelector();
130     }
131 
132 
133     /***
134      * Gets the selector
135      *
136      * @return The selector value
137      */
138     public final Selector getSelector() {
139         return ((SListModel) getModel()).getSelector();
140     }
141 
142 
143     /***
144      * Gets the selection selector
145      *
146      * @return The selectionSelector value
147      */
148     public final Selector getSelectionSelector() {
149         return ((SListSelectionModel) getSelectionModel()).getSelector();
150     }
151 
152 
153     /***
154      * Gets the renderer selector
155      *
156      * @return The rendererSelector value
157      */
158     public final Selector getRendererSelector() {
159         ListCellRenderer renderer = getCellRenderer();
160         if (!(renderer instanceof SListCellRenderer)) {
161             return null;
162         }
163         return ((SListCellRenderer) renderer).getTextSelector();
164     }
165 
166 
167     /***
168      * Gets the renderer icon selector
169      *
170      * @return The rendererIconSelector value
171      */
172     public final Selector getRendererIconSelector() {
173         ListCellRenderer renderer = getCellRenderer();
174         if (!(renderer instanceof SListCellRenderer)) {
175             return null;
176         }
177         return ((SListCellRenderer) renderer).getIconSelector();
178     }
179 
180 
181     /***
182      * Gets the change selection control ID
183      *
184      * @return The changeSelectionControlID value
185      */
186     public final String getChangeSelectionControlID() {
187         return selectionControlID;
188     }
189 
190 
191     /***
192      * Gets the double click control ID
193      *
194      * @return The doubleClickControlID value
195      */
196     public final String getDoubleClickControlID() {
197         return doubleClickControlID;
198     }
199 
200 
201     // -------------------- Controls -----------------------
202 
203     /***
204      * TODO: document the method
205      */
206     public void issueChangeSelectionControl() {
207         if (selectionControlID != null) {
208             Control control = new Control(selectionControlID);
209             issueControl(control);
210         }
211     }
212 
213 
214     /***
215      * Don't assign a direct Controller to List, instead delegate to the
216      * containing SwingView that has a parent Controller.
217      *
218      * @return The controller value
219      */
220     public Controller getController() {
221         return null;
222     }
223 
224 
225     /***
226      * Don't assign a direct Controller to List, instead delegate to the
227      * containing SwingView that has a parent Controller.
228      *
229      * @param inControl TODO: Describe the Parameter
230      */
231     public void issueControl(Control inControl) {
232         SwingUtil.issueControl(this, inControl);
233     }
234 
235 
236     /***
237      * Sets the bound model
238      *
239      * @param inModel The new boundModel value
240      */
241     public final void setBoundModel(Object inModel) {
242         ((SListModel) getModel()).setBoundModel(inModel);
243         ((SListSelectionModel) getSelectionModel()).setBoundModel(inModel);
244     }
245 
246     /***
247      * Set the Selector for the list data. Should be a java.util.List or an
248      * Object[] or have a "size" property and properties accessible by an
249      * IntIndexedSelector.
250      *
251      * @param inSelector The new selector value
252      */
253     public final void setSelector(Selector inSelector) {
254         ((SListModel) getModel()).setSelector(inSelector);
255     }
256 
257 
258     /***
259      * Set the Selector for the list data. Should be a java.util.List or an
260      * Object[] or have a "size" property and properties accessible by an
261      * IntIndexedSelector.
262      *
263      * @param inSelectorString The new selectorString value
264      */
265     public final void setSelectorString(String inSelectorString) {
266         ((SListModel) getModel()).setSelectorString(inSelectorString);
267     }
268 
269     /***
270      * Set the Selector for the list selection: this property will be bound to
271      * the list's single selection.
272      *
273      * @param inSelector The new selectionSelector value
274      */
275     public final void setSelectionSelector(Selector inSelector) {
276         ((SListSelectionModel) getSelectionModel()).setSelector(inSelector);
277     }
278 
279 
280     /***
281      * Set the Selector for the list selection: this property will be bound to
282      * the list's single selection.
283      *
284      * @param inSelectorString The new selectionSelectorString value
285      */
286     public final void setSelectionSelectorString(String inSelectorString) {
287         ((SListSelectionModel) getSelectionModel()).setSelectorString(inSelectorString);
288     }
289 
290     /***
291      * Set the Selector for the list cell renderer: this is the property that
292      * will be shown in a list cell (converted to a String).
293      *
294      * @param inSelector The new rendererSelector value
295      */
296     public final void setRendererSelector(Selector inSelector) {
297         ListCellRenderer renderer = getCellRenderer();
298         if (!(renderer instanceof SListCellRenderer)) {
299             throw new UnsupportedOperationException("Not using a Scope bound SListCellRenderer so can't set a Selector on it");
300         }
301         ((SListCellRenderer) renderer).setTextSelector(inSelector);
302     }
303 
304     /***
305      * Set the Selector for the list cell renderer to get an Icon: this is the
306      * property that will be shown as an Icon in a list cell.
307      *
308      * @param inSelector The new rendererIconSelector value
309      */
310     public final void setRendererIconSelector(Selector inSelector) {
311         ListCellRenderer renderer = getCellRenderer();
312         if (!(renderer instanceof SListCellRenderer)) {
313             throw new UnsupportedOperationException("Not using a Scope bound SListCellRenderer so can't set a Selector on it");
314         }
315         ((SListCellRenderer) renderer).setIconSelector(inSelector);
316     }
317 
318 
319     /***
320      * Set the Selector for the list cell renderer: this is the property that
321      * will be shown in a list cell (converted to a String).
322      *
323      * @param inSelectorString The new rendererSelectorString value
324      */
325     public final void setRendererSelectorString(String inSelectorString) {
326         ListCellRenderer renderer = getCellRenderer();
327         if (!(renderer instanceof SListCellRenderer)) {
328             throw new UnsupportedOperationException("Not using a Scope bound SListCellRenderer so can't set a Selector on it");
329         }
330         ((SListCellRenderer) renderer).setTextSelectorString(inSelectorString);
331     }
332 
333 
334     /***
335      * Set the Selector for the list cell renderer to get an Icon: this is the
336      * property that will be shown as an Icon in a list cell.
337      *
338      * @param inSelectorString The new rendererIconSelectorString value
339      */
340     public final void setRendererIconSelectorString(String inSelectorString) {
341         ListCellRenderer renderer = getCellRenderer();
342         if (!(renderer instanceof SListCellRenderer)) {
343             throw new UnsupportedOperationException("Not using a Scope bound SListCellRenderer so can't set a Selector on it");
344         }
345         ((SListCellRenderer) renderer).setIconSelectorString(inSelectorString);
346     }
347 
348     /***
349      * Set the Control ID for the Control that will be issued when the selection
350      * is changed. If null no Control will be issued.
351      *
352      * @param inControlID The new changeSelectionControlID value
353      */
354     public final void setChangeSelectionControlID(String inControlID) {
355         selectionControlID = inControlID;
356     }
357 
358     /***
359      * Set the Control ID for the Control that will be issued when the List is
360      * double-clicked. If null no Control will be issued.
361      *
362      * @param inControlID The new doubleClickControlID value
363      */
364     public final void setDoubleClickControlID(String inControlID) {
365         doubleClickControlID = inControlID;
366     }
367 
368 
369     /***
370      * Sets the model
371      *
372      * @param model The new model value
373      */
374     public void setModel(ListModel model) {
375         if (!(model instanceof SListModel)) {
376             throw new IllegalArgumentException("model must be a SListModel");
377         }
378         super.setModel(model);
379     }
380 
381 
382     // --------- Set up list binding by delegation -------------
383 
384     /***
385      * Can use this to specify a static list model for the contents of the list
386      * rather than binding to a dynamic property of some view model.
387      *
388      * @param inModel The new listModel value
389      * @see org.scopemvc.model.collection.ListModelAdaptor
390      */
391     public void setListModel(Object inModel) {
392         ((SListModel) getModel()).setListModel(inModel);
393     }
394 
395     /***
396      * Can specify that the list's size comes from a bound property. This is
397      * very useful for JavaBeans indexed properties for which the size is not
398      * accessible in any other way.
399      *
400      * @param inSelector The new sizeSelector value
401      */
402     public void setSizeSelector(Selector inSelector) {
403         ((SListModel) getModel()).setSizeSelector(inSelector);
404     }
405 
406 
407     /***
408      * Can specify that the list's size comes from a bound property. This is
409      * very useful for JavaBeans indexed properties for which the size is not
410      * accessible in any other way.
411      *
412      * @param inSelectorString The new sizeSelectorString value
413      */
414     public void setSizeSelectorString(String inSelectorString) {
415         ((SListModel) getModel()).setSizeSelectorString(inSelectorString);
416     }
417 
418     /***
419      * Don't assign a Controller to this component, instead delegate to the
420      * containing SwingView that has a parent Controller.
421      *
422      * @param inController The new controller value
423      */
424     public void setController(Controller inController) {
425         throw new UnsupportedOperationException("Can't assign a Controller to a " + getClass());
426     }
427 
428     // ------------- Implement SingleListSelectionParent ----------------
429 
430     /***
431      * -1 if not found.
432      *
433      * @param inValue TODO: Describe the Parameter
434      * @return TODO: Describe the Return Value
435      */
436     public int findIndexFor(Object inValue) {
437         if (inValue == null) {
438             return -1;
439         }
440         for (int i = getModel().getSize() - 1; i >= 0; --i) {
441             if (inValue.equals(getModel().getElementAt(i))) {
442                 return i;
443             }
444         }
445         return -1;
446     }
447 
448 
449     /***
450      * Null if not found.
451      *
452      * @param inIndex TODO: Describe the Parameter
453      * @return TODO: Describe the Return Value
454      */
455     public Object findElementAt(int inIndex) {
456         if (inIndex < 0) {
457             return null;
458         }
459         try {
460             return getModel().getElementAt(inIndex);
461         } catch (Exception e) {
462             LOG.warn("Can't findElementAt: " + inIndex, e);
463         }
464         return null;
465     }
466 
467 
468     /***
469      * TODO: document the method
470      *
471      * @param e TODO: Describe the Parameter
472      */
473     public void mouseClicked(MouseEvent e) {
474         if (e.getClickCount() == 2) {
475             if (doubleClickControlID != null) {
476                 Control control = new Control(doubleClickControlID);
477                 issueControl(control);
478             }
479         }
480     }
481 
482 
483     /***
484      * TODO: document the method
485      *
486      * @param e TODO: Describe the Parameter
487      */
488     public void mousePressed(MouseEvent e) { }
489 
490     /***
491      * TODO: document the method
492      *
493      * @param e TODO: Describe the Parameter
494      */
495     public void mouseReleased(MouseEvent e) { }
496 
497     /***
498      * TODO: document the method
499      *
500      * @param e TODO: Describe the Parameter
501      */
502     public void mouseEntered(MouseEvent e) { }
503 
504     /***
505      * TODO: document the method
506      *
507      * @param e TODO: Describe the Parameter
508      */
509     public void mouseExited(MouseEvent e) { }
510 
511 
512     // ------------------ Refreshable -------------------------
513 
514     /***
515      * TODO: document the method
516      */
517     public void refresh() {
518         ((SListModel) getModel()).refresh();
519         refreshSelection();
520     }
521 
522 
523     // ------------- Support maintaining selection when list data changes ----------
524 
525     /***
526      * TODO: document the method
527      */
528     public void refreshSelection() {
529         ((SListSelectionModel) getSelectionModel()).refresh();
530     }
531 
532 
533     /***
534      * TODO: document the method
535      *
536      * @param inException TODO: Describe the Parameter
537      */
538     public void validationFailed(Exception inException) {
539         validationHelper.validationFailed(inException);
540     }
541 
542 
543     /***
544      * TODO: document the method
545      */
546     public void validationSuccess() {
547         validationHelper.validationSuccess();
548     }
549 
550 
551     /***
552      * TODO: document the method
553      *
554      * @return TODO: Describe the Return Value
555      */
556     public JToolTip createToolTip() {
557         return validationHelper.createToolTip(super.createToolTip());
558     }
559 
560 
561     // ------------------------ Create Selection ------------------------------
562 
563     /***
564      * TODO: document the method
565      *
566      * @return TODO: Describe the Return Value
567      */
568     protected ListSelectionModel createSelectionModel() {
569         return new SListSelectionModel(this);
570     }
571 }
This page was automatically generated by Maven