Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: javax/microedition/lcdui/ChoiceGroup.java


1   /*
2    *  MicroEmulator
3    *  Copyright (C) 2001 Bartek Teodorczyk <barteo@it.pl>
4    *
5    *  This library is free software; you can redistribute it and/or
6    *  modify it under the terms of the GNU Lesser General Public
7    *  License as published by the Free Software Foundation; either
8    *  version 2.1 of the License, or (at your option) any later version.
9    *
10   *  This library is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   *  Lesser General Public License for more details.
14   *
15   *  You should have received a copy of the GNU Lesser General Public
16   *  License along with this library; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   *
19   *  Contributor(s):
20   *    Shane Harper
21   */
22   
23  package javax.microedition.lcdui;
24  
25  
26  public class ChoiceGroup extends Item implements Choice
27  {
28  
29    ChoiceItem items[] = new ChoiceItem[4];
30    int numOfItems = 0;
31  
32    int choiceType;
33  
34    int highlightedItemIndex = -1;
35  
36    static byte multiOff[] = {
37        -119, 80, 78, 71, 13, 10, 26, 10, 0, 0,
38        0, 13, 73, 72, 68, 82, 0, 0, 0, 10,
39        0, 0, 0, 11, 2, 3, 0, 0, 0, 59,
40        0, -12, -117, 0, 0, 0, 6, 80, 76, 84,
41        69, -1, -1, -1, -69, -69, -69, -57, 75, -33,
42        -8, 0, 0, 0, 30, 73, 68, 65, 84, 120,
43        -38, 99, 96, 96, 96, 96, 12, 101, -8, -51,
44        -32, -64, 32, -64, -60, -64, -64, -128, 11, 51,
45        -122, 50, -4, 6, 0, 63, 116, 3, 1, 53,
46        -108, 39, -26, 0, 0, 0, 0, 73, 69, 78,
47        68, -82, 66, 96, -126 };
48  
49    static byte multiOn[] = {
50        -119, 80, 78, 71, 13, 10, 26, 10, 0, 0,
51        0, 13, 73, 72, 68, 82, 0, 0, 0, 10,
52        0, 0, 0, 11, 2, 3, 0, 0, 0, 59,
53        0, -12, -117, 0, 0, 0, 12, 80, 76, 84,
54        69, -1, -1, -1, -69, -69, -69, 106, 106, 106,
55        2, 2, 2, 106, -103, 14, -47, 0, 0, 0,
56        53, 73, 68, 65, 84, 120, -38, 99, 96, 96,
57        124, -64, -16, -1, -77, 3, -45, 65, -111, 15,
58        76, 12, 108, 12, 76, 12, -4, 12, 76, 12,
59        18, 12, 76, -68, 127, 24, -104, 126, 45, 96,
60        96, -7, -11, -109, -127, -23, -65, 3, 3, -29,
61        127, -122, -113, 0, 5, 37, 12, -34, 1, -99,
62        -83, 100, 0, 0, 0, 0, 73, 69, 78, 68,
63        -82, 66, 96, -126 };
64  
65    static byte radioOff[] = {
66        -119, 80, 78, 71, 13, 10, 26, 10, 0, 0,
67        0, 13, 73, 72, 68, 82, 0, 0, 0, 11,
68        0, 0, 0, 11, 2, 3, 0, 0, 0, -44,
69        -62, -97, -75, 0, 0, 0, 9, 80, 76, 84,
70        69, -1, -1, -1, -69, -69, -69, 106, 106, 106,
71        -44, 13, -1, -24, 0, 0, 0, 42, 73, 68,
72        65, 84, 120, -38, 99, 96, 90, -59, -64, 32,
73        -63, 48, -127, 65, -127, 65, -127, 41, -127, -31,
74        5, 19, 3, 3, 3, 50, 102, 80, 96, 80,
75        96, -6, -63, 80, -64, -64, -76, -118, 1, 0,
76        113, 24, 5, 61, 73, -68, -100, 98, 0, 0,
77        0, 0, 73, 69, 78, 68, -82, 66, 96, -126 };
78  
79    static byte radioOn[] = {
80        -119, 80, 78, 71, 13, 10, 26, 10, 0, 0,
81        0, 13, 73, 72, 68, 82, 0, 0, 0, 11,
82        0, 0, 0, 11, 2, 3, 0, 0, 0, -44,
83        -62, -97, -75, 0, 0, 0, 12, 80, 76, 84,
84        69, -1, -1, -1, -69, -69, -69, 106, 106, 106,
85        2, 2, 2, 106, -103, 14, -47, 0, 0, 0,
86        50, 73, 68, 65, 84, 120, -38, 5, -63, 65,
87        13, 0, 32, 12, 4, -63, -19, -11, -117, 1,
88        18, 68, -100, 10, 52, 19, 94, 72, 64, 17,
89        101, -122, 44, -44, -29, 98, -52, 89, 77, -102,
90        40, 2, 85, -95, -73, -63, -104, -63, 37, -117,
91        15, -40, 119, 10, 41, 78, 26, -79, 59, 0,
92        0, 0, 0, 73, 69, 78, 68, -82, 66, 96,
93        -126 };
94  
95    private static final Image imgMultiOff = Image.createImage(multiOff, 0, multiOff.length);
96    private static final Image imgMultiOn = Image.createImage(multiOn, 0, multiOn.length);
97    private static final Image imgRadioOff = Image.createImage(radioOff, 0, radioOff.length);
98    private static final Image imgRadioOn = Image.createImage(radioOn, 0, radioOn.length);
99  
100 
101   public ChoiceGroup(String label, int choiceType)
102   {
103     super(label);
104     this.choiceType = choiceType;
105   }
106 
107 
108   // XXX imageElements is ignored.
109   public ChoiceGroup(String label, int choiceType, String[] stringElements, Image[] imageElements)
110   {
111     this(label, choiceType);
112 
113     for (int i = 0; i < stringElements.length; i++) {
114       if (imageElements == null) {
115         append(stringElements[i], null);
116       } else {
117         append(stringElements[i], imageElements[i]);
118       }
119     }
120   }
121 
122 
123   public int append(String stringPart, Image imagePart)
124   {
125     insert(numOfItems, stringPart, imagePart);
126 
127     return (numOfItems - 1);
128   }
129 
130 
131   public void delete(int itemNum)
132   {
133     if (itemNum < 0 || itemNum >= numOfItems) {
134       throw new IndexOutOfBoundsException();
135     }
136 
137     // Ensure that an item of an EXCLUSIVE list remains selected.
138     if (Choice.EXCLUSIVE == choiceType && items[itemNum].isSelected()) {
139       if (numOfItems > 1) {
140         items[itemNum!=0 ? 0 : 1].setSelectedState(true);
141       }
142     }
143 
144     // Delete item.
145     if (itemNum != numOfItems - 1) {
146       System.arraycopy(items, itemNum+1, items, itemNum, numOfItems-itemNum-1);
147     }
148     numOfItems--;
149 
150     // Ensure highlighted item remains highlighted (if it wasn't just deleted).
151     if (highlightedItemIndex > itemNum) {
152       --highlightedItemIndex;
153     }
154 
155     // Ensure that an item remains highlighted.
156     if (highlightedItemIndex >= numOfItems) {
157       highlightedItemIndex = numOfItems-1;
158     }
159     
160     repaint();
161   }
162 
163 
164   public Image getImage(int elementNum)
165   {
166     if (elementNum < 0 || elementNum >= numOfItems) {
167       throw new IndexOutOfBoundsException();
168     }
169 
170     return null;
171   }
172 
173 
174   /**
175    * Queries the state of a ChoiceGroup and returns the state of all elements in
176    * the boolean array selectedArray_return. NOTE: this is a result parameter.
177    * It must be at least as long as the size of the ChoiceGroup as returned by
178    * size(). If the array is longer, the extra elements are set to false.
179    *
180    * For ChoiceGroup objects of type MULTIPLE, any number of elements may be
181    * selected and set to true in the result array. For ChoiceGroup objects of
182    * type EXCLUSIVE, exactly one element will be selected, unless there are zero
183    * elements in the ChoiceGroup.
184    */
185   public int getSelectedFlags(boolean[] selectedArray_return)
186   {
187     if (selectedArray_return == null) {
188       throw new NullPointerException();
189     }
190     if (selectedArray_return.length < numOfItems) {
191       throw new IllegalArgumentException();
192     }
193 
194     // set selectedArray_return elements and count number of selected items
195     int selectedItemsCount = 0;
196     for (int i = 0; i < selectedArray_return.length; ++i) {
197       selectedArray_return[i] = (i<numOfItems) ? items[i].isSelected() : false;
198       if (selectedArray_return[i]) {
199         ++selectedItemsCount;
200       }
201     }
202 
203     return selectedItemsCount;
204   }
205 
206   /**
207    *  Returns the index number of an element in the ChoiceGroup that is
208    *  selected. For ChoiceGroup objects of type EXCLUSIVE there is at most one
209    *  element selected, so this method is useful for determining the user's
210    *  choice. Returns -1 if there are no elements in the ChoiceGroup.
211    *
212    *  For ChoiceGroup objects of type MULTIPLE, this always returns -1 because
213    *  no single value can in general represent the state of such a ChoiceGroup.
214    *  To get the complete state of a MULTIPLE Choice, see getSelectedFlags.
215    */
216   public int getSelectedIndex()
217   {
218     switch (choiceType) {
219       case Choice.EXCLUSIVE:
220         // XXX It'd be nice if the selected item index was stored, so it isn't
221         //     necessary to search for it.
222         for (int i = 0; i < numOfItems; ++i) {
223           if (items[i].isSelected()) return i;
224         }
225         break;
226       case Choice.IMPLICIT:
227         return highlightedItemIndex;
228     }
229     return -1;
230   }
231 
232 
233   public String getString(int elementNum)
234   {
235     if (elementNum < 0 || elementNum >= numOfItems) {
236       throw new IndexOutOfBoundsException();
237     }
238 
239     return items[elementNum].getText();
240   }
241 
242 
243   public void insert(int elementNum, String stringPart, Image imagePart)
244   {
245     if (elementNum < 0 || elementNum > numOfItems) {
246       throw new IndexOutOfBoundsException();
247     }
248     if (imagePart != null && imagePart.isMutable()) {
249       throw new IllegalArgumentException();
250     }
251     if (stringPart == null) {
252       throw new NullPointerException();
253     }
254 
255     if (numOfItems == items.length  /*no space left in item array*/) {
256       ChoiceItem newItems[] = new ChoiceItem[numOfItems + 4];
257       System.arraycopy(items, 0, newItems, 0, numOfItems);
258       items = newItems;
259     }
260 
261     System.arraycopy(items, elementNum, items, elementNum + 1,
262                      numOfItems - elementNum);
263   
264     items[elementNum] = new ChoiceItem(null, imagePart, stringPart);
265 
266     ++numOfItems;
267 
268     if (numOfItems == 1) {
269       highlightedItemIndex = 0;
270       if (Choice.EXCLUSIVE == choiceType) {
271         setSelectedIndex(0, true);
272       }
273     }
274     
275     repaint();
276   }
277 
278 
279   public boolean isSelected(int elementNum)
280   {
281     if (elementNum < 0 || elementNum >= numOfItems) {
282       throw new IndexOutOfBoundsException();
283     }
284 
285     return items[elementNum].isSelected();
286   }
287 
288 
289   public void set(int elementNum, String stringPart, Image imagePart)
290   {
291     if (elementNum < 0 || elementNum >= numOfItems) {
292       throw new IndexOutOfBoundsException();
293     }
294     if (imagePart != null && imagePart.isMutable()) {
295       throw new IllegalArgumentException();
296     }
297     if (stringPart == null) {
298       throw new NullPointerException();
299     }
300 
301     items[elementNum].setText(stringPart);
302     items[elementNum].setImage(imagePart);
303     
304     repaint();
305   }
306 
307 
308   public void setLabel(String label)
309   {
310     super.setLabel(label);
311   }
312 
313 
314   public void setSelectedFlags(boolean[] selectedArray)
315   {
316     if (selectedArray == null) {
317       throw new NullPointerException();
318     }
319     if (selectedArray.length < numOfItems) {
320       throw new NullPointerException();
321     }
322 
323     if (choiceType == Choice.EXCLUSIVE) {
324       boolean performed = false;
325       for (int i = 0; i < numOfItems; i++) {
326         if (selectedArray[i]) {
327           setSelectedIndex(i, true);
328           performed = true;
329           break;
330         }
331       }
332       if (!performed) {
333         setSelectedIndex(0, true);
334       }
335     } else if (choiceType == Choice.MULTIPLE) {
336       for (int i = 0; i < numOfItems; i++) {
337         setSelectedIndex(i, selectedArray[i]);
338       }
339     }
340   }
341 
342 
343   public void setSelectedIndex(int elementNum, boolean selected)
344   {
345     if (elementNum < 0 || elementNum >= numOfItems) {
346       throw new IndexOutOfBoundsException();
347     }
348 
349     if (choiceType == Choice.EXCLUSIVE && selected) {
350       for (int i = 0; i < numOfItems; i++) {
351         items[i].setSelectedState(elementNum == i);
352       }
353       repaint();
354     } else if (choiceType == Choice.MULTIPLE) {
355       items[elementNum].setSelectedState(selected);
356       repaint();
357     }
358   }
359 
360 
361   public int size()
362   {
363     return numOfItems;
364   }
365 
366 
367   boolean isFocusable()
368   {
369     return true;
370   }
371 
372 
373   int getHeight()
374   {
375     int height = 0;
376     for (int i = 0; i < numOfItems; i++) {
377       height += items[i].getHeight();
378     }
379 
380     return super.getHeight() + height;
381   }
382 
383 
384   int paint(Graphics g)
385   {
386     super.paintContent(g);
387 
388     g.translate(0, super.getHeight());
389     int translatedY = 0;
390     for (int i = 0; i < numOfItems; i++) {
391       items[i].invertPaint(i == highlightedItemIndex && hasFocus());
392       items[i].paint(g);
393       g.translate(0, items[i].getHeight());
394       translatedY += items[i].getHeight();
395     }
396     g.translate(0, -translatedY);
397     g.translate(0, -super.getHeight());
398 
399     return getHeight();
400   }
401 
402 
403   boolean select()
404   {
405     if (numOfItems == 0) {
406       return false;
407     }
408 
409     // XXX What does the following statement do?
410     setSelectedIndex(highlightedItemIndex, !items[highlightedItemIndex].isSelected());
411 
412     return true;
413   }
414 
415 
416   int traverse(int gameKeyCode, int top, int bottom, boolean action)
417   {
418     if (gameKeyCode == Canvas.UP) {
419       if (highlightedItemIndex > 0) {
420         if (action) {
421           highlightedItemIndex--;
422         }
423         int height = super.getHeight();
424         for (int i = 0; i < highlightedItemIndex; i++) {
425           height += items[i].getHeight();
426         }
427         if (height < top) {
428           return height - top;
429         } else {
430           repaint();
431         }
432       } else {
433         if (top > 0) {
434           return -top;
435         } else {
436           return Item.OUTOFITEM;
437         }
438       }
439     }
440     if (gameKeyCode == Canvas.DOWN) {
441       if ((!action && highlightedItemIndex < numOfItems)
442           || (action && highlightedItemIndex < (numOfItems - 1))) {
443         if (action) {
444           highlightedItemIndex++;
445         }
446         int height = super.getHeight();
447         for (int i = 0; i <= highlightedItemIndex; i++) {
448           height += items[i].getHeight();
449         }
450         if (height > bottom) {
451           return height - bottom;
452         } else {
453           repaint();
454         }
455       } else {
456         return Item.OUTOFITEM;
457       }
458     }
459 
460     return 0;
461   }
462 
463 
464   class ChoiceItem extends ImageStringItem
465   {
466     private boolean selected;
467 
468     ChoiceItem(String label, Image image, String text)
469     {
470       super(label, image, text);
471       setSelectedState(false);
472     }
473 
474     boolean isSelected()
475     {
476       return selected;
477     }
478 
479     void setSelectedState(boolean state)
480     {
481       selected = state;
482       
483       if (choiceType != Choice.IMPLICIT) {
484         setImage(Choice.EXCLUSIVE  == choiceType ? 
485             (state? imgRadioOn:imgRadioOff) : (state? imgMultiOn:imgMultiOff));
486       }
487     }
488   }
489   
490 }