View Javadoc

1   /*
2    *  MicroEmulator
3    *  Copyright (C) 2001 Bartek Teodorczyk <barteo@barteo.net>
4    *  Copyright (C) 2005 Andres Navarro
5    *
6    *  This library is free software; you can redistribute it and/or
7    *  modify it under the terms of the GNU Lesser General Public
8    *  License as published by the Free Software Foundation; either
9    *  version 2.1 of the License, or (at your option) any later version.
10   *
11   *  This library is distributed in the hope that it will be useful,
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   *  Lesser General Public License for more details.
15   *
16   *  You should have received a copy of the GNU Lesser General Public
17   *  License along with this library; if not, write to the Free Software
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   *
20   *  Contributor(s):
21   *    Shane Harper
22   */
23   
24  package javax.microedition.lcdui;
25  
26  public class ChoiceGroup extends Item implements Choice
27  {
28      int choiceType;
29  
30      private ChoiceItem items[] = new ChoiceItem[4];
31      
32      private int numOfItems = 0;
33    
34      private int fitPolicy;
35      
36      private int highlightedItemIndex = -1;  
37      
38      private List popupList;
39  
40  	private static byte multiOff[] = {
41    		-119, 80, 78, 71, 13, 10, 26, 10, 0, 0,
42    		0, 13, 73, 72, 68, 82, 0, 0, 0, 10,
43          0, 0, 0, 11, 2, 3, 0, 0, 0, 59,
44          0, -12, -117, 0, 0, 0, 6, 80, 76, 84,
45          69, -1, -1, -1, -69, -69, -69, -57, 75, -33,
46          -8, 0, 0, 0, 30, 73, 68, 65, 84, 120,
47          -38, 99, 96, 96, 96, 96, 12, 101, -8, -51,
48          -32, -64, 32, -64, -60, -64, -64, -128, 11, 51,
49          -122, 50, -4, 6, 0, 63, 116, 3, 1, 53,
50          -108, 39, -26, 0, 0, 0, 0, 73, 69, 78,
51          68, -82, 66, 96, -126 
52      };
53  
54  	private static byte multiOn[] = {
55  	    -119, 80, 78, 71, 13, 10, 26, 10, 0, 0,
56          0, 13, 73, 72, 68, 82, 0, 0, 0, 10,
57          0, 0, 0, 11, 2, 3, 0, 0, 0, 59,
58          0, -12, -117, 0, 0, 0, 12, 80, 76, 84,
59          69, -1, -1, -1, -69, -69, -69, 106, 106, 106,
60          2, 2, 2, 106, -103, 14, -47, 0, 0, 0,
61          53, 73, 68, 65, 84, 120, -38, 99, 96, 96,
62          124, -64, -16, -1, -77, 3, -45, 65, -111, 15,
63          76, 12, 108, 12, 76, 12, -4, 12, 76, 12,
64          18, 12, 76, -68, 127, 24, -104, 126, 45, 96,
65          96, -7, -11, -109, -127, -23, -65, 3, 3, -29,
66          127, -122, -113, 0, 5, 37, 12, -34, 1, -99,
67          -83, 100, 0, 0, 0, 0, 73, 69, 78, 68,
68          -82, 66, 96, -126 
69      };
70  
71  	private static byte radioOff[] = {
72  	    -119, 80, 78, 71, 13, 10, 26, 10, 0, 0,
73  	    0, 13, 73, 72, 68, 82, 0, 0, 0, 11,
74  	    0, 0, 0, 11, 2, 3, 0, 0, 0, -44,
75  	    -62, -97, -75, 0, 0, 0, 9, 80, 76, 84,
76  	    69, -1, -1, -1, -69, -69, -69, 106, 106, 106,
77  	    -44, 13, -1, -24, 0, 0, 0, 42, 73, 68,
78  	    65, 84, 120, -38, 99, 96, 90, -59, -64, 32,
79  	    -63, 48, -127, 65, -127, 65, -127, 41, -127, -31,
80  	    5, 19, 3, 3, 3, 50, 102, 80, 96, 80,
81  	    96, -6, -63, 80, -64, -64, -76, -118, 1, 0,
82  	    113, 24, 5, 61, 73, -68, -100, 98, 0, 0,
83  	    0, 0, 73, 69, 78, 68, -82, 66, 96, -126 
84      };
85  
86  	private static byte radioOn[] = {
87          -119, 80, 78, 71, 13, 10, 26, 10, 0, 0,
88          0, 13, 73, 72, 68, 82, 0, 0, 0, 11,
89          0, 0, 0, 11, 2, 3, 0, 0, 0, -44,
90          -62, -97, -75, 0, 0, 0, 12, 80, 76, 84,
91          69, -1, -1, -1, -69, -69, -69, 106, 106, 106,
92          2, 2, 2, 106, -103, 14, -47, 0, 0, 0,
93          50, 73, 68, 65, 84, 120, -38, 5, -63, 65,
94          13, 0, 32, 12, 4, -63, -19, -11, -117, 1,
95          18, 68, -100, 10, 52, 19, 94, 72, 64, 17,
96          101, -122, 44, -44, -29, 98, -52, 89, 77, -102,
97          40, 2, 85, -95, -73, -63, -104, -63, 37, -117,
98          15, -40, 119, 10, 41, 78, 26, -79, 59, 0,
99          0, 0, 0, 73, 69, 78, 68, -82, 66, 96,
100         -126 
101     };
102 
103 	private static final Image imgMultiOff = Image.createImage(multiOff, 0, multiOff.length);
104 	private static final Image imgMultiOn = Image.createImage(multiOn, 0, multiOn.length);
105 	private static final Image imgRadioOff = Image.createImage(radioOff, 0, radioOff.length);
106 	private static final Image imgRadioOn = Image.createImage(radioOn, 0, radioOn.length);
107 
108 
109 	public ChoiceGroup(String label, int choiceType) 
110 	{
111 		this(label, choiceType, true);
112 	}
113 
114 
115 	public ChoiceGroup(String label, int choiceType, String[] stringElements, Image[] imageElements)
116 	{
117 		this(label, choiceType, stringElements, imageElements, true);
118 	}
119 
120 
121 	ChoiceGroup(String label, int choiceType, boolean validateChoiceType)
122 	{
123 		super(label);
124 
125 		if (validateChoiceType) {
126 			if (choiceType != Choice.POPUP && choiceType != Choice.MULTIPLE && choiceType != Choice.EXCLUSIVE) {
127 				throw new IllegalArgumentException("Illegal choice type");
128 			}
129 		}
130 		this.choiceType = choiceType;
131 		if (choiceType == Choice.POPUP) {
132 			// POPUP has a hidden List to implement it's
133 			// behaviour
134 			popupList = new List(label, Choice.IMPLICIT);
135 			popupList.setCommandListener(new ImplicitListener());
136 		}
137 	}
138 
139 
140 	// XXX imageElements is ignored.
141 	ChoiceGroup(String label, int choiceType, String[] stringElements, Image[] imageElements, boolean validateChoiceType)
142 	{
143 		this(label, choiceType, validateChoiceType);
144 
145 		for (int i = 0; i < stringElements.length; i++) {
146 			if (imageElements == null) {
147 				append(stringElements[i], null);
148 			} else {
149 				append(stringElements[i], imageElements[i]);
150 			}
151 		}
152 	}
153 
154 	
155 	public int append(String stringPart, Image imagePart)
156   {
157 		insert(numOfItems, stringPart, imagePart);
158 
159     return (numOfItems - 1);
160   }
161 
162 
163   public void delete(int itemNum)
164   {
165 		if (itemNum < 0 || itemNum >= numOfItems) {
166 			throw new IndexOutOfBoundsException();
167 		}
168 
169     // Ensure that an item of an EXCLUSIVE list remains selected.
170     if ((Choice.EXCLUSIVE == choiceType || Choice.POPUP == choiceType)
171     		&& items[itemNum].isSelected()) {
172       if (numOfItems > 1) {
173         items[itemNum!=0 ? 0 : 1].setSelectedState(true);
174       }
175     }
176 
177     // Delete item.
178     if (itemNum != numOfItems - 1) {
179       System.arraycopy(items, itemNum+1, items, itemNum, numOfItems-itemNum-1);
180     }
181     numOfItems--;
182     // clear the slot to allow garbage collection
183     items[numOfItems] = null;
184 
185     // Ensure highlighted item remains highlighted (if it wasn't just deleted).
186     if (highlightedItemIndex > itemNum) {
187       --highlightedItemIndex;
188     }
189 
190     // Ensure that an item remains highlighted.
191     if (highlightedItemIndex >= numOfItems) {
192       highlightedItemIndex = numOfItems-1;
193     }
194     
195     if (choiceType == Choice.POPUP)
196 	  popupList.delete(itemNum);
197     repaint();
198   }
199   
200   public void deleteAll() {
201 	  // clear the array to allow garbage collection
202 	  for (int i = 0; i < numOfItems; i++)
203 		  items[i] = null;
204 	  numOfItems = 0;
205 	  highlightedItemIndex = -1;
206 	  if (choiceType == Choice.POPUP)
207 		  popupList.deleteAll();
208 	  repaint();
209   }
210 
211 
212   public int getFitPolicy() {
213 	  return fitPolicy;
214   }
215   
216   public Font getFont(int itemNum) {
217 		if (itemNum < 0 || itemNum >= numOfItems) {
218 			throw new IndexOutOfBoundsException();
219 		}
220 		return items[itemNum].getFont();
221   }
222   
223   
224   public Image getImage(int elementNum)
225   {
226 		if (elementNum < 0 || elementNum >= numOfItems) {
227 			throw new IndexOutOfBoundsException();
228 		}
229 
230     return items[elementNum].getImage();
231   }
232 
233 
234   /**
235    * Queries the state of a ChoiceGroup and returns the state of all elements in
236    * the boolean array selectedArray_return. NOTE: this is a result parameter.
237    * It must be at least as long as the size of the ChoiceGroup as returned by
238    * size(). If the array is longer, the extra elements are set to false.
239    *
240    * For ChoiceGroup objects of type MULTIPLE, any number of elements may be
241    * selected and set to true in the result array. For ChoiceGroup objects of
242    * type EXCLUSIVE, exactly one element will be selected, unless there are zero
243    * elements in the ChoiceGroup.
244    */
245   public int getSelectedFlags(boolean[] selectedArray_return)
246   {
247 		if (selectedArray_return == null) {
248 			throw new NullPointerException();
249 		}
250 		if (selectedArray_return.length < numOfItems) {
251 			throw new IllegalArgumentException();
252 		}
253 
254     // set selectedArray_return elements and count number of selected items
255 		int selectedItemsCount = 0;
256 		
257 			for (int i = 0; i < selectedArray_return.length; ++i) {
258 	      selectedArray_return[i] = (i<numOfItems) ? items[i].isSelected() : false;
259 	      if (selectedArray_return[i]) {
260 	        ++selectedItemsCount;
261 	      }
262     }
263 
264     return selectedItemsCount;
265   }
266 
267   /**
268    *  Returns the index number of an element in the ChoiceGroup that is
269    *  selected. For ChoiceGroup objects of type EXCLUSIVE there is at most one
270    *  element selected, so this method is useful for determining the user's
271    *  choice. Returns -1 if there are no elements in the ChoiceGroup.
272    *
273    *  For ChoiceGroup objects of type MULTIPLE, this always returns -1 because
274    *  no single value can in general represent the state of such a ChoiceGroup.
275    *  To get the complete state of a MULTIPLE Choice, see getSelectedFlags.
276    */
277   public int getSelectedIndex()
278   {
279     switch (choiceType) {
280       case Choice.EXCLUSIVE:
281       case Choice.POPUP:
282         // XXX It'd be nice if the selected item index was stored, so it isn't
283         //     necessary to search for it.
284         for (int i = 0; i < numOfItems; ++i) {
285           if (items[i].isSelected()) return i;
286         }
287         break;
288       case Choice.IMPLICIT:
289         return highlightedItemIndex;
290     }
291     return -1;
292   }
293 
294 
295   public String getString(int elementNum)
296   {
297 		if (elementNum < 0 || elementNum >= numOfItems) {
298 			throw new IndexOutOfBoundsException();
299 		}
300 
301     return items[elementNum].getText();
302   }
303 
304 
305   public void insert(int elementNum, String stringPart, Image imagePart)
306   {
307 		if (elementNum < 0 || elementNum > numOfItems) {
308 			throw new IndexOutOfBoundsException();
309 		}
310 		if (stringPart == null) {
311 			throw new NullPointerException();
312 		}
313 
314 		if (choiceType == Choice.POPUP) {
315 			  popupList.insert(elementNum, stringPart, imagePart);
316 		}
317 
318 	if (numOfItems == items.length  /*no space left in item array*/) {
319       ChoiceItem newItems[] = new ChoiceItem[numOfItems + 4];
320       System.arraycopy(items, 0, newItems, 0, numOfItems);
321       items = newItems;
322     }
323 
324     System.arraycopy(items, elementNum, items, elementNum + 1,
325                      numOfItems - elementNum);
326   
327 	  items[elementNum] = new ChoiceItem(null, imagePart, stringPart);
328 
329     ++numOfItems;
330 
331     if (numOfItems == 1) {
332       highlightedItemIndex = 0;
333       if (Choice.EXCLUSIVE == choiceType ||
334     		  Choice.POPUP == choiceType) {
335         setSelectedIndex(0, true);
336       }
337     }
338     
339     repaint();
340   }
341 
342 
343   public boolean isSelected(int elementNum)
344   {
345 		if (elementNum < 0 || elementNum >= numOfItems) {
346 			throw new IndexOutOfBoundsException();
347 		}
348 
349     return items[elementNum].isSelected();
350   }
351 
352 
353   public void set(int elementNum, String stringPart, Image imagePart)
354 	{
355 		if (elementNum < 0 || elementNum >= numOfItems) {
356 			throw new IndexOutOfBoundsException();
357 		}
358 		if (imagePart != null && imagePart.isMutable()) {
359 			throw new IllegalArgumentException();
360 		}
361 		if (stringPart == null) {
362 			throw new NullPointerException();
363 		}
364 
365 		items[elementNum].setText(stringPart);
366 		items[elementNum].setImage(imagePart);
367 
368 		if (choiceType == Choice.POPUP) {
369 			  popupList.set(elementNum, stringPart, imagePart);
370 		}
371 		
372 		repaint();
373   }
374 
375   public void setFitPolicy(int policy) {
376 	  if (policy != Choice.TEXT_WRAP_DEFAULT &&
377 			  	policy != Choice.TEXT_WRAP_ON &&
378 			  	policy != Choice.TEXT_WRAP_OFF)
379 		  throw new IllegalArgumentException("Bad Policy");
380 	  fitPolicy = policy;
381 		if (choiceType == Choice.POPUP) {
382 			  popupList.setFitPolicy(policy);
383 		}
384   }
385   
386   public void setFont(int itemNum, Font font) {
387 		if (itemNum < 0 || itemNum >= numOfItems) {
388 			throw new IndexOutOfBoundsException();
389 		}
390 		items[itemNum].setFont(font);
391 		if (choiceType == Choice.POPUP) {
392 			  popupList.setFont(itemNum, font);
393 		}
394   }
395 
396 
397   public void setSelectedFlags(boolean[] selectedArray)
398   {
399 		if (selectedArray == null) {
400 			throw new NullPointerException();
401 		}
402 		if (selectedArray.length < numOfItems) {
403 			throw new NullPointerException();
404 		}
405 		
406 		if (numOfItems == 0)
407 			return;
408 
409 		if (choiceType == Choice.MULTIPLE) {
410 			for (int i = 0; i < numOfItems; i++) {
411 				setSelectedIndex(i, selectedArray[i]);
412 			}
413 		} else {
414 			int selectedItem = -1;
415 			for (int i = 0; i < numOfItems; i++) {
416 				if (selectedArray[i]) {
417 					setSelectedIndex(i, true);
418 					selectedItem = i;
419 					break;
420 				}
421 			}
422 			if (selectedItem == -1) {
423 				setSelectedIndex(0, true);
424 			}
425 			
426 			if (choiceType == Choice.POPUP) {
427 				popupList.setSelectedFlags(selectedArray);
428 			}
429 		}
430 
431   }
432 
433 
434   public void setSelectedIndex(int elementNum, boolean selected)
435   {
436 		if (elementNum < 0 || elementNum >= numOfItems) {
437 			throw new IndexOutOfBoundsException();
438 		}
439 
440         highlightedItemIndex = elementNum;
441 		if ((choiceType == Choice.EXCLUSIVE ||
442 				choiceType == Choice.POPUP) && selected) {
443 			for (int i = 0; i < numOfItems; i++) {
444 				items[i].setSelectedState(elementNum == i);
445 			}
446 			if (choiceType == Choice.POPUP) {
447 			        popupList.setSelectedIndex(elementNum, true);
448 		    }
449 			 repaint();
450 		} else if (choiceType == Choice.MULTIPLE) {
451 			items[elementNum].setSelectedState(selected);
452 			repaint();
453 		} else if (choiceType == Choice.IMPLICIT) {
454 		    if (selected) {
455 				items[elementNum].setSelectedState(selected);
456 				repaint();
457 		    }
458 		}
459   }
460 
461 
462   public int size()
463   {
464     return numOfItems;
465   }
466 
467 
468 	boolean isFocusable()
469 	{
470 		return true;
471 	}
472 
473 
474 	int getHeight()
475 	{
476 		int height = 0;
477 		if (choiceType == Choice.POPUP) {
478 			if (highlightedItemIndex != -1) {
479 				height += items[highlightedItemIndex].getHeight();
480 			}
481 		} else {
482 			for (int i = 0; i < numOfItems; i++) {
483 				height += items[i].getHeight();
484 			}
485 		}
486 
487 		return super.getHeight() + height;
488 	}
489 	
490 	/*
491 	 * Get item index from coordinates
492 	 */
493 	int getItemIndexAt(int x, int y)
494 	{
495 		x -= super.getHeight();
496 		int testY = 0;
497 		for (int i = 0; i < numOfItems; i++) {
498 			testY += items[i].getHeight();
499 			if (y < testY) {
500 				return i;
501 			}
502 		}
503 		
504 		return -1;
505 	}
506 	
507 	
508 	int getHeightToItem(int itemIndex) 
509 	{
510 		int height = 0;
511 
512 		for (int i = 0; i < itemIndex; i++) {
513 			height += items[i].getHeight();
514 		}
515 
516 		return height;
517 	}
518 
519 
520 	int getItemHeight(int itemIndex)
521 	{
522 		return items[itemIndex].getHeight();
523 	}
524 	
525 	
526   int paint(Graphics g)
527   {
528 		super.paintContent(g);
529 
530 		g.translate(0, super.getHeight());
531 		int translatedY = 0;
532 		
533 		if (choiceType == Choice.POPUP) {
534 			int index = getSelectedIndex();
535 			if (index != -1) {
536 				items[index].invertPaint(hasFocus());
537 				items[index].paint(g);
538 			}
539 			g.translate(0, -super.getHeight());
540 		} else {
541 			for (int i = 0; i < numOfItems; i++) {
542 				items[i].invertPaint(i == highlightedItemIndex && hasFocus());
543 				items[i].paint(g);
544 				g.translate(0, items[i].getHeight());
545 				translatedY += items[i].getHeight();
546 			}
547 			g.translate(0, -translatedY);
548 			g.translate(0, -super.getHeight());
549 		}
550 
551 		return getHeight();
552   }
553 
554 
555   boolean select()
556   {
557     if (numOfItems == 0) {
558       return false;
559     }
560 
561     if (choiceType == Choice.POPUP) {
562         getOwner().currentDisplay.setCurrent(popupList);
563     } else {
564 	    // XXX What does the following statement do?
565     	
566     	// It is correct, in the case of multiple inverts the selected
567     	// state, in exclusive selects the highligthed
568     	// and in implicit it does nothing
569     	// Andres Navarro
570 	    setSelectedIndex(highlightedItemIndex, !items[highlightedItemIndex].isSelected());
571     }
572 
573     return true;
574   }
575 
576   
577   
578   int traverse(int gameKeyCode, int top, int bottom, boolean action)
579   {
580 	  
581 	if (this.choiceType == Choice.POPUP) {
582 		// POPUP has a totally different behaviour
583 	    if (gameKeyCode == Canvas.UP) {
584 			if (top > 0) {
585 				return -top;
586 			} else {
587 				return Item.OUTOFITEM;
588 			}
589 	    } else if (gameKeyCode == Canvas.DOWN) {
590 	    	if (!action) {
591 	    		int height = super.getHeight();
592 				int index = getSelectedIndex();
593 				if (index != -1) {
594 	    			height += items[index].getHeight();
595 				}
596 
597 				if (height > bottom) {
598 	    			return height - bottom;
599 	    		} else {
600 	    			repaint();
601 	    		}
602 		     } else {
603 		    	 return Item.OUTOFITEM;
604 			}
605 	    }
606 	} else {
607 	    if (gameKeyCode == Canvas.UP) {
608 	      if (highlightedItemIndex > 0) {
609 					if (action) {
610 						highlightedItemIndex--;
611 					}
612 					int height = super.getHeight();
613 					for (int i = 0; i < highlightedItemIndex; i++) {
614 						height += items[i].getHeight();
615 					}
616 					if (height < top) {
617 						return height - top;
618 					} else {
619 						repaint();
620 					}
621 	      } else {
622 					if (top > 0) {
623 						return -top;
624 					} else {
625 						return Item.OUTOFITEM;
626 					}
627 				}
628 	    }
629 	    if (gameKeyCode == Canvas.DOWN) {
630 	      if ((!action && highlightedItemIndex < numOfItems)
631 	      		|| (action && highlightedItemIndex < (numOfItems - 1))) {
632 					if (action) {
633 						highlightedItemIndex++;
634 					}
635 					int height = super.getHeight();
636 					for (int i = 0; i <= highlightedItemIndex; i++) {
637 						height += items[i].getHeight();
638 					}
639 					if (height > bottom) {
640 						return height - bottom;
641 					} else {
642 						repaint();
643 					}
644 	      } else {
645 					return Item.OUTOFITEM;
646 		  }
647 	    }
648 	}
649 
650 		return 0;
651   }
652 
653   void repaint() {
654 	  // the popup list should be repainted
655 	  // in the case it is being shown
656 	  if (choiceType == Choice.POPUP)
657 		  popupList.repaint();
658 	  super.repaint();
659   }
660 
661   class ChoiceItem extends ImageStringItem
662   {
663     private boolean selected;
664     private Font font;
665     Image box;
666            
667 
668     ChoiceItem(String label, Image image, String text)
669     {
670       super(label, image, text);
671       setSelectedState(false);
672       font = Font.getDefaultFont();
673     }
674 
675     Font getFont() {
676     	return font;
677     }
678     
679     	public void setImage(Image img)
680 	{
681                 this.img = img;
682 		
683                 int width = 0;
684                 if (box != null) width+=box.getWidth();
685                 if (this.img != null) width+=img.getWidth();
686                 if (width > 0) width+=2;
687                 stringComponent.setWidthDecreaser(width);
688 	}
689 
690 	int getHeight()
691 	{
692                 int height =  0;
693                 if (box != null) height = box.getHeight();                
694 		if (img != null && img.getHeight() > height) {
695 			height = img.getHeight();
696                 }
697 		if (stringComponent.getHeight() > height) {
698                             height = stringComponent.getHeight();                
699 		}
700                 return height;
701 	}
702 
703   int paint(Graphics g)
704   {
705 		if (stringComponent == null) {
706 			return 0;
707 		}
708 
709                 int widthAddition = 0;
710 		if (box != null) {
711 			g.drawImage(box, 0, 0, Graphics.LEFT | Graphics.TOP);
712 			if (img != null) {
713                             widthAddition = box.getWidth();
714                             g.translate(box.getWidth(), 0);
715                         }
716                         else {
717                             widthAddition = box.getWidth() + 2;
718                             g.translate(box.getWidth() + 2, 0);
719                         }
720 		}
721                 
722                 
723 		if (img != null) {
724                         widthAddition += img.getWidth() + 2;
725 			g.drawImage(img, 0, 0, Graphics.LEFT | Graphics.TOP);
726 			g.translate(img.getWidth() + 2, 0);
727 		}
728 
729 		int y = stringComponent.paint(g);
730 
731 		if (widthAddition != 0) {
732 			g.translate(-widthAddition, 0);
733 		}
734 
735 		return y;
736   }
737         
738         
739     
740     boolean isSelected()
741     {
742       return selected;
743     }
744 
745     void setFont(Font f) {
746 		if (f == null)
747 			throw new NullPointerException();
748     	// only allow fonts of the same height
749     	// for now (to simplify the layout)
750     	if (f.getHeight() == font.getHeight())
751     		font = f;
752     }
753     
754     void setSelectedState(boolean state)
755     {
756       selected = state;
757       
758       if (choiceType != Choice.IMPLICIT && choiceType != Choice.POPUP) {
759             box = (Choice.EXCLUSIVE  == choiceType ? 
760 						(state? imgRadioOn:imgRadioOff) : (state? imgMultiOn:imgMultiOff));
761       }
762     }
763   }
764 
765   class ImplicitListener implements CommandListener {
766 		public void commandAction(Command c, Displayable d) {
767 			List list = (List) d;
768 			setSelectedIndex(list.getSelectedIndex(), true);
769 			try {
770 				getOwner().currentDisplay.setCurrent(getOwner());
771 				repaint();
772 			} catch (NullPointerException n) {
773 				// this happens if the item becomes an orphan
774 				// (ie not owned by a Form, shouldn't happen
775 				// if correct programming practices are used!!)
776 			}
777 		}
778 	}
779 }