68 |
* @since 1.4 |
* @since 1.4 |
69 |
*/ |
*/ |
70 |
|
|
71 |
public class SpinnerListModel |
public class SpinnerListModel extends AbstractSpinnerModel |
72 |
extends AbstractSpinnerModel |
implements Serializable |
|
implements Serializable |
|
73 |
{ |
{ |
74 |
/** |
/** |
75 |
* For compatability with Sun's JDK |
* For compatability with Sun's JDK |
76 |
*/ |
*/ |
77 |
private static final long serialVersionUID = 3358804052191994516L; |
private static final long serialVersionUID = 3358804052191994516L; |
78 |
|
|
79 |
/** |
/** |
80 |
* The backing list for this model. |
* The backing list for this model. |
81 |
*/ |
*/ |
82 |
private List list; |
private List list; |
83 |
|
|
84 |
/** |
/** |
85 |
* The current index in the list. |
* The current index in the list. |
86 |
*/ |
*/ |
87 |
private transient int index; |
private transient int index; |
88 |
|
|
89 |
/** |
/** |
90 |
* Constructs a default <code>SpinnerListModel</code>. This |
* Constructs a default <code>SpinnerListModel</code>. This |
91 |
* is a model backed by a list containing only the single |
* is a model backed by a list containing only the single |
92 |
* <code>String</code> element, "empty". |
* <code>String</code> element, "empty". |
93 |
*/ |
*/ |
94 |
public SpinnerListModel() |
public SpinnerListModel() |
95 |
{ |
{ |
96 |
List defaultList; |
List defaultList; |
97 |
|
|
98 |
/* Create an empty list */ |
// Create an empty list. |
99 |
defaultList = new ArrayList(); |
defaultList = new ArrayList(); |
100 |
/* Add the string "empty" */ |
// Add the string "empty". |
101 |
defaultList.add("empty"); |
defaultList.add("empty"); |
102 |
/* Set the list */ |
// Set the list. |
103 |
setList(defaultList); |
setList(defaultList); |
104 |
} |
} |
105 |
|
|
106 |
/** |
/** |
107 |
* Constructs a <code>SpinnerListModel</code> using the supplied list. |
* Constructs a <code>SpinnerListModel</code> using the supplied list. |
108 |
* The model maintains a reference to this list, and returns |
* The model maintains a reference to this list, and returns |
109 |
* consecutive elements in response to calls to <code>getNextValue()</code>. |
* consecutive elements in response to calls to <code>getNextValue()</code>. |
110 |
* The initial value is that at position 0, so an initial call |
* The initial value is that at position 0, so an initial call |
111 |
* to <code>getValue()</code> returns the same as <code>list.get(0)</code>. |
* to <code>getValue()</code> returns the same as <code>list.get(0)</code>. |
112 |
* |
* |
113 |
* @param list The list to use for this model. |
* @param list The list to use for this model. |
114 |
* @throws IllegalArgumentException if the list is null or contains no |
* |
115 |
* elements. |
* @throws IllegalArgumentException if the list is null or contains no |
116 |
* @see SpinnerListModel#getNextValue() |
* elements. |
117 |
* @see SpinnerListModel#getValue() |
* |
118 |
*/ |
* @see SpinnerListModel#getNextValue() |
119 |
public SpinnerListModel(List list) |
* @see SpinnerListModel#getValue() |
120 |
{ |
*/ |
121 |
/* Retain a reference to the valid list */ |
public SpinnerListModel(List list) |
122 |
setList(list); |
{ |
123 |
} |
// Retain a reference to the valid list. |
124 |
|
setList(list); |
125 |
/** |
} |
126 |
* Constructs a <code>SpinnerListModel</code> using the supplied array. |
|
127 |
* The model stores a reference to the wrapper list returned by |
/** |
128 |
* <code>Arrays.asList()</code>. The wrapper list reflects modifications |
* Constructs a <code>SpinnerListModel</code> using the supplied array. |
129 |
* in the underlying array, so these changes will also be reflected |
* The model stores a reference to the wrapper list returned by |
130 |
* by the model. The model produces consecutive elements from the array |
* <code>Arrays.asList()</code>. The wrapper list reflects modifications |
131 |
* in response to calls to <code>getNextValue()</code>. The initial |
* in the underlying array, so these changes will also be reflected |
132 |
* value returned by <code>getValue()</code> is the same as |
* by the model. The model produces consecutive elements from the array |
133 |
* <code>array[0]</code>. |
* in response to calls to <code>getNextValue()</code>. The initial |
134 |
* |
* value returned by <code>getValue()</code> is the same as |
135 |
* @param array The array to use for this model. |
* <code>array[0]</code>. |
136 |
* @throws IllegalArgumentException if the array is null or contains |
* |
137 |
* no elements. |
* @param array The array to use for this model. |
138 |
* @see Arrays#asList(Object[]) |
* |
139 |
* @see SpinnerListModel#getNextValue() |
* @throws IllegalArgumentException if the array is null or contains |
140 |
* @see SpinnerListModel#getValue() |
* no elements. |
141 |
*/ |
* |
142 |
public SpinnerListModel(Object[] array) |
* @see Arrays#asList(Object[]) |
143 |
{ |
* @see SpinnerListModel#getNextValue() |
144 |
/* Check for a null or zero-sized array */ |
* @see SpinnerListModel#getValue() |
145 |
if (array == null || array.length == 0) |
*/ |
146 |
{ |
public SpinnerListModel(Object[] array) |
147 |
throw new IllegalArgumentException("The supplied array was invalid."); |
{ |
148 |
} |
// Check for a null or zero-sized array. |
149 |
/* |
if (array == null || array.length == 0) |
150 |
Retain a reference to a wrapper around the valid array |
{ |
151 |
The array, in list form, will be tested again here, but we can't really |
throw new IllegalArgumentException("The supplied array was invalid."); |
152 |
avoid this -- a null value to Arrays.asList will throw a NullPointerException |
} |
153 |
*/ |
|
154 |
setList(Arrays.asList(array)); |
// Retain a reference to a wrapper around the valid array. |
155 |
} |
// The array, in list form, will be tested again here, but we can't really |
156 |
|
// avoid this -- a null value to Arrays.asList will throw a |
157 |
/** |
// NullPointerException. |
158 |
* Returns the backing list for this model. |
setList(Arrays.asList(array)); |
159 |
* |
} |
160 |
* @return The backing list. |
|
161 |
*/ |
/** |
162 |
public List getList() |
* Returns the backing list for this model. |
163 |
{ |
* |
164 |
return list; |
* @return The backing list. |
165 |
} |
*/ |
166 |
|
public List getList() |
167 |
|
{ |
168 |
|
return list; |
169 |
|
} |
170 |
|
|
171 |
/** |
/** |
172 |
* Returns the next value from the list, which is the same as the element |
* Returns the next value from the list, which is the same as the element |
173 |
* stored at the current index + 1. Null is returned if there are no more |
* stored at the current index + 1. Null is returned if there are no more |
174 |
* values to be returned (the end of the list has been reached). An |
* values to be returned (the end of the list has been reached). An |
175 |
* ambiguity can occur here, as null may also be returned as a valid list |
* ambiguity can occur here, as null may also be returned as a valid list |
176 |
* element. This operation does not change the current value. |
* element. This operation does not change the current value. |
177 |
* |
* |
178 |
* @return The next value from the list or null. |
* @return The next value from the list or null. |
179 |
*/ |
*/ |
180 |
public Object getNextValue() |
public Object getNextValue() |
181 |
{ |
{ |
182 |
/* Check for a next value */ |
// Check for a next value. |
183 |
if (index < (list.size() - 1)) |
if (index < (list.size() - 1)) |
184 |
{ |
// Return the element at the next index. |
185 |
/* Return the element at the next index */ |
return list.get(index + 1); |
186 |
return list.get(index + 1); |
else |
187 |
} |
// Return null as this is the end of the list. |
188 |
|
return null; |
189 |
|
} |
190 |
|
|
191 |
|
/** |
192 |
|
* Returns the previous value from the list, which is the same as the element |
193 |
|
* stored at the current index - 1. Null is returned if there are no more |
194 |
|
* values to be returned (the start of the list has been reached). An |
195 |
|
* ambiguity can occur here, as null may also be returned as a valid list |
196 |
|
* element. This operation does not change the current value. |
197 |
|
* |
198 |
|
* @return The previous value from the list or null. |
199 |
|
*/ |
200 |
|
public Object getPreviousValue() |
201 |
|
{ |
202 |
|
// Check for a previous value. |
203 |
|
if (index > 0) |
204 |
|
// Return the element at the previous position. |
205 |
|
return list.get(index - 1); |
206 |
else |
else |
207 |
{ |
// Return null as this is the start of the list. |
208 |
/* Return null as this is the end of the list */ |
return null; |
|
return null; |
|
|
} |
|
209 |
} |
} |
210 |
|
|
211 |
/** |
/** |
212 |
* Returns the previous value from the list, which is the same as the element |
* Returns the current value of the model. Initially, this will |
213 |
* stored at the current index - 1. Null is returned if there are no more |
* be the element at position 0. On later invocations, this will |
214 |
* values to be returned (the start of the list has been reached). An |
* be the last element returned by <code>getNextValue()</code> |
215 |
* ambiguity can occur here, as null may also be returned as a valid list |
* or <code>getPreviousValue()</code>. |
216 |
* element. This operation does not change the current value. |
* |
217 |
* |
* @return The current value. |
218 |
* @return The previous value from the list or null. |
* |
219 |
*/ |
* @see SpinnerListModel#getPreviousValue() |
220 |
public Object getPreviousValue() |
* @see SpinnerListModel#getNextValue() |
221 |
{ |
*/ |
222 |
/* Check for a previous value. */ |
public Object getValue() |
223 |
if (index > 0) |
{ |
224 |
{ |
return list.get(index); |
225 |
/* Return the element at the previous position */ |
} |
226 |
return list.get(index - 1); |
|
227 |
} |
/** |
228 |
else |
* Changes the backing list for this model. The model only stores |
229 |
{ |
* a reference to the list, so any changes made to the list elsewhere |
230 |
/* Return null as this is the start of the list */ |
* will be reflected in the values returned by the model. A |
231 |
return null; |
* <code>ChangeEvent</code> is fired if the list being used actually |
232 |
} |
* changes (i.e. the new list is not referentially equal (!=) to the |
233 |
} |
* old one). |
234 |
|
* |
235 |
/** |
* @param list The new list to use. |
236 |
* Returns the current value of the model. Initially, this will |
* |
237 |
* be the element at position 0. On later invocations, this will |
* @throws IllegalArgumentException if the list is null or contains |
238 |
* be the last element returned by <code>getNextValue()</code> |
* no elements. |
239 |
* or <code>getPreviousValue()</code>. |
* |
240 |
* |
* @see ChangeEvent |
241 |
* @return The current value. |
*/ |
242 |
* @see SpinnerListModel#getPreviousValue() |
public void setList(List list) |
243 |
* @see SpinnerListModel#getNextValue() |
{ |
244 |
*/ |
// Check for null or zero size list. |
245 |
public Object getValue() |
if (list == null || list.size() == 0) |
246 |
{ |
throw new IllegalArgumentException("The supplied list was invalid."); |
247 |
return list.get(index); |
|
248 |
} |
// Check for a change of referenced list. |
249 |
|
if (this.list != list) |
250 |
/** |
{ |
251 |
* Changes the backing list for this model. The model only stores |
// Store the new list. |
252 |
* a reference to the list, so any changes made to the list elsewhere |
this.list = list; |
253 |
* will be reflected in the values returned by the model. A |
// Notify listeners of a change. |
254 |
* <code>ChangeEvent</code> is fired if the list being used actually |
fireStateChanged(); |
255 |
* changes (i.e. the new list is not referentially equal (!=) to the |
} |
256 |
* old one). |
// We reset the other values in either case. |
257 |
* |
// Set the index to 0. |
258 |
* @param list The new list to use. |
index = 0; |
259 |
* @throws IllegalArgumentException if the list is null or contains |
} |
260 |
* no elements. |
|
261 |
* @see ChangeEvent |
/** |
262 |
*/ |
* Sets the current value of the model to be the one supplied. |
263 |
public void setList(List list) |
* The value must exist within the backing list in order for |
264 |
{ |
* the change to take place. Otherwise, an exception is thrown. |
265 |
/* Check for null or zero size list */ |
* The value used is the first occurrence of the value within |
266 |
if (list == null || list.size() == 0) |
* the backing list. Listeners are notified of this change. |
267 |
{ |
* Following the change, <code>getNextValue()</code> and |
268 |
throw new IllegalArgumentException("The supplied list was invalid."); |
* <code>getPreviousValue()</code> return the objects following |
269 |
} |
* and prior to the supplied value, respectively. |
270 |
/* Check for a change of referenced list */ |
* |
271 |
if (this.list != list) |
* @param value The requested new value of the list. |
272 |
{ |
* |
273 |
/* Store the new list */ |
* @throws IllegalArgumentException if the supplied value does |
274 |
this.list = list; |
* not exist in the backing list. |
275 |
/* Notify listeners of a change */ |
* |
276 |
fireStateChanged(); |
* @see SpinnerListModel#getPreviousValue() |
277 |
} |
* @see SpinnerListModel#getNextValue() |
278 |
/* We reset the other values in either case */ |
*/ |
279 |
/* Set the index to 0 */ |
public void setValue(Object value) |
280 |
index = 0; |
{ |
281 |
} |
int valueIndex; |
282 |
|
|
283 |
/** |
// Search for the value in the list. |
284 |
* Sets the current value of the model to be the one supplied. |
valueIndex = list.indexOf(value); |
285 |
* The value must exist within the backing list in order for |
// Check for the value being found. |
286 |
* the change to take place. Otherwise, an exception is thrown. |
if (valueIndex == -1) |
287 |
* The value used is the first occurrence of the value within |
throw new IllegalArgumentException("The supplied value does not " |
288 |
* the backing list. Listeners are notified of this change. |
+ "exist in this list"); |
289 |
* Following the change, <code>getNextValue()</code> and |
// Make the indices match. |
290 |
* <code>getPreviousValue()</code> return the objects following |
index = valueIndex; |
291 |
* and prior to the supplied value, respectively. |
// Notify the listeners. |
292 |
* |
fireStateChanged(); |
293 |
* @param value The requested new value of the list. |
} |
|
* @throws IllegalArgumentException if the supplied value does |
|
|
* not exist in the backing list. |
|
|
* @see SpinnerListModel#getPreviousValue() |
|
|
* @see SpinnerListModel#getNextValue() |
|
|
*/ |
|
|
public void setValue(Object value) |
|
|
{ |
|
|
int valueIndex; |
|
|
|
|
|
/* Search for the value in the list */ |
|
|
valueIndex = list.indexOf(value); |
|
|
/* Check for the value being found */ |
|
|
if (valueIndex == -1) |
|
|
{ |
|
|
throw new IllegalArgumentException("The supplied value does not " |
|
|
+ "exist in this list"); |
|
|
} |
|
|
/* Make the indices match */ |
|
|
index = valueIndex; |
|
|
/* Notify the listeners */ |
|
|
fireStateChanged(); |
|
|
} |
|
294 |
|
|
295 |
} |
} |