Source code: javax/microedition/lcdui/Form.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 modify it
6 * under the terms of the GNU Lesser General Public License as published by the
7 * Free Software Foundation; either version 2.1 of the License, or (at your
8 * option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Contributor(s):
20 * 3GLab
21 */
22
23 package javax.microedition.lcdui;
24
25 public class Form extends Screen
26 {
27 Item items[] = new Item[4];
28 int numOfItems = 0;
29 int focusItemIndex;
30 ItemStateListener itemStateListener = null;
31
32
33 public Form(String title)
34 {
35 super(title);
36 focusItemIndex = -2;
37 }
38
39
40 public Form(String title, Item[] items)
41 {
42 this(title);
43
44 this.items = items;
45 numOfItems = items.length;
46 for (int i = 0; i < numOfItems; i++) {
47 verifyItem(items[i]);
48 }
49 }
50
51
52 public int append(Item item)
53 {
54 verifyItem(item);
55
56 if (numOfItems + 1 == items.length) {
57 Item newitems[] = new Item[numOfItems + 4];
58 System.arraycopy(items, 0, newitems, 0, numOfItems);
59 items = newitems;
60 }
61 items[numOfItems] = item;
62 numOfItems++;
63
64 return (numOfItems - 1);
65 }
66
67
68 public int append(Image img)
69 {
70 return append(new ImageItem(null, img, ImageItem.LAYOUT_DEFAULT, null));
71 }
72
73
74 public int append(String str)
75 {
76 if (str == null) {
77 throw new NullPointerException();
78 }
79
80 return append(new StringItem(null, str));
81 }
82
83
84 public void delete(int itemNum)
85 {
86 verifyItemNum(itemNum);
87
88 items[itemNum].setOwner(null);
89 System.arraycopy(
90 items,
91 itemNum + 1,
92 items,
93 itemNum,
94 numOfItems - itemNum - 1);
95 numOfItems--;
96 }
97
98
99 public Item get(int itemNum)
100 {
101 verifyItemNum(itemNum);
102
103 return items[itemNum];
104 }
105
106
107 public void insert(int itemNum, Item item)
108 {
109 verifyItemNum(itemNum);
110 verifyItem(item);
111
112 if (numOfItems + 1 == items.length) {
113 Item newitems[] = new Item[numOfItems + 4];
114 System.arraycopy(items, 0, newitems, 0, numOfItems);
115 items = newitems;
116 }
117 System.arraycopy(
118 items,
119 itemNum,
120 items,
121 itemNum + 1,
122 numOfItems - itemNum);
123 items[itemNum] = item;
124 items[itemNum].setOwner(this);
125 numOfItems++;
126 }
127
128
129 public void set(int itemNum, Item item)
130 {
131 verifyItemNum(itemNum);
132 verifyItem(item);
133
134 items[itemNum] = item;
135 items[itemNum].setOwner(this);
136 }
137
138
139 public void setItemStateListener(ItemStateListener iListener)
140 {
141 itemStateListener = iListener;
142 }
143
144
145 public int size()
146 {
147 return numOfItems;
148 }
149
150
151 int paintContent(Graphics g)
152 {
153 int contentHeight = 0;
154 int translateY;
155 for (int i = 0; i < numOfItems; i++) {
156 translateY = items[i].paint(g);
157 g.translate(0, translateY);
158 contentHeight += translateY;
159 }
160 g.translate(0, -contentHeight);
161
162 return contentHeight;
163 }
164
165
166 int getHeight()
167 {
168 int height = 0;
169
170 for (int i = 0; i < numOfItems; i++) {
171 height += items[i].getHeight();
172 }
173
174 return height;
175 }
176
177
178 void hideNotify()
179 {
180 super.hideNotify();
181
182 for (int i = 0; i < numOfItems; i++) {
183 if (items[i].isFocusable() && items[i].hasFocus()) {
184 items[i].setFocus(false);
185 focusItemIndex = -2;
186 break;
187 }
188 }
189 }
190
191
192 void keyPressed(int keyCode)
193 {
194 if (focusItemIndex != -1) {
195 if (Display.getGameAction(keyCode) == Canvas.FIRE) {
196 items[focusItemIndex].select();
197 if (itemStateListener != null) {
198 itemStateListener.itemStateChanged(items[focusItemIndex]);
199 }
200 } else {
201 items[focusItemIndex].keyPressed(keyCode);
202 }
203 }
204
205 super.keyPressed(keyCode);
206 }
207
208
209 void showNotify()
210 {
211 super.showNotify();
212
213 if (focusItemIndex == -2) {
214 focusItemIndex = -1;
215
216 for (int i = 0; i < numOfItems; i++) {
217 if (items[i].isFocusable()) {
218 items[i].setFocus(true);
219 focusItemIndex = i;
220 break;
221 }
222 }
223 }
224 }
225
226
227 int traverse(int gameKeyCode, int top, int bottom)
228 {
229 int height, testItemIndex, traverse, i;
230 int topItemIndex, bottomItemIndex;
231
232 if (numOfItems == 0) {
233 return 0;
234 }
235
236 if (gameKeyCode == Canvas.UP) {
237 topItemIndex = getTopVisibleIndex(top);
238 if (focusItemIndex == -1) {
239 testItemIndex = topItemIndex;
240 height = getHeightToItem(testItemIndex);
241 traverse =
242 items[testItemIndex].traverse(
243 gameKeyCode,
244 top - height,
245 bottom - height,
246 false);
247 } else {
248 testItemIndex = focusItemIndex;
249 height = getHeightToItem(testItemIndex);
250 traverse =
251 items[testItemIndex].traverse(
252 gameKeyCode,
253 top - height,
254 bottom - height,
255 true);
256 }
257 if (traverse != Item.OUTOFITEM) {
258 if (focusItemIndex == -1
259 && items[testItemIndex].isFocusable()) {
260 items[testItemIndex].setFocus(true);
261 focusItemIndex = testItemIndex;
262 }
263 return traverse;
264 } else {
265 if (testItemIndex > 0) {
266 // Czy istnieje obiekt focusable powyzej testItemIndex
267 // widoczny na ekranie
268 // jesli tak to zrob na nim traverse(false) i return
269 // traverse
270 for (i = testItemIndex - 1; i >= topItemIndex; i--) {
271 if (items[i].isFocusable()) {
272 if (focusItemIndex != -1) {
273 items[focusItemIndex].setFocus(false);
274 }
275 items[i].setFocus(true);
276 focusItemIndex = i;
277 height = getHeightToItem(i);
278 traverse =
279 items[i].traverse(
280 gameKeyCode,
281 top - height,
282 bottom - height,
283 false);
284 if (traverse == Item.OUTOFITEM) {
285 return 0;
286 } else {
287 return traverse;
288 }
289 }
290 }
291 // Na najnizszym widocznym item zrob traverse(false)
292 height = getHeightToItem(topItemIndex);
293 traverse =
294 items[topItemIndex].traverse(
295 gameKeyCode,
296 top - height,
297 bottom - height,
298 false);
299 if (traverse == Item.OUTOFITEM) {
300 } else {
301 // Sprawdzenie czy znajduje sie powyzej na ekranie
302 // focusable item
303 // jesli tak zrob co trzeba
304 bottomItemIndex = getTopVisibleIndex(bottom + traverse);
305 if (focusItemIndex != -1
306 && focusItemIndex > bottomItemIndex) {
307 items[focusItemIndex].setFocus(false);
308 focusItemIndex = -1;
309 }
310 return traverse;
311 }
312 }
313 }
314 }
315 if (gameKeyCode == Canvas.DOWN) {
316 bottomItemIndex = getBottomVisibleIndex(bottom);
317 if (focusItemIndex == -1) {
318 testItemIndex = bottomItemIndex;
319 height = getHeightToItem(testItemIndex);
320 traverse =
321 items[testItemIndex].traverse(
322 gameKeyCode,
323 top - height,
324 bottom - height,
325 false);
326 } else {
327 testItemIndex = focusItemIndex;
328 height = getHeightToItem(testItemIndex);
329 traverse =
330 items[testItemIndex].traverse(
331 gameKeyCode,
332 top - height,
333 bottom - height,
334 true);
335 }
336 if (traverse != Item.OUTOFITEM) {
337 if (focusItemIndex == -1
338 && items[testItemIndex].isFocusable()) {
339 items[testItemIndex].setFocus(true);
340 focusItemIndex = testItemIndex;
341 }
342 return traverse;
343 } else {
344 if (testItemIndex < numOfItems - 1) {
345 // Czy istnieje obiekt focusable ponizej testItemIndex
346 // widoczny na ekranie
347 // jesli tak to zrob na nim traverse(false) i return
348 // traverse
349 for (i = testItemIndex + 1; i <= bottomItemIndex; i++) {
350 if (items[i].isFocusable()) {
351 if (focusItemIndex != -1) {
352 items[focusItemIndex].setFocus(false);
353 }
354 items[i].setFocus(true);
355 focusItemIndex = i;
356 height = getHeightToItem(i);
357 traverse =
358 items[i].traverse(
359 gameKeyCode,
360 top - height,
361 bottom - height,
362 false);
363 if (traverse == Item.OUTOFITEM) {
364 return 0;
365 } else {
366 return traverse;
367 }
368 }
369 }
370 // Na najnizszym widocznym item zrob traverse(false)
371 height = getHeightToItem(bottomItemIndex);
372 traverse =
373 items[bottomItemIndex].traverse(
374 gameKeyCode,
375 top - height,
376 bottom - height,
377 false);
378 if (traverse == Item.OUTOFITEM) {
379 } else {
380 // Sprawdzenie czy znajduje sie powyzej na ekranie
381 // focusable item
382 // jesli tak zrob co trzeba
383 topItemIndex = getTopVisibleIndex(top + traverse);
384 if (focusItemIndex != -1
385 && focusItemIndex < topItemIndex) {
386 items[focusItemIndex].setFocus(false);
387 focusItemIndex = -1;
388 }
389 return traverse;
390 }
391 }
392 }
393 }
394
395 return 0;
396 }
397
398
399 int getTopVisibleIndex(int top)
400 {
401 int height = 0;
402
403 for (int i = 0; i < numOfItems; i++) {
404 height += items[i].getHeight();
405 if (height >= top) {
406 return i;
407 }
408 }
409
410 return numOfItems - 1;
411 }
412
413
414 int getBottomVisibleIndex(int bottom)
415 {
416 int height = 0;
417
418 for (int i = 0; i < numOfItems; i++) {
419 height += items[i].getHeight();
420 if (height > bottom) {
421 return i;
422 }
423 }
424
425 return numOfItems - 1;
426 }
427
428
429 int getHeightToItem(int itemIndex)
430 {
431 int height = 0;
432
433 for (int i = 0; i < itemIndex; i++) {
434 height += items[i].getHeight();
435 }
436
437 return height;
438 }
439
440 /**
441 * Verify that the item is non null and is not owned by this form or anyone
442 * else. If all is ok set the owner to this Form
443 *
444 * @param item the item to be verified
445 * @throws IllegalStateException
446 * @throws NullPointerException
447 */
448 private void verifyItem(Item item)
449 {
450 // Check that we are being passed valid items
451 if (item == null) {
452 throw new NullPointerException("item is null");
453 }
454 if (item.getOwner() != null) {
455 throw new IllegalStateException("item is already owned");
456 }
457 // All is ok make ourselves the owner
458 item.setOwner(this);
459 }
460
461 /**
462 * Verify that the index passed in is valid for this form. ie within the
463 * range 0..size-1
464 *
465 * @param itemNum the number of the item
466 * @throws IndexOutOfBoundsException
467 */
468 private void verifyItemNum(int itemNum)
469 {
470 if (itemNum < 0 || itemNum >= numOfItems) {
471 throw new IndexOutOfBoundsException("item number is outside range of Form");
472 }
473 }
474
475 }