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: * Implements a graphical display, such as a bar graph, of an integer
031: * value. The <code>Gauge</code> contains a <em>current value</em>
032: * that lies between zero and the <em>maximum value</em>, inclusive.
033: * The application can control the current value and maximum value.
034: * The range of values specified by the application may be larger than
035: * the number of distinct visual states possible on the device, so
036: * more than one value may have the same visual representation.
037: *
038: * <P>For example, consider a <code>Gauge</code> object that has a
039: * range of values from zero to <code>99</code>, running on a device
040: * that displays the <code>Gauge's</code> approximate value using a
041: * set of one to ten bars. The device might show one bar for values
042: * zero through nine, two bars for values ten through <code>19</code>,
043: * three bars for values <code>20</code> through <code>29</code>, and
044: * so forth. </p>
045: *
046: * <P>A <code>Gauge</code> may be interactive or
047: * non-interactive. Applications may set or retrieve the
048: * <code>Gauge's</code> value at any time regardless of the
049: * interaction mode. The implementation may change the visual
050: * appearance of the bar graph depending on whether the object is
051: * created in interactive mode. </p>
052: *
053: * <P>In interactive mode, the user is allowed to modify the
054: * value. The user will always have the means to change the value up
055: * or down by one and may also have the means to change the value in
056: * greater increments. The user is prohibited from moving the value
057: * outside the established range. The expected behavior is that the
058: * application sets the initial value and then allows the user to
059: * modify the value thereafter. However, the application is not
060: * prohibited from modifying the value even while the user is
061: * interacting with it. </p>
062: *
063: * <p> In many cases the only means for the user to modify the value
064: * will be to press a button to increase or decrease the value by one
065: * unit at a time. Therefore, applications should specify a range of
066: * no more than a few dozen values. </p>
067: *
068: * <P>In non-interactive mode, the user is prohibited from modifying
069: * the value. Non-interactive mode is used to provide feedback to the
070: * user on the state of a long-running operation. One expected use of
071: * the non-interactive mode is as a "progress indicator" or
072: * "activity indicator" to give the user some feedback
073: * during a long-running operation. The application may update the
074: * value periodically using the <code>setValue()</code> method. </P>
075: *
076: * <P>A non-interactive <code>Gauge</code> can have a definite or
077: * indefinite range. If a <code>Gauge</code> has definite range, it
078: * will have an integer value between zero and the maximum value set
079: * by the application, inclusive. The implementation will provide a
080: * graphical representation of this value such as described above.</p>
081: *
082: * <P>A non-interactive <code>Gauge</code> that has indefinite range
083: * will exist in one of four states: continuous-idle,
084: * incremental-idle, continuous-running, or incremental-updating.
085: * These states are intended to indicate to the user that some level
086: * of activity is occurring. With incremental-updating, progress can
087: * be indicated to the user even though there is no known endpoint to
088: * the activity. With continuous-running, there is no progress that
089: * gets reported to the user and there is no known endpoint;
090: * continuous-running is merely a busy state indicator. The
091: * implementation should use a graphical display that shows this
092: * appropriately. The implementation may use different graphics for
093: * indefinite continuous gauges and indefinite incremental gauges.
094: * Because of this, separate idle states exist for each mode. For
095: * example, the implementation might show an hourglass or spinning
096: * watch in the continuous-running state, but show an animation with
097: * different states, like a beach ball or candy-striped bar, in the
098: * incremental-updating state.</p>
099: *
100: * <p>In the continuous-idle or incremental-idle state, the
101: * <code>Gauge</code> indicates that no activity is occurring. In the
102: * incremental-updating state, the <code>Gauge</code> indicates
103: * activity, but its graphical representation should be updated only
104: * when the application requests an update with a call to
105: * <code>setValue()</code>. In the continuous-running state, the
106: * <code>Gauge</code> indicates activity by showing an animation that
107: * runs continuously, without update requests from the
108: * application.</p>
109: *
110: * <p>The values <code>CONTINUOUS_IDLE</code>,
111: * <code>INCREMENTAL_IDLE</code>, <code>CONTINUOUS_RUNNING</code>, and
112: * <code>INCREMENTAL_UPDATING</code> have their special meaning only
113: * when the <code>Gauge</code> is non-interactive and has been set to
114: * have indefinite range. They are treated as ordinary values if the
115: * <code>Gauge</code> is interactive or if it has been set to have a
116: * definite range.</p>
117: *
118: * <P>An application using the <code>Gauge</code> as a progress
119: * indicator should typically also attach a {@link Command#STOP STOP}
120: * command to the container containing the <code>Gauge</code> to allow
121: * the user to halt the operation in progress.</p>
122: *
123: * <h3>Notes for Application Developers</h3>
124: *
125: * <P>As mentioned above, a non-interactive <code>Gauge</code> may be
126: * used to give user feedback during a long-running operation. If the
127: * application can observe the progress of the operation as it
128: * proceeds to an endpoint known in advance, then the application
129: * should use a non-interactive <code>Gauge</code> with a definite
130: * range. For example, consider an application that is downloading a
131: * file known to be <code>20</code> kilobytes in size. The
132: * application could set the <code>Gauge's</code> maximum value to be
133: * <code>20</code> and set its value to the number of kilobytes
134: * downloaded so far. The user will be presented with a
135: * <code>Gauge</code> that shows the portion of the task completed at
136: * any given time.</P>
137: *
138: * <P>If, on the other hand, the application is downloading a file of
139: * unknown size, it should use a non-interactive <code>Gauge</code>
140: * with indefinite range. Ideally, the application should call
141: * <CODE>setValue(INCREMENTAL_UPDATING)</CODE> periodically, perhaps
142: * each time its input buffer has filled. This will give the user an
143: * indication of the rate at which progress is occurring.</P>
144: *
145: * <P>Finally, if the application is performing an operation but has
146: * no means of detecting progress, it should set a non-interactive
147: * <code>Gauge</code> to have indefinite range and set its value to
148: * <CODE>CONTINUOUS_RUNNING</CODE> or <CODE>CONTINUOUS_IDLE</CODE> as
149: * appropriate. For example, if the application has issued a request
150: * to a network server and is about to block waiting for the server to
151: * respond, it should set the <code>Gauge's</code> state to
152: * <CODE>CONTINUOUS_RUNNING</CODE> before awaiting the response, and it
153: * should set the state to <CODE>CONTINUOUS_IDLE</CODE> after it has
154: * received the response.</P>
155: *
156: * @since MIDP 1.0
157: */
158:
159: public class Gauge extends Item {
160:
161: // public implementation
162:
163: /**
164: * A special value used for the maximum value in order to indicate that
165: * the <code>Gauge</code> has indefinite range. This value may be
166: * used as the <code>maxValue</code>
167: * parameter to the constructor, the parameter passed to
168: * <code>setMaxValue()</code>, and
169: * as the return value of <code>getMaxValue()</code>.
170: * <P>
171: * The value of <code>INDEFINITE</code> is <code>-1</code>.</P>
172: *
173: */
174: public static final int INDEFINITE = -1;
175:
176: /**
177: * The value representing the continuous-idle state of a
178: * non-interactive <code>Gauge</code> with indefinite range. In
179: * the continuous-idle state, the gauge shows a graphic
180: * indicating that no work is in progress.
181: *
182: * <p>This value has special meaning only for non-interactive
183: * gauges with indefinite range. It is treated as an ordinary
184: * value for interactive gauges and for non-interactive gauges
185: * with definite range.</p>
186: *
187: * <p>The value of <code>CONTINUOUS_IDLE</code> is
188: * <code>0</code>.</p>
189: *
190: */
191: public static final int CONTINUOUS_IDLE = 0;
192:
193: /**
194: * The value representing the incremental-idle state of a
195: * non-interactive <code>Gauge</code> with indefinite range. In
196: * the incremental-idle state, the gauge shows a graphic
197: * indicating that no work is in progress.
198: *
199: * <p>This value has special meaning only for non-interactive
200: * gauges with indefinite range. It is treated as an ordinary
201: * value for interactive gauges and for non-interactive gauges
202: * with definite range.</p>
203: *
204: * <p>The value of <code>INCREMENTAL_IDLE</code> is
205: * <code>1</code>.</p>
206: *
207: */
208: public static final int INCREMENTAL_IDLE = 1;
209:
210: /**
211: * The value representing the continuous-running state of a
212: * non-interactive <code>Gauge</code> with indefinite range. In
213: * the continuous-running state, the gauge shows a
214: * continually-updating animation sequence that indicates that
215: * work is in progress. Once the application sets a gauge into
216: * the continuous-running state, the animation should proceed
217: * without further requests from the application.
218: *
219: * <p>This value has special meaning only for non-interactive
220: * gauges with indefinite range. It is treated as an ordinary
221: * value for interactive gauges and for non-interactive gauges
222: * with definite range.</p>
223: *
224: * <p>The value of <code>CONTINUOUS_RUNNING</code> is
225: * <code>2</code>.</p>
226: *
227: */
228: public static final int CONTINUOUS_RUNNING = 2;
229:
230: /**
231: * The value representing the incremental-updating state of a
232: * non-interactive <code>Gauge</code> with indefinite range. In
233: * the incremental-updating state, the gauge shows a graphic
234: * indicating that work is in progress, typically one frame of an
235: * animation sequence. The graphic should be updated to the next
236: * frame in the sequence only when the application calls
237: * <code>setValue(INCREMENTAL_UPDATING)</code>.
238: *
239: * <p>This value has special meaning only for non-interactive
240: * gauges with indefinite range. It is treated as an ordinary
241: * value for interactive gauges and for non-interactive gauges
242: * with definite range.</p>
243: *
244: * <p> The value of <code>INCREMENTAL_UPDATING</code> is
245: * <code>3</code>.</p>
246: *
247: */
248: public static final int INCREMENTAL_UPDATING = 3;
249:
250: /**
251: * Creates a new <code>Gauge</code> object with the given
252: * label, in interactive or non-interactive mode, with the given
253: * maximum and initial values. In interactive mode (where
254: * <code>interactive</code> is <code>true</code>) the maximum
255: * value must be greater than zero, otherwise an exception is
256: * thrown. In non-interactive mode (where
257: * <code>interactive</code> is <code>false</code>) the maximum
258: * value must be greater than zero or equal to the special value
259: * <code>INDEFINITE</code>, otherwise an exception is thrown.
260: *
261: * <p>If the maximum value is greater than zero, the gauge has
262: * definite range. In this case the initial value must be within
263: * the range zero to <code>maxValue</code>, inclusive. If the
264: * initial value is less than zero, the value is set to zero. If
265: * the initial value is greater than <code>maxValue</code>, it is
266: * set to <code>maxValue</code>.</p>
267: *
268: * <p>If <code>interactive</code> is <code>false</code> and the
269: * maximum value is <code>INDEFINITE</code>, this creates a
270: * non-interactive gauge with indefinite range. The initial value
271: * must be one of <code>CONTINUOUS_IDLE</code>,
272: * <code>INCREMENTAL_IDLE</code>, <code>CONTINUOUS_RUNNING</code>,
273: * or <code>INCREMENTAL_UPDATING</code>.</p>
274: *
275: * @see #INDEFINITE
276: * @see #CONTINUOUS_IDLE
277: * @see #INCREMENTAL_IDLE
278: * @see #CONTINUOUS_RUNNING
279: * @see #INCREMENTAL_UPDATING
280: *
281: * @param label the <code>Gauge's</code> label
282: * @param interactive tells whether the user can change the value
283: * @param maxValue the maximum value, or <code>INDEFINITE</code>
284: * @param initialValue the initial value in the range
285: * <code>[0..maxValue]</code>, or one of <code>CONTINUOUS_IDLE</code>,
286: * <code>INCREMENTAL_IDLE</code>, <code>CONTINUOUS_RUNNING</code>,
287: * or <code>INCREMENTAL_UPDATING</code> if <code>maxValue</code> is
288: * <code>INDEFINITE</code>.
289: *
290: * @throws IllegalArgumentException if <code>maxValue</code>
291: * is not positive for interactive gauges
292: * @throws IllegalArgumentException if <code>maxValue</code> is
293: * neither positive nor
294: * <code>INDEFINITE</code> for non-interactive gauges
295: * @throws IllegalArgumentException if initialValue is not one of
296: * <code>CONTINUOUS_IDLE</code>, <code>INCREMENTAL_IDLE</code>,
297: * <code>CONTINUOUS_RUNNING</code>, or <code>INCREMENTAL_UPDATING</code>
298: * for a non-interactive gauge with indefinite range
299: */
300: public Gauge(String label, boolean interactive, int maxValue,
301: int initialValue) {
302: super (label);
303:
304: if (maxValue == INDEFINITE
305: && (initialValue < CONTINUOUS_IDLE || initialValue > INCREMENTAL_UPDATING)) {
306: throw new IllegalArgumentException();
307: }
308:
309: synchronized (Display.LCDUILock) {
310:
311: this .interactive = interactive;
312:
313: itemLF = gaugeLF = LFFactory.getFactory().getGaugeLF(this );
314: /**
315: * IllegalArgumentException may be thrown by
316: * setMaxValueImpl and setValue
317: */
318: setMaxValueImpl(maxValue);
319: setValueImpl(initialValue);
320: }
321: }
322:
323: /**
324: * Sets the label of the <code>Item</code>. If <code>label</code>
325: * is <code>null</code>, specifies that this item has no label.
326: *
327: * <p>It is illegal to call this method if this <code>Item</code>
328: * is contained within an <code>Alert</code>.</p>
329: *
330: * @param label the label string
331: * @throws IllegalStateException if this <code>Item</code> is contained
332: * within an <code>Alert</code>
333: * @see #getLabel
334: */
335: public void setLabel(String label) {
336: if (this .owner instanceof Alert) {
337: throw new IllegalStateException(
338: "Gauge contained within an Alert");
339: }
340: super .setLabel(label);
341: }
342:
343: /**
344: * Sets the layout directives for this item.
345: *
346: * <p>It is illegal to call this method if this <code>Item</code>
347: * is contained within an <code>Alert</code>.</p>
348: *
349: * @param layout a combination of layout directive values for this item
350: * @throws IllegalArgumentException if the value of layout is not a valid
351: * combination of layout directives
352: * @throws IllegalStateException if this <code>Item</code> is
353: * contained within an <code>Alert</code>
354: * @see #getLayout
355: */
356: public void setLayout(int layout) {
357: if (this .owner instanceof Alert) {
358: throw new IllegalStateException(
359: "Gauge contained within an Alert");
360: }
361: super .setLayout(layout);
362: }
363:
364: /**
365: * Adds a context sensitive <code>Command</code> to the item.
366: * The semantic type of
367: * <code>Command</code> should be <code>ITEM</code>. The implementation
368: * will present the command
369: * only when the the item is active, for example, highlighted.
370: * <p>
371: * If the added command is already in the item (tested by comparing the
372: * object references), the method has no effect. If the item is
373: * actually visible on the display, and this call affects the set of
374: * visible commands, the implementation should update the display as soon
375: * as it is feasible to do so.
376: *
377: * <p>It is illegal to call this method if this <code>Item</code>
378: * is contained within an <code>Alert</code>.</p>
379: *
380: * @param cmd the command to be added
381: * @throws IllegalStateException if this <code>Item</code> is contained
382: * within an <code>Alert</code>
383: * @throws NullPointerException if cmd is <code>null</code>
384: */
385: public void addCommand(Command cmd) {
386: if (this .owner instanceof Alert) {
387: throw new IllegalStateException(
388: "Gauge contained within an Alert");
389: }
390: super .addCommand(cmd);
391: }
392:
393: /**
394: * Sets a listener for <code>Commands</code> to this Item,
395: * replacing any previous
396: * <code>ItemCommandListener</code>. A <code>null</code> reference
397: * is allowed and has the effect of
398: * removing any existing listener.
399: *
400: * <p>It is illegal to call this method if this <code>Item</code>
401: * is contained within an <code>Alert</code>.</p>
402: *
403: * @param l the new listener, or <code>null</code>.
404: * @throws IllegalStateException if this <code>Item</code> is contained
405: * within an <code>Alert</code>
406: */
407: public void setItemCommandListener(ItemCommandListener l) {
408: if (this .owner instanceof Alert) {
409: throw new IllegalStateException(
410: "Gauge contained within an Alert");
411: }
412: super .setItemCommandListener(l);
413: }
414:
415: /**
416: * Sets the preferred width and height for this <code>Item</code>.
417: * Values for width and height less than <code>-1</code> are illegal.
418: * If the width is between zero and the minimum width, inclusive,
419: * the minimum width is used instead.
420: * If the height is between zero and the minimum height, inclusive,
421: * the minimum height is used instead.
422: *
423: * <p>Supplying a width or height value greater than the minimum width or
424: * height <em>locks</em> that dimension to the supplied
425: * value. The implementation may silently enforce a maximum dimension for
426: * an <code>Item</code> based on factors such as the screen size.
427: * Supplying a value of
428: * <code>-1</code> for the width or height unlocks that dimension.
429: * See <a href="#sizes">Item Sizes</a> for a complete discussion.</p>
430: *
431: * <p>It is illegal to call this method if this <code>Item</code>
432: * is contained within an <code>Alert</code>.</p>
433: *
434: * @param width the value to which the width should be locked, or
435: * <code>-1</code> to unlock
436: * @param height the value to which the height should be locked, or
437: * <code>-1</code> to unlock
438: * @throws IllegalArgumentException if width or height is less than
439: * <code>-1</code>
440: * @throws IllegalStateException if this <code>Item</code> is contained
441: * within an <code>Alert</code>
442: * @see #getPreferredHeight
443: * @see #getPreferredWidth
444: */
445: public void setPreferredSize(int width, int height) {
446: if (this .owner instanceof Alert) {
447: throw new IllegalStateException(
448: "Gauge contained within an Alert");
449: }
450: super .setPreferredSize(width, height);
451: }
452:
453: /**
454: * Sets default <code>Command</code> for this <code>Item</code>.
455: * If the <code>Item</code> previously had a
456: * default <code>Command</code>, that <code>Command</code>
457: * is no longer the default, but it
458: * remains present on the <code>Item</code>.
459: *
460: * <p>If not <code>null</code>, the <code>Command</code> object
461: * passed becomes the default <code>Command</code>
462: * for this <code>Item</code>. If the <code>Command</code> object
463: * passed is not currently present
464: * on this <code>Item</code>, it is added as if {@link #addCommand}
465: * had been called
466: * before it is made the default <code>Command</code>.</p>
467: *
468: * <p>If <code>null</code> is passed, the <code>Item</code> is set to
469: * have no default <code>Command</code>.
470: * The previous default <code>Command</code>, if any, remains present
471: * on the <code>Item</code>.
472: * </p>
473: *
474: * <p>It is illegal to call this method if this <code>Item</code>
475: * is contained within an <code>Alert</code>.</p>
476: *
477: * @param cmd the command to be used as this <code>Item's</code> default
478: * <code>Command</code>, or <code>null</code> if there is to
479: * be no default command
480: *
481: * @throws IllegalStateException if this <code>Item</code> is contained
482: * within an <code>Alert</code>
483: */
484: public void setDefaultCommand(Command cmd) {
485: if (this .owner instanceof Alert) {
486: throw new IllegalStateException(
487: "Gauge contained within an Alert");
488: }
489: super .setDefaultCommand(cmd);
490: }
491:
492: /**
493: * Sets the current value of this <code>Gauge</code> object.
494: *
495: * <p>If the gauge is interactive, or if it is non-interactive with
496: * definite range, the following rules apply. If the value is less than
497: * zero, zero is used. If the current value is greater than the maximum
498: * value, the current value is set to be equal to the maximum value. </p>
499: *
500: * <p> If this <code>Gauge</code> object is a non-interactive
501: * gauge with indefinite
502: * range, then value must be one of <code>CONTINUOUS_IDLE</code>,
503: * <code>INCREMENTAL_IDLE</code>, <code>CONTINUOUS_RUNNING</code>, or
504: * <code>INCREMENTAL_UPDATING</code>.
505: * Other values will cause an exception to be thrown.</p>
506: *
507: * @see #CONTINUOUS_IDLE
508: * @see #INCREMENTAL_IDLE
509: * @see #CONTINUOUS_RUNNING
510: * @see #INCREMENTAL_UPDATING
511: *
512: * @param value the new value
513: * @throws IllegalArgumentException if value is not one of
514: * <code>CONTINUOUS_IDLE</code>, <code>INCREMENTAL_IDLE</code>,
515: * <code>CONTINUOUS_RUNNING</code>, or <code>INCREMENTAL_UPDATING</code>
516: * for non-interactive gauges with indefinite range
517: * @see #getValue
518: */
519: public void setValue(int value) {
520: synchronized (Display.LCDUILock) {
521: setValueImpl(value);
522: }
523: }
524:
525: /**
526: * Gets the current value of this <code>Gauge</code> object.
527: *
528: * <p> If this <code>Gauge</code> object is a non-interactive
529: * gauge with indefinite
530: * range, the value returned will be one of <code>CONTINUOUS_IDLE</code>,
531: * <code>INCREMENTAL_IDLE</code>, <code>CONTINUOUS_RUNNING</code>, or
532: * <code>INCREMENTAL_UPDATING</code>. Otherwise, it will be an integer
533: * between zero and the gauge's maximum value, inclusive.</p>
534: *
535: * @see #CONTINUOUS_IDLE
536: * @see #INCREMENTAL_IDLE
537: * @see #CONTINUOUS_RUNNING
538: * @see #INCREMENTAL_UPDATING
539: *
540: * @return current value of the <code>Gauge</code>
541: * @see #setValue
542: */
543: public int getValue() {
544: synchronized (Display.LCDUILock) {
545: return gaugeLF.lGetValue();
546: }
547: }
548:
549: /**
550: * Sets the maximum value of this <code>Gauge</code> object.
551: *
552: * <p>For interactive gauges, the new maximum value must be greater than
553: * zero, otherwise an exception is thrown. For non-interactive gauges,
554: * the new maximum value must be greater than zero or equal to the special
555: * value <code>INDEFINITE</code>, otherwise an exception is thrown. </p>
556: *
557: * <p>If the new maximum value is greater than zero, this provides the
558: * gauge with a definite range. If the gauge previously had a definite
559: * range, and if the current value is greater than new maximum value, the
560: * current value is set to be equal to the new maximum value. If the
561: * gauge previously had a definite range, and if the current value is less
562: * than or equal to the new maximum value, the current value is left
563: * unchanged. </p>
564: *
565: * <p>If the new maximum value is greater than zero, and if the gauge had
566: * previously had indefinite range, this new maximum value provides it
567: * with a definite range. Its graphical representation must change
568: * accordingly, the previous state of <code>CONTINUOUS_IDLE</code>,
569: * <code>INCREMENTAL_IDLE</code>, <code>CONTINUOUS_RUNNING</code>, or
570: * <code>INCREMENTAL_UPDATING</code> is ignored, and the current value
571: * is set to zero. </p>
572: *
573: * <p>If this gauge is non-interactive and the new maximum value is
574: * <code>INDEFINITE</code>, this gives the gauge indefinite range.
575: * If the gauge
576: * previously had a definite range, its graphical representation must
577: * change accordingly, the previous value is ignored, and the current
578: * state is set to <code>CONTINUOUS_IDLE</code>. If the gauge previously
579: * had an indefinite range, setting the maximum value to
580: * <code>INDEFINITE</code> will have no effect. </p>
581: *
582: * @see #INDEFINITE
583: *
584: * @param maxValue the new maximum value
585: *
586: * @throws IllegalArgumentException if <code>maxValue</code> is invalid
587: * @see #getMaxValue
588: */
589: public void setMaxValue(int maxValue) {
590: synchronized (Display.LCDUILock) {
591: setMaxValueImpl(maxValue);
592: }
593: }
594:
595: /**
596: * Gets the maximum value of this <code>Gauge</code> object.
597: *
598: * <p>If this gauge is interactive, the maximum value will be a positive
599: * integer. If this gauge is non-interactive, the maximum value will be a
600: * positive integer (indicating that the gauge has definite range)
601: * or the special value <code>INDEFINITE</code> (indicating that
602: * the gauge has
603: * indefinite range).</p>
604: *
605: * @see #INDEFINITE
606: *
607: * @return the maximum value of the <code>Gauge</code>, or
608: * <code>INDEFINITE</code>
609: * @see #setMaxValue
610: */
611: public int getMaxValue() {
612: // SYNC NOTE: return of atomic value, no locking necessary
613: return maxValue;
614: }
615:
616: /**
617: * Tells whether the user is allowed to change the value of the
618: * <code>Gauge</code>.
619: *
620: * @return a boolean indicating whether the <code>Gauge</code> is
621: * interactive
622: */
623: public boolean isInteractive() {
624: // SYNC NOTE: return of atomic value, no locking necessary
625: return interactive;
626: }
627:
628: // package private implementation
629:
630: /**
631: * Sets the current value of this Gauge object.
632: *
633: * @param value the new value
634: * @throws IllegalArgumentException if value is not one of
635: * <code>CONTINUOUS_IDLE</code>, <code>INCREMENTAL_IDLE</code>,
636: * <code>CONTINUOUS_RUNNING</code>, or <code>INCREMENTAL_UPDATING</code>
637: * for non-interactive gauges with indefinite range
638: */
639: void setValueImpl(int value) {
640: if (!interactive && maxValue == INDEFINITE) {
641: switch (value) {
642: case CONTINUOUS_IDLE:
643: case INCREMENTAL_IDLE:
644: case INCREMENTAL_UPDATING:
645: case CONTINUOUS_RUNNING:
646: break;
647: default:
648: throw new IllegalArgumentException();
649: }
650: }
651:
652: if ((this .value != value)
653: || (this .maxValue == INDEFINITE && value == INCREMENTAL_UPDATING)) {
654: int oldValue = this .value;
655: this .value = value;
656: checkValue();
657: gaugeLF.lSetValue(oldValue, this .value);
658: }
659: }
660:
661: /**
662: * Return whether the Item takes user input focus.
663: *
664: * @return return <code>true</code> if contents is interactive or have
665: * abstract commands.
666: */
667: boolean acceptFocus() {
668: return super .acceptFocus() || interactive;
669: }
670:
671: // private implementation
672:
673: /**
674: * Utility method to ensure the value of the Gauge is always
675: * in a range of 0 to maxValue, or if maxValue is INDEFINITE
676: * that value is CONTINUOUS_IDLE, INCREMENTAL_IDLE,
677: * INCREMENTAL_UPDATING, or CONTINUOUS_RUNNING. In the case
678: * where maxValue is INDEFINITE and value is not one of the
679: * three defined here it will be set to CONTINUOUS_IDLE. (0)
680: *
681: * private instance variable value will be within parameter
682: * after this call
683: */
684: private void checkValue() {
685: if (maxValue == INDEFINITE) {
686: if (value < CONTINUOUS_IDLE || value > INCREMENTAL_UPDATING) {
687: value = CONTINUOUS_IDLE;
688: }
689: } else {
690: if (value < 0) {
691: value = 0;
692: } else if (value > maxValue) {
693: value = maxValue;
694: }
695: }
696: }
697:
698: /**
699: * Set the max value of this Gauge.
700: *
701: * @param maxValue The maximum value to set for this Gauge
702: *
703: * @throws IllegalArgumentException if maxValue is not positive for
704: * interactive gauges
705: * @throws IllegalArgumentException if maxValue is neither positive nor
706: * INDEFINITE for non-interactive gauges
707: */
708: private void setMaxValueImpl(int maxValue) {
709: if (maxValue <= 0) {
710: if (!(interactive == false && maxValue == INDEFINITE)) {
711: throw new IllegalArgumentException();
712: }
713: }
714:
715: int oldMaxValue = this .maxValue;
716: this .maxValue = maxValue;
717:
718: if (oldMaxValue == INDEFINITE) { // oldMaxValue
719: if (maxValue > INDEFINITE) {
720: value = 0;
721: }
722: } else if (maxValue == INDEFINITE) {
723: value = CONTINUOUS_IDLE;
724: }
725:
726: checkValue();
727:
728: if (oldMaxValue != maxValue) {
729: gaugeLF.lSetMaxValue(oldMaxValue, maxValue);
730:
731: }
732: }
733:
734: /**
735: * The look&feel associated with this item.
736: * Set in the constructor.
737: */
738: GaugeLF gaugeLF; // = null
739:
740: /** The current value of this gauge */
741: int value; // = 0
742:
743: /** The maximum possible value of this gauge */
744: int maxValue; // = 0
745:
746: /** Whether this gauge is interactive or not */
747: boolean interactive; // = false
748:
749: }
|