Source Code Cross Referenced for Form.java in  » 6.0-JDK-Modules » j2me » javax » microedition » lcdui » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » javax.microedition.lcdui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *   
003:         *
004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006:         * 
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License version
009:         * 2 only, as published by the Free Software Foundation.
010:         * 
011:         * This program is distributed in the hope that it will be useful, but
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014:         * General Public License version 2 for more details (a copy is
015:         * included at /legal/license.txt).
016:         * 
017:         * You should have received a copy of the GNU General Public License
018:         * version 2 along with this work; if not, write to the Free Software
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA
021:         * 
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023:         * Clara, CA 95054 or visit www.sun.com if you need additional
024:         * information or have any questions.
025:         */
026:
027:        package javax.microedition.lcdui;
028:
029:        /**
030:         * A <code>Form</code> is a <code>Screen</code> that contains
031:         * an arbitrary mixture of items: images,
032:         * read-only text fields, editable text fields, editable date fields, gauges,
033:         * choice groups, and custom items. In general, any subclass of the
034:         * {@link Item Item} class may be contained within a form.
035:         * The implementation handles layout, traversal, and scrolling.
036:         * The entire contents of the <code>Form</code> scrolls together.
037:         *
038:         * <h2>Item Management</h2>
039:         * <p>
040:         * The items contained within a <code>Form</code> may be edited
041:         * using append, delete,
042:         * insert, and set methods.  <code>Items</code> within a
043:         * <code>Form</code> are referred to by their
044:         * indexes, which are consecutive integers in the range from zero to
045:         * <code>size()-1</code>,
046:         * with zero referring to the first item and <code>size()-1</code>
047:         * to the last item.  </p>
048:         *
049:         * <p> An item may be placed within at most one
050:         * <code>Form</code>. If the application
051:         * attempts to place an item into a <code>Form</code>, and the
052:         * item is already owned by this
053:         * or another <code>Form</code>, an
054:         * <code>IllegalStateException</code> is thrown.
055:         * The application must
056:         * remove the item from its currently containing <code>Form</code>
057:         * before inserting it into
058:         * the new <code>Form</code>. </p>
059:         *
060:         * <p> If the <code>Form</code> is visible on the display when
061:         * changes to its contents are
062:         * requested by the application, updates to the display take place as soon
063:         * as it is feasible for the implementation to do so.
064:         * Applications need not take any special action to refresh a
065:         * <code>Form's</code> display
066:         * after its contents have been modified. </p>
067:         *
068:         * <a name="layout"></a>
069:         * <h2>Layout</h2>
070:         *
071:         * <p>Layout policy in <code>Form</code> is organized around
072:         * rows. Rows are typically
073:         * related to the width of the screen, respective of margins, scroll bars, and
074:         * such.  All rows in a particular <code>Form</code> will have the
075:         * same width.  Rows do not
076:         * vary in width based on the <code>Items</code> contained within
077:         * the <code>Form</code>, although they
078:         * may all change width in certain circumstances, such as when a scroll bar
079:         * needs to be added or removed. <code>Forms</code> generally do not scroll
080:         * horizontally.</p>
081:         *
082:         * <p><code>Forms</code> grow vertically and scroll vertically as
083:         * necessary. The height
084:         * of a <code>Form</code> varies depending upon the number of rows
085:         * and the height of
086:         * each row. The height of each row is determined by the items that are
087:         * positioned on that row. Rows need not all have the same height.
088:         * Implementations may also vary row heights to provide proper padding or
089:         * vertical alignment of <code>Item</code> labels.</p>
090:         *
091:         * <p>An implementation may choose to lay out <code>Items</code> in a
092:         * left-to-right or right-to-left direction depending upon the language
093:         * conventions in use.  The same choice of layout direction must apply to all
094:         * rows within a particular <code>Form</code>.</p>
095:         *
096:         * <p>Prior to the start of the layout algorithm, the
097:         * <code>Form</code> is considered to
098:         * have one empty row at the top. The layout algorithm considers each Item
099:         * in turn, starting at <code>Item</code> zero and proceeding in
100:         * order through each <code>Item</code>
101:         * until the last <code>Item</code> in the <code>Form</code>
102:         * has been processed.
103:         * If the layout direction (as described above) is left-to-right, the
104:         * beginning of the row is the left edge of the <code>Form</code>.  If the
105:         * layout direction is right-to-left, the beginning of the row is the right
106:         * edge of the <code>Form</code>.  <code>Items</code> are laid out at the
107:         * beginning of each row, proceeding across each row in the chosen layout
108:         * direction, packing as many <code>Items</code> onto each row as will fit,
109:         * unless a condition occurs that causes the packing of a row to be terminated
110:         * early.
111:         * A new row is then added, and
112:         * <code>Items</code> are packed onto it
113:         * as described above. <code>Items</code> are packed onto rows,
114:         * and new rows are added
115:         * below existing rows as necessary until all <code>Items</code>
116:         * have been processed by
117:         * the layout algorithm.</p>
118:         *
119:         * <p>The layout algorithm has a concept of a <em>current alignment</em>.
120:         * It can have the value <code>LAYOUT_LEFT</code>,
121:         * <code>LAYOUT_CENTER</code>, or <code>LAYOUT_RIGHT</code>.
122:         * The value of the current alignment at the start of the layout algorithm
123:         * depends upon the layout direction in effect for this <code>Form</code>.  If
124:         * the layout direction is left-to-right, the initial alignment value must be
125:         * <code>LAYOUT_LEFT</code>.  If the layout direction is right-to-left, the
126:         * initial alignment value must be <code>LAYOUT_RIGHT</code>.
127:         * The current alignment changes when the layout
128:         * algorithm encounters an <code>Item</code> that has one of the layout
129:         * directives <code>LAYOUT_LEFT</code>, <code>LAYOUT_CENTER</code>, or
130:         * <code>LAYOUT_RIGHT</code>.  If none of these directives is present on an
131:         * <code>Item</code>, the current layout directive does not change.  This
132:         * rule has the effect of grouping the contents of the
133:         * <code>Form</code> into sequences of consecutive <code>Items</code>
134:         * sharing an alignment value.  The alignment value of each <code>Item</code>
135:         * is maintained internally to the <code>Form</code> and does not affect the
136:         * <code>Items'</code> layout value as reported by the
137:         * {@link Item#getLayout Item.getLayout} method.</p>
138:         *
139:         * <p>The layout algorithm generally attempts to place an item on the same
140:         * row as the previous item, unless certain conditions occur that cause a
141:         * &quot;row break.&quot; When there is a row break, the current item
142:         * will be placed
143:         * at the beginning of a new row instead of being placed after
144:         * the previous item, even if there is room.</p>
145:         *
146:         * <p>A row break occurs before an item if any of the following
147:         * conditions occurs:</p>
148:         *
149:         * <ul>
150:         * <li>the previous item has a row break after it;</li>
151:         * <li>it has the <code>LAYOUT_NEWLINE_BEFORE</code> directive; or</li>
152:         * <li>it is a <code>StringItem</code> whose contents starts with
153:         * &quot;\n&quot;;</li>
154:         * <li>it is a
155:         * <code>ChoiceGroup</code>, <code>DateField</code>,
156:         * <code>Gauge</code>, or a <code>TextField</code>, and the
157:         * <code>LAYOUT_2</code> directive is not set; or</li>
158:         * <li>this <code>Item</code> has a <code>LAYOUT_LEFT</code>,
159:         * <code>LAYOUT_CENTER</code>, or <code>LAYOUT_RIGHT</code> directive
160:         * that differs from the <code>Form's</code> current alignment.</li>
161:         * </ul>
162:         *
163:         * <p>A row break occurs after an item if any of the following
164:         * conditions occurs:</p>
165:         *
166:         * <ul>
167:         * <li>it is a <code>StringItem</code> whose contents ends with
168:         * &quot;\n&quot;; or</li>
169:         * <li>it has the <code>LAYOUT_NEWLINE_AFTER</code> directive; or</li>
170:         * <li>it is a
171:         * <code>ChoiceGroup</code>, <code>DateField</code>,
172:         * <code>Gauge</code>, or a <code>TextField</code>, and the
173:         * <code>LAYOUT_2</code> directive is not set.</li>
174:         * </ul>
175:         *
176:         * <p>The presence of the <code>LAYOUT_NEWLINE_BEFORE</code> or
177:         * <code>LAYOUT_NEWLINE_AFTER</code> directive does not cause
178:         * an additional row break if there is one already present.  For example,
179:         * if a <code>LAYOUT_NEWLINE_BEFORE</code> directive appears on a
180:         * <code>StringItem</code> whose contents starts with &quot;\n&quot;,
181:         * there is only a single row break.  A similar rule applies with a
182:         * trailing &quot;\n&quot; and <code>LAYOUT_NEWLINE_AFTER</code>.
183:         * Also, there is only a single row
184:         * break if an item has the <code>LAYOUT_NEWLINE_AFTER</code> directive
185:         * and the next item has the <code>LAYOUT_NEWLINE_BEFORE</code> directive.
186:         * However, the presence of consecutive &quot;\n&quot; characters,
187:         * either within a single <code>StringItem</code> or in adjacent
188:         * <code>StringItems</code>, will cause as many row breaks as there are
189:         * &quot;\n&quot; characters.  This will cause empty rows to be present.
190:         * The height of an empty row is determined by the prevailing font height of
191:         * the <code>StringItem</code> within which the &quot;\n&quot; that ends the
192:         * row occurs.</p>
193:         *
194:         * <p>Implementations may provide additional conditions under which a row
195:         * break occurs.  For example, an implementation's layout policy may lay out
196:         * labels specially, implicitly causing a break before every
197:         * <code>Item</code> that has a
198:         * label.  Or, as another example, a particular implementation's user
199:         * interface style may dictate that a DateField item always appears on a row
200:         * by itself.  In this case, this implementation may cause row breaks to occur
201:         * both before and after every <code>DateField</code> item.</p>
202:         *
203:         * <p>Given two items with adjacent <code>Form</code> indexes, if
204:         * none of the specified
205:         * or implementation-specific conditions for a row break between them
206:         * occurs, and if space permits, these items should be placed on the same
207:         * row.</p>
208:         *
209:         * <p>When packing <code>Items</code> onto a row, the width of the
210:         * item is compared with
211:         * the remaining space on the row. For this purpose, the width used is the
212:         * <code>Item's</code> preferred width, unless the
213:         * <code>Item</code> has the <code>LAYOUT_SHRINK</code>
214:         * directive,
215:         * in which case the <code>Item's</code> minimum width is used. If
216:         * the <code>Item</code> is too wide
217:         * to fit in the space remaining on the row, the row is considered to be
218:         * full, a new row is added beneath this one, and the
219:         * <code>Item</code> is laid out on
220:         * this new row.</p>
221:         *
222:         * <p>Once the contents of a row have been determined, the space available on
223:         * the row is distributed by expanding items and by adding space between
224:         * items. If any items on this row have the
225:         * <code>LAYOUT_SHRINK</code> directive (that is,
226:         * they are shrinkable), space is first distributed to these items. Space is
227:         * distributed to each of these items proportionally to the difference between
228:         * the each <code>Item's</code> preferred size and its minimum
229:         * size.  At this stage, no
230:         * shrinkable item is expanded beyond its preferred width.</p>
231:         *
232:         * <p>For example, consider a row that has <code>30</code> pixels
233:         * of space available and
234:         * that has two shrinkable items <code>A</code> and
235:         * <code>B</code>. Item <code>A's</code> preferred size is
236:         * <code>15</code> and
237:         * its minimum size is <code>10</code>. Item <code>B's</code>
238:         * preferred size is <code>30</code> and its minimum
239:         * size is <code>20</code>. The difference between
240:         * <code>A's</code> preferred and minimum size is
241:         * <code>5</code>,
242:         * and <code>B's</code> difference is <code>10</code>. The
243:         * <code>30</code> pixels are distributed to these items
244:         * proportionally to these differences. Therefore, <code>10</code>
245:         * pixels are
246:         * distributed to item <code>A</code> and <code>20</code>
247:         * pixels to item <code>B</code>.</p>
248:         *
249:         * <p>If after expanding all the shrinkable items to their preferred widths,
250:         * there is still space left on the row, this remaining space is distributed
251:         * equally among the Items that have the
252:         * <code>LAYOUT_EXPAND</code> directive (the
253:         * stretchable <code>Items</code>).  The presence of any
254:         * stretchable items on a row will
255:         * cause the <code>Items</code> on this row to occupy the full
256:         * width of the row.</p>
257:         *
258:         * <p>If there are no stretchable items on this row, and there is still space
259:         * available on this row, the <code>Items</code> are packed as tightly as
260:         * possible and are placed on the row according to the alignment value shared
261:         * by the <code>Items</code> on this row.  (Since changing the current
262:         * alignment causes a row break, all <code>Items</code> on the same row must
263:         * share the same alignment value.)  If the alignment value is
264:         * <code>LAYOUT_LEFT</code>, the <code>Items</code> are positioned at the left
265:         * end of the row and the remaining space is placed at the right end of the
266:         * row.  If the alignment value is <code>LAYOUT_RIGHT</code>, the
267:         * <code>Items</code> are positioned at the right end of the row and the
268:         * remaining space is placed at the left end of the row.  If the alignment
269:         * value is <code>LAYOUT_CENTER</code>, the <code>Items</code> are positioned
270:         * in the middle of the row such that the remaining space on the row is
271:         * divided evenly between the left and right ends of the row.</p>
272:         *
273:         * <p>Given the set of items on a particular row, the heights of these
274:         * <code>Items</code> are inspected.  For each <code>Item</code>, the height
275:         * that is used is the preferred height, unless the <code>Item</code> has the
276:         * <code>LAYOUT_VSHRINK</code> directive, in which case the
277:         * <code>Item's</code> minimum height is used.
278:         * The height of the tallest
279:         * <code>Item</code> determines the
280:         * height of the row.  <code>Items</code> that have the
281:         * <code>LAYOUT_VSHRINK</code> directive are expanded to their preferred
282:         * height or to the height of the row, whichever is smaller.
283:         * <code>Items</code> that are still shorter than the
284:         * row height and that
285:         * have the <code>LAYOUT_VEXPAND</code> directive will expand to
286:         * the height of the row.
287:         * The <code>LAYOUT_VEXPAND</code> directive on an item will never
288:         * increase the height
289:         * of a row.</p>
290:         *
291:         * <p>Remaining <code>Items</code> shorter than the row height
292:         * will be positioned
293:         * vertically within the row using the <code>LAYOUT_TOP</code>,
294:         * <code>LAYOUT_BOTTOM</code>, and
295:         * <code>LAYOUT_VCENTER</code> directives.  If no vertical layout directive is
296:         * specified, the item must be aligned along the bottom of the row.</p>
297:         *
298:         * <p><code>StringItems</code> are treated specially in the above
299:         * algorithm.  If the
300:         * contents of a <code>StringItem</code> (its string value,
301:         * exclusive of its label) contain
302:         * a newline character (&quot;\n&quot;), the string should be split at
303:         * that point and
304:         * the remainder laid out starting on the next row.</p>
305:         *
306:         * <p>If one or both dimensions of the preferred size of
307:         * a <code>StringItem</code> have been locked, the <code>StringItem</code>
308:         * is wrapped to fit that width and height and is treated as a
309:         * rectangle whose minimum and preferred width and height are the width and
310:         * height of this rectangle. In this case, the
311:         * <code>LAYOUT_SHRINK</code>, <code>LAYOUT_EXPAND</code>,
312:         * and <code>LAYOUT_VEXPAND</code> directives are ignored.</p>
313:         *
314:         * <p>If both dimensions of the preferred size of a <code>StringItem</code>
315:         * are unlocked, the text from the <code>StringItem</code> may be wrapped
316:         * across multiple rows.  At the point in the layout algorithm where the width
317:         * of the <code>Item</code> is compared to the remaining space on the row, as
318:         * much text is taken from the beginning of the <code>StringItem</code> as
319:         * will fit onto the current row.  The contents of this row are then
320:         * positioned according to the current alignment value.  The remainder of the
321:         * text in the <code>StringItem</code> is line-wrapped to the full width of as
322:         * many new rows as are necessary to accommodate the text.  Each full row is
323:         * positioned according to the current alignment value.  The last line of the
324:         * text might leave space available on its row.  If there is no row break
325:         * following this <code>StringItem</code>, subsequent <code>Items</code> are
326:         * packed into the remaining space and the contents of the row are positioned
327:         * according to the current alignment value.  This rule has the effect of
328:         * displaying the contents of a <code>StringItem</code> as a paragraph of text
329:         * set flush-left, flush-right, or centered, depending upon whether the
330:         * current alignment value is <code>LAYOUT_LEFT</code>,
331:         * <code>LAYOUT_RIGHT</code>, or <code>LAYOUT_CENTER</code>, respectively.
332:         * The preferred width and height of a <code>StringItem</code> wrapped across
333:         * multiple rows, as reported by the
334:         * {@link Item#getPreferredWidth Item.getPreferredWidth} and
335:         * {@link Item#getPreferredHeight Item.getPreferredHeight}
336:         * methods, describe the width and height of the bounding rectangle of the
337:         * wrapped text.</p>
338:         *
339:         * <p><code>ImageItems</code> are also treated specially by the above
340:         * algorithm.  The foregoing rules concerning the horizontal alignment value
341:         * and the <code>LAYOUT_LEFT</code>, <code>LAYOUT_RIGHT</code>, and
342:         * <code>LAYOUT_CENTER</code> directives, apply to <code>ImageItems</code>
343:         * only when the <code>LAYOUT_2</code> directive is also present on that item.
344:         * If the <code>LAYOUT_2</code> directive is not present on an
345:         * <code>ImageItem</code>, the behavior of the <code>LAYOUT_LEFT</code>,
346:         * <code>LAYOUT_RIGHT</code>, and <code>LAYOUT_CENTER</code> directives is
347:         * implementation-specific.</p>
348:         *
349:         * <p>A <code>Form's</code> layout is recomputed automatically as
350:         * necessary.  This may
351:         * occur because of a change in an <code>Item's</code> size caused
352:         * by a change in its
353:         * contents or because of a request by the application to change the Item's
354:         * preferred size.  It may also occur if an <code>Item's</code>
355:         * layout directives are
356:         * changed by the application.  The application does not need to perform
357:         * any specific action to cause the <code>Form's</code> layout to
358:         * be updated.</p>
359:         *
360:         * <h2><a NAME="linebreak">Line Breaks and Wrapping</a></h2>
361:         *
362:         * <p>For all cases where text is wrapped,
363:         * line breaks must occur at each newline character
364:         * (<code>'\n'</code> = Unicode <code>'U+000A'</code>).  
365:         * If space does not permit
366:         * the full text to be displayed it is truncated at line breaks.
367:         * If there are no suitable line breaks, it is recommended that
368:         * implementations break text at word boundaries.
369:         * If there are no word boundaries, it is recommended that
370:         * implementations break text at character boundaries. </p>
371:         *
372:         * <p>Labels that contain line breaks may be truncated at the line
373:         * break and cause the rest of the label not to be shown.</p>
374:         *
375:         * <h2>User Interaction</h2>
376:         *
377:         * <p> When a <code>Form</code> is present on the display the user
378:         * can interact
379:         * with it and its <code>Items</code> indefinitely (for instance,
380:         * traversing from <code>Item</code>
381:         * to <code>Item</code>
382:         * and possibly
383:         * scrolling). These traversing and scrolling operations do not cause
384:         * application-visible events. The system notifies
385:         * the application when the user modifies the state of an interactive
386:         * <code>Item</code>
387:         * contained within the <code>Form</code>.  This notification is
388:         * accomplished by calling the
389:         * {@link ItemStateListener#itemStateChanged itemStateChanged()}
390:         * method of the listener declared to the <code>Form</code> with the
391:         * {@link #setItemStateListener setItemStateListener()} method. </p>
392:         *
393:         * <p> As with other <code>Displayable</code> objects, a
394:         * <code>Form</code> can declare
395:         * {@link Command commands} and declare a command listener with the
396:         * {@link Displayable#setCommandListener setCommandListener()} method.
397:         * {@link CommandListener CommandListener}
398:         * objects are distinct from
399:         * {@link ItemStateListener ItemStateListener} objects, and they are declared
400:         * and invoked separately. </p>
401:         *
402:         * <h2>Notes for Application Developers</h2>
403:         *
404:         * <UL>
405:         * <LI>Although this class allows creation of arbitrary combination of
406:         * components
407:         * the application developers should keep the small screen size in mind.
408:         * <code>Form</code> is designed to contain a <em>small number of
409:         * closely related</em>
410:         * UI elements. </LI>
411:         *
412:         * <LI>If the number of items does not fit on the screen, the
413:         * implementation may choose to make it scrollable or to fold some components
414:         * so that a separate screen appears when the element is edited.</LI>
415:         * </UL>
416:         *
417:         * <p>
418:         * </p>
419:         *
420:         * @see Item
421:         * @since MIDP 1.0
422:         */
423:
424:        public class Form extends Screen {
425:
426:            // ************************************************************
427:            //  Static initializer, constructor
428:            // ************************************************************
429:
430:            /**
431:             * Creates a new, empty <code>Form</code>.
432:             *
433:             * @param title the <code>Form's</code> title, or
434:             * <code>null</code> for no title
435:             */
436:            public Form(String title) {
437:                this (title, null);
438:            }
439:
440:            /**
441:             * Creates a new <code>Form</code> with the specified
442:             * contents. This is identical to
443:             * creating an empty <code>Form</code> and then using a set of
444:             * <code>append</code>
445:             * methods.  The
446:             * items array may be <code>null</code>, in which case the
447:             * <code>Form</code> is created empty.  If
448:             * the items array is non-null, each element must be a valid
449:             * <code>Item</code> not
450:             * already contained within another <code>Form</code>.
451:             *
452:             * @param title the <code>Form's</code> title string
453:             * @param items the array of items to be placed in the
454:             * <code>Form</code>, or <code>null</code> if there are no
455:             * items
456:             * @throws IllegalStateException if one of the items is already owned by
457:             * another container
458:             * @throws NullPointerException if an element of the items array is
459:             * <code>null</code>
460:             */
461:            public Form(String title, Item[] items) {
462:                super (title);
463:
464:                synchronized (Display.LCDUILock) {
465:                    if (items == null) {
466:                        this .items = new Item[GROW_SIZE];
467:                        // numOfItems was initialized to 0
468:                        // so there is no need to update it
469:
470:                    } else {
471:                        this .items = new Item[items.length > GROW_SIZE ? items.length
472:                                : GROW_SIZE];
473:
474:                        // We have to check all items first so that some
475:                        // items would not be added to a form that was not
476:                        // instantiated
477:                        for (int i = 0; i < items.length; i++) {
478:                            // NullPointerException will be thrown by
479:                            // items[i].owner if items[i] == null;
480:                            if (items[i].owner != null) {
481:                                throw new IllegalStateException();
482:                            }
483:                        }
484:
485:                        numOfItems = items.length;
486:
487:                        for (int i = 0; i < numOfItems; i++) {
488:                            items[i].lSetOwner(this );
489:                            this .items[i] = items[i];
490:                        }
491:                    }
492:                    displayableLF = formLF = LFFactory.getFactory().getFormLF(
493:                            this );
494:                } // synchronized
495:            }
496:
497:            // ************************************************************
498:            //  public methods
499:            // ************************************************************
500:
501:            /**
502:             * Adds an <code>Item</code> into the <code>Form</code>.  The newly
503:             * added <code>Item</code> becomes the last <code>Item</code> in the
504:             * <code>Form</code>, and the size of the <code>Form</code> grows
505:             * by one.
506:             *
507:             * @param item the {@link Item Item} to be added.
508:             * @return the assigned index of the <code>Item</code>
509:             * @throws IllegalStateException if the item is already owned by
510:             * a container
511:             * @throws NullPointerException if item is <code>null</code>
512:             */
513:            public int append(Item item) {
514:                synchronized (Display.LCDUILock) {
515:                    // NullPointerException will be thrown
516:                    // by item.owner if item == null
517:                    if (item.owner != null) {
518:                        throw new IllegalStateException();
519:                    }
520:                    int i = insertImpl(numOfItems, item);
521:                    formLF.lInsert(i, item);
522:                    return i;
523:                }
524:            }
525:
526:            /**
527:             * Adds an item consisting of one <code>String</code> to the
528:             * <code>Form</code>. The effect of
529:             * this method is identical to 
530:             *
531:             * <p> <code>
532:             * append(new StringItem(null, str))
533:             * </code> </p>
534:             *
535:             * @param str the <code>String</code> to be added
536:             * @return the assigned index of the <code>Item</code>
537:             * @throws NullPointerException if str is <code>null</code>
538:             */
539:            public int append(String str) {
540:                if (str == null) {
541:                    throw new NullPointerException();
542:                }
543:
544:                synchronized (Display.LCDUILock) {
545:                    Item item = new StringItem(null, str);
546:                    int i = insertImpl(numOfItems, item);
547:                    formLF.lInsert(i, item);
548:                    return i;
549:                }
550:            }
551:
552:            /**
553:             * Adds an item consisting of one <code>Image</code> to the
554:             * <code>Form</code>. The effect of
555:             * this method is identical to 
556:             *
557:             * <p> <code>
558:             * append(new ImageItem(null, img, ImageItem.LAYOUT_DEFAULT, null))
559:             * </code> </p>
560:             *
561:             * @param img the image to be added
562:             * @return the assigned index of the <code>Item</code>
563:             * @throws NullPointerException if <code>img</code> is <code>null</code>
564:             */
565:            public int append(Image img) {
566:                if (img == null) {
567:                    throw new NullPointerException();
568:                }
569:
570:                synchronized (Display.LCDUILock) {
571:                    Item item = new ImageItem(null, img,
572:                            ImageItem.LAYOUT_DEFAULT, null);
573:                    int i = insertImpl(numOfItems, item);
574:                    formLF.lInsert(i, item);
575:                    return i;
576:                }
577:            }
578:
579:            /**
580:             * Inserts an item into the <code>Form</code> just prior to
581:             * the item specified.
582:             * The size of the <code>Form</code> grows by one.  The
583:             * <code>itemNum</code> parameter must be
584:             * within the range <code>[0..size()]</code>, inclusive.
585:             * The index of the last item is <code>size()-1</code>, and 
586:             * so there is actually no item whose index is
587:             * <code>size()</code>. If this value
588:             * is used for <code>itemNum</code>, the new item is inserted
589:             * immediately after
590:             * the last item. In this case, the effect is identical to
591:             * {@link #append(Item) append(Item)}. 
592:             *
593:             * <p> The semantics are otherwise identical to
594:             * {@link #append(Item) append(Item)}. </p>
595:             *
596:             * @param itemNum the index where insertion is to occur
597:             * @param item the item to be inserted
598:             * @throws IndexOutOfBoundsException if <code>itemNum</code> is invalid
599:             * @throws IllegalStateException if the item is already owned by
600:             * a container
601:             * @throws NullPointerException if <code>item</code> is
602:             * <code>null</code>
603:             */
604:            public void insert(int itemNum, Item item) {
605:                synchronized (Display.LCDUILock) {
606:                    // NullPointerException will be thrown
607:                    // by item.owner if item == null
608:                    if (item.owner != null) {
609:                        throw new IllegalStateException();
610:                    }
611:
612:                    if (itemNum < 0 || itemNum > numOfItems) {
613:                        throw new IndexOutOfBoundsException();
614:                    }
615:                    insertImpl(itemNum, item);
616:                    formLF.lInsert(itemNum, item);
617:                }
618:            }
619:
620:            /**
621:             * Deletes the <code>Item</code> referenced by
622:             * <code>itemNum</code>. The size of the <code>Form</code>
623:             * shrinks by one. It is legal to delete all items from a
624:             * <code>Form</code>.
625:             * The <code>itemNum</code> parameter must be 
626:             * within the range <code>[0..size()-1]</code>, inclusive. 
627:             *
628:             * @param itemNum the index of the item to be deleted
629:             * @throws IndexOutOfBoundsException if <code>itemNum</code> is invalid
630:             */
631:            public void delete(int itemNum) {
632:                Item deletedItem;
633:                synchronized (Display.LCDUILock) {
634:                    if (itemNum < 0 || itemNum >= numOfItems) {
635:                        throw new IndexOutOfBoundsException();
636:                    }
637:
638:                    deletedItem = items[itemNum];
639:
640:                    numOfItems--;
641:
642:                    if (itemNum < numOfItems) {
643:                        System.arraycopy(items, itemNum + 1, items, itemNum,
644:                                numOfItems - itemNum);
645:                    }
646:
647:                    // Delete reference to the last item 
648:                    // that was left after array copy
649:                    items[numOfItems] = null;
650:
651:                    // The Form is clear; reset its state
652:                    if (numOfItems == 0 && items.length > GROW_SIZE) {
653:                        items = new Item[GROW_SIZE]; // start fresh
654:                    }
655:
656:                    formLF.lDelete(itemNum, deletedItem);
657:
658:                } // synchronized
659:
660:                deletedItem.itemDeleted();
661:            }
662:
663:            /**
664:             * Deletes all the items from this <code>Form</code>, leaving
665:             * it with zero items.
666:             * This method does nothing if the <code>Form</code> is already empty.
667:             *
668:             */
669:            public void deleteAll() {
670:                Item[] itemsCopy;
671:                synchronized (Display.LCDUILock) {
672:                    if (numOfItems == 0) {
673:                        return;
674:                    }
675:                    itemsCopy = new Item[numOfItems];
676:
677:                    for (int x = 0; x < numOfItems; x++) {
678:                        itemsCopy[x] = items[x];
679:                        items[x] = null;
680:                    }
681:                    if (items.length > GROW_SIZE) {
682:                        items = new Item[GROW_SIZE]; // start fresh
683:                    }
684:
685:                    // Reset form state
686:                    numOfItems = 0;
687:
688:                    formLF.lDeleteAll();
689:                }
690:
691:                for (int x = 0; x < itemsCopy.length; x++) {
692:                    itemsCopy[x].itemDeleted();
693:                }
694:            }
695:
696:            /**
697:             * Sets the item referenced by <code>itemNum</code> to the
698:             * specified item,
699:             * replacing the previous item. The previous item is removed
700:             * from this <code>Form</code>.
701:             * The <code>itemNum</code> parameter must be 
702:             * within the range <code>[0..size()-1]</code>, inclusive. 
703:             *
704:             * <p>The end result is equal to
705:             * <code>insert(n, item); delete(n+1);</code><br>
706:             * although the implementation may optimize the repainting
707:             * and usage of the array that stores the items. <P>
708:             *
709:             * @param itemNum the index of the item to be replaced
710:             * @param item the new item to be placed in the <code>Form</code>
711:             *
712:             * @throws IndexOutOfBoundsException if <code>itemNum</code> is invalid
713:             * @throws IllegalStateException if the item is already owned by
714:             * a container
715:             * @throws NullPointerException if <code>item</code> is 
716:             * <code>null</code>
717:             */
718:            public void set(int itemNum, Item item) {
719:                synchronized (Display.LCDUILock) {
720:                    // NullPointerException will be thrown
721:                    // by item.owner if item == null
722:                    if (item.owner != null) {
723:                        throw new IllegalStateException();
724:                    }
725:
726:                    if (itemNum < 0 || itemNum >= numOfItems) {
727:                        throw new IndexOutOfBoundsException();
728:                    }
729:
730:                    items[itemNum].lSetOwner(null);
731:                    item.lSetOwner(this );
732:
733:                    items[itemNum] = item;
734:
735:                    formLF.lSet(itemNum, item);
736:                }
737:            }
738:
739:            /**
740:             * Gets the item at given position.  The contents of the
741:             * <code>Form</code> are left
742:             * unchanged.
743:             * The <code>itemNum</code> parameter must be 
744:             * within the range <code>[0..size()-1]</code>, inclusive. 
745:             *
746:             * @param itemNum the index of item
747:             *
748:             * @return the item at the given position
749:             *
750:             * @throws IndexOutOfBoundsException if <code>itemNum</code> is invalid
751:             */
752:            public Item get(int itemNum) {
753:                synchronized (Display.LCDUILock) {
754:                    if (itemNum < 0 || itemNum >= numOfItems) {
755:                        throw new IndexOutOfBoundsException();
756:                    }
757:
758:                    return items[itemNum];
759:                }
760:            }
761:
762:            /**
763:             * Sets the <code>ItemStateListener</code> for the
764:             * <code>Form</code>, replacing any previous
765:             * <code>ItemStateListener</code>. If
766:             * <code>iListener</code> is <code>null</code>, simply
767:             * removes the previous <code>ItemStateListener</code>.
768:             * @param iListener the new listener, or <code>null</code> to remove it
769:             */
770:            public void setItemStateListener(ItemStateListener iListener) {
771:                synchronized (Display.LCDUILock) {
772:                    itemStateListener = iListener;
773:                }
774:            }
775:
776:            /**
777:             * Gets the number of items in the <code>Form</code>.
778:             * @return the number of items
779:             */
780:            public int size() {
781:                synchronized (Display.LCDUILock) {
782:                    return numOfItems;
783:                }
784:            }
785:
786:            /**
787:             * Returns the width in pixels of the displayable area available for items.
788:             * The value may depend on how the device uses the screen and may be
789:             * affected by the presence or absence of the ticker, title, or commands.
790:             * The <code>Items</code> of the <code>Form</code> are
791:             * laid out to fit within this width.
792:             * @return the width of the <code>Form</code> in pixels
793:             */
794:            public int getWidth() {
795:                synchronized (Display.LCDUILock) {
796:                    return formLF.lGetWidth();
797:                }
798:            }
799:
800:            /**
801:             * Returns the height in pixels of the displayable area available
802:             * for items.
803:             * This value is the height of the form that can be displayed without
804:             * scrolling.
805:             * The value may depend on how the device uses the screen and may be
806:             * affected by the presence or absence of the ticker, title, or commands.
807:             * @return the height of the displayable area of the 
808:             * <code>Form</code> in pixels
809:             */
810:            public int getHeight() {
811:                synchronized (Display.LCDUILock) {
812:                    return formLF.lGetHeight();
813:                }
814:            }
815:
816:            // ************************************************************
817:            //  protected methods
818:            // ************************************************************
819:
820:            // ************************************************************
821:            //  package private methods
822:            // ************************************************************
823:
824:            /**
825:             * Retrieve the ItemStateListener for this Form.
826:             * NOTE: calls to this method should only occur from within
827:             * a lock on LCDUILock.
828:             *
829:             * @return ItemStateListener The ItemStateListener of this Form,
830:             *                           null if there isn't one set
831:             */
832:            ItemStateListener getItemStateListener() {
833:                return itemStateListener;
834:            }
835:
836:            /**
837:             * Used by the event handler to notify the ItemStateListener
838:             * of a change in the given item
839:             *
840:             * @param item the Item which state was changed
841:             */
842:            void uCallItemStateChanged(Item item) {
843:                // get a copy of the object reference to ItemStateListener
844:                ItemStateListener isl = itemStateListener;
845:                if (isl == null || item == null) {
846:                    return;
847:                }
848:
849:                // Protect from any unexpected application exceptions
850:                try {
851:                    // SYNC NOTE: We lock on calloutLock around any calls
852:                    // into application code
853:                    synchronized (Display.calloutLock) {
854:                        isl.itemStateChanged(item);
855:                    }
856:                } catch (Throwable thr) {
857:                    Display.handleThrowable(thr);
858:                }
859:            }
860:
861:            // ************************************************************
862:            //  private methods
863:            // ************************************************************
864:
865:            /**
866:             * Insert an Item into this Form
867:             *
868:             * @param itemNum The index into the Item array to insert this Item
869:             * @param item The Item to insert
870:             * @return int The index at which the newly inserted Item can be found
871:             */
872:            private int insertImpl(int itemNum, Item item) {
873:
874:                if (items.length == numOfItems) {
875:                    Item newItems[] = new Item[numOfItems + GROW_SIZE];
876:                    System.arraycopy(items, 0, newItems, 0, itemNum);
877:                    System.arraycopy(items, itemNum, newItems, itemNum + 1,
878:                            numOfItems - itemNum);
879:                    items = newItems;
880:                } else {
881:                    // if we're not appending
882:                    if (itemNum != numOfItems) {
883:                        System.arraycopy(items, itemNum, items, itemNum + 1,
884:                                numOfItems - itemNum);
885:                    }
886:                }
887:
888:                numOfItems++;
889:
890:                //
891:                // the arraycopy copied the reference to the item at this
892:                // spot. if we call setImpl without setting the index to null
893:                // setImpl will set the items owner to null.
894:                //
895:                item.lSetOwner(this );
896:                items[itemNum] = item;
897:
898:                return itemNum;
899:            }
900:
901:            // ************************************************************
902:            //  public member variables
903:            // ************************************************************
904:
905:            // ************************************************************
906:            //  protected member variables
907:            // ************************************************************
908:
909:            // ************************************************************
910:            //  package private member variables
911:            // ************************************************************
912:
913:            /** Array of Items that were added to this form. */
914:            Item items[];
915:
916:            /** The number of actual Items added is numOfItems. */
917:            int numOfItems; // = 0;
918:
919:            /** The Form look&feel object associated with this Form */
920:            FormLF formLF;
921:
922:            // ************************************************************
923:            //  private member variables
924:            // ************************************************************
925:
926:            /**
927:             * This is the rate at which the internal array of Items grows if
928:             * it gets filled up
929:             */
930:            private static final int GROW_SIZE = 4;
931:
932:            /** itemStateListener that has to be notified of any state changes */
933:            private ItemStateListener itemStateListener;
934:
935:        } // class Form
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.