1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
133
134 popupList = new List(label, Choice.IMPLICIT);
135 popupList.setCommandListener(new ImplicitListener());
136 }
137 }
138
139
140
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
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
178 if (itemNum != numOfItems - 1) {
179 System.arraycopy(items, itemNum+1, items, itemNum, numOfItems-itemNum-1);
180 }
181 numOfItems--;
182
183 items[numOfItems] = null;
184
185
186 if (highlightedItemIndex > itemNum) {
187 --highlightedItemIndex;
188 }
189
190
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
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
236
237
238
239
240
241
242
243
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
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
269
270
271
272
273
274
275
276
277 public int getSelectedIndex()
278 {
279 switch (choiceType) {
280 case Choice.EXCLUSIVE:
281 case Choice.POPUP:
282
283
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
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
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
565
566
567
568
569
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
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
655
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
749
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
774
775
776 }
777 }
778 }
779 }