View Javadoc

1   /*
2      Copyright 2002-2006 Martin van den Bemt
3   
4      Licensed under the Apache License, Version 2.0 (the "License");
5      you may not use this file except in compliance with the License.
6      You may obtain a copy of the License at
7   
8          http://www.apache.org/licenses/LICENSE-2.0
9   
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15  */
16  package org.xulux.guilayer.swing.models;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  import java.util.StringTokenizer;
21  
22  import javax.swing.AbstractListModel;
23  import javax.swing.ComboBoxModel;
24  
25  import org.xulux.api.dataprovider.IField;
26  import org.xulux.api.dataprovider.IMapping;
27  import org.xulux.core.XuluxContext;
28  import org.xulux.guilayer.swing.widgets.Combo;
29  
30  /**
31   * The default combobox model.
32   *
33   * @author <a href="mailto:martin@mvdb.net">Martin van den Bemt</a>
34   * @version $Id: DefaultComboModel.java,v 1.1 2005/12/18 12:58:21 mvdb Exp $
35   */
36  public class DefaultComboModel extends AbstractListModel implements ComboBoxModel {
37      /**
38       * The original list
39       */
40      private List original;
41      /**
42       * the used list
43       */
44      private ArrayList list;
45      /**
46       * The selected item
47       */
48      private ComboShowable selectedItem;
49      /**
50       * the field to use
51       */
52      private String field;
53      /**
54       * the Mapping
55       */
56      private IMapping mapping;
57      /**
58       * the combo where this model is used for
59       */
60      private Combo combo;
61      /**
62       * If the model has been initialized
63       */
64      private boolean initialized;
65  
66      /**
67       * don't do anything, since we don't have any data..
68       * It will create an empty list however
69       */
70      public DefaultComboModel() {
71          this.list = new ArrayList();
72      }
73  
74      /**
75       * Constructor for DefaultComboModel.
76       *
77       * @param list the list with data
78       * @param field the field to use
79       * @param combo the combo used
80       */
81      public DefaultComboModel(List list, String field, Combo combo) {
82          this.field = field;
83          this.original = list;
84          this.combo = combo;
85          initialize();
86      }
87  
88      /**
89       * When using the arrow keys to select another
90       * item from the combo, we have to fire an event
91       * with the index0 and the index1 with the value -1.
92       * This way you can actually see the selectedItem change
93       * on screen. If you don't fire this event, the selectedItem
94       * (onscreen!) will stay on the selected item on creation
95       * of the combo.
96       *
97       * @see javax.swing.ComboBoxModel#setSelectedItem(Object)
98       */
99      public void setSelectedItem(Object anItem) {
100         if (anItem instanceof ComboShowable) {
101             this.selectedItem = (ComboShowable) anItem;
102             if (initialized && !combo.isRefreshing()) {// && combo.getProvider() == null) {
103                 combo.setLazyValue(getRealSelectedValue());
104             }
105         } else {
106             setRealSelectedValue(anItem);
107         }
108         fireContentsChanged(this, -1, -1);
109     }
110 
111     /**
112      * Set the selected item to the specified index
113      * @param index the index to select
114      */
115     public void setSelectedItem(int index) {
116         if (list.size() > 0) {
117             if (!(index >= list.size())) {
118                 this.selectedItem = (ComboShowable) list.get(index);
119             }
120         }
121     }
122 
123     /**
124      * @see javax.swing.ComboBoxModel#getSelectedItem()
125      */
126     public Object getSelectedItem() {
127         return selectedItem;
128     }
129 
130     /**
131      * @see javax.swing.ListModel#getSize()
132      */
133     public int getSize() {
134         if (list == null) {
135             return 0;
136         }
137         return list.size();
138     }
139 
140     /**
141      * The comboshowable which is requested by the JCombo
142      * object.
143      *
144      * @see javax.swing.ListModel#getElementAt(int)
145      */
146     public Object getElementAt(int index) {
147         return list.get(index);
148     }
149 
150     /**
151      * @return the real selected value in the combo, so not a comboshowable
152      */
153     public Object getRealSelectedValue() {
154         Object retValue = null;
155         if (original != null && selectedItem != null) {
156             retValue = original.get(selectedItem.getIndex());
157         } else if (original != null && original.size() > 0) {
158             retValue = original.get(0);
159         }
160         return retValue;
161     }
162 
163     /**
164      * @return the selected index in the model
165      *          If the selection is null, it will return -1
166      */
167     public int getSelectedIndex() {
168         if (selectedItem == null) {
169             return -1;
170         } else {
171             return selectedItem.getIndex();
172         }
173     }
174 
175     /**
176      * Set the real selected item (so not the comboshowable.
177      *
178      * @param selectedItem the real selected item
179      */
180     public void setRealSelectedValue(Object selectedItem) {
181         if (original == null) {
182             return;
183         }
184         int index = -1;
185         try {
186             index = original.indexOf(selectedItem);
187         } catch(Exception e) {
188             // ignore exceptions thrown in an equals method.
189             e.printStackTrace();
190         }
191         if (index != -1) {
192             setSelectedItem(list.get(index));
193         } else if (combo.getProvider() != null) {
194             combo.setValue(getRealSelectedValue());
195         } else {
196             setSelectedItem(0);
197             if (combo.getProvider() == null) {
198                 combo.setLazyValue(getRealSelectedValue());
199             }
200         }
201     }
202 
203     /**
204      * Initialize the model and the data
205      */
206     protected void initialize() {
207         if (field != null && original.size() > 0) {
208             int startMappingAt = 0;
209             if (original.get(0).equals(combo.getNotSelectedValue())) {
210                 startMappingAt = 1;
211             }
212             if ((startMappingAt == 1 && original.size() > 1) || startMappingAt == 0) {
213                 Class tmpClazz = original.get(startMappingAt).getClass();
214                 mapping = XuluxContext.getDictionary().getDefaultProvider().getMapping(tmpClazz);
215             }
216         }
217         list = new ArrayList();
218         for (int i = 0; i < original.size(); i++) {
219             Object object = original.get(i);
220             if (object != null && (i == 0 && combo.getNotSelectedValue() != null && object.equals(combo.getNotSelectedValue())) || this.field == null) {
221                 list.add(new ComboShowable(i, object.toString()));
222             } else {
223                 String value = "";
224                 StringTokenizer stn = new StringTokenizer(field, ",");
225                 while (stn.hasMoreTokens()) {
226                     String token = stn.nextToken();
227                     String strPart = "";
228                     IField iField = mapping.getField(token);
229                     if (iField != null) {
230                         strPart = iField.getValue(object).toString();
231                     } else {
232                         //allow seperators in the field list.
233                         strPart = token;
234                     }
235                     value += strPart;
236                 }
237                 list.add(new ComboShowable(i, value));
238             }
239         }
240         initialized = true;
241     }
242 
243     /**
244      * Clean up combomodel (if at all needed)
245      */
246     public void destroy() {
247         this.combo = null;
248         this.list = null;
249         this.mapping = null;
250         this.original = null;
251         this.field = null;
252         this.selectedItem = null;
253     }
254 
255     /**
256      * @return the original data
257      */
258     protected List getOriginal() {
259         return this.original;
260     }
261 
262     /**
263      * @return the data in the combo
264      */
265     protected List getList() {
266         return this.list;
267     }
268     /**
269      * Holds all items in a list
270      */
271     public class ComboShowable {
272         /**
273          * the index
274          */
275         private int index;
276         /**
277          * the value
278          */
279         private String value;
280 
281         /**
282          * The main constructor
283          * @param index the index in the original data
284          * @param value the value that needs to be shown
285          */
286         public ComboShowable(int index, String value) {
287             this.index = index;
288             this.value = value;
289         }
290 
291         /**
292          * Since a combo is using the toString value of an object,
293          * this will return the value set in the constructor
294          *
295          * @see java.lang.Object#toString()
296          */
297         public String toString() {
298             return this.value;
299         }
300 
301         /**
302          * @return the index in the original data
303          */
304         public int getIndex() {
305             return index;
306         }
307     }
308 }