001 /* JProgressBar.java --
002 Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
003
004 This file is part of GNU Classpath.
005
006 GNU Classpath is free software; you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation; either version 2, or (at your option)
009 any later version.
010
011 GNU Classpath 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 for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with GNU Classpath; see the file COPYING. If not, write to the
018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019 02110-1301 USA.
020
021 Linking this library statically or dynamically with other modules is
022 making a combined work based on this library. Thus, the terms and
023 conditions of the GNU General Public License cover the whole
024 combination.
025
026 As a special exception, the copyright holders of this library give you
027 permission to link this library with independent modules to produce an
028 executable, regardless of the license terms of these independent
029 modules, and to copy and distribute the resulting executable under
030 terms of your choice, provided that you also meet, for each linked
031 independent module, the terms and conditions of the license of that
032 module. An independent module is a module which is not derived from
033 or based on this library. If you modify this library, you may extend
034 this exception to your version of the library, but you are not
035 obligated to do so. If you do not wish to do so, delete this
036 exception statement from your version. */
037
038
039 package javax.swing;
040
041 import gnu.java.lang.CPStringBuilder;
042
043 import java.awt.Graphics;
044 import java.beans.PropertyChangeEvent;
045
046 import javax.accessibility.Accessible;
047 import javax.accessibility.AccessibleContext;
048 import javax.accessibility.AccessibleRole;
049 import javax.accessibility.AccessibleState;
050 import javax.accessibility.AccessibleStateSet;
051 import javax.accessibility.AccessibleValue;
052 import javax.swing.border.Border;
053 import javax.swing.event.ChangeEvent;
054 import javax.swing.event.ChangeListener;
055 import javax.swing.plaf.ProgressBarUI;
056
057 /**
058 * A component that displays a visual indicator of the progress of a task. The
059 * component has two modes: determinate and indeterminate. In determinate mode,
060 * the <code>JProgressBar</code> fills a percentage of its bar based on its
061 * current value. In indeterminate mode, it creates box and bounces it between
062 * its bounds.
063 * <p>
064 * This component has the following properties:
065 * </p>
066 * <table>
067 * <tr><th> Property </th><th> Stored in </th><th> Bound? </th></tr>
068 * <tr><td> borderPainted </td><td> progressBar </td><td> yes </td></tr>
069 * <tr><td> changeListeners </td><td> progressBar </td><td> no </td></tr>
070 * <tr><td> indeterminate </td><td> progressBar </td><td> yes </td></tr>
071 * <tr><td> maximum </td><td> model </td><td> no </td></tr>
072 * <tr><td> minimum </td><td> model </td><td> no </td></tr>
073 * <tr><td> model </td><td> progressBar </td><td> no </td></tr>
074 * <tr><td> orientation </td><td> progressBar </td><td> yes </td></tr>
075 * <tr><td> percentComplete </td><td> progressBar </td><td> no </td></tr>
076 * <tr><td> string </td><td> progressBar </td><td> yes </td></tr>
077 * <tr><td> stringPainted </td><td> progressBar </td><td> yes </td></tr>
078 * <tr><td> value </td><td> model </td><td> no </td></tr>
079 * </table>
080 */
081 public class JProgressBar extends JComponent implements SwingConstants,
082 Accessible
083 {
084 /**
085 * Provides the accessibility features for the <code>JProgressBar</code>
086 * component.
087 */
088 protected class AccessibleJProgressBar extends AccessibleJComponent
089 implements AccessibleValue
090 {
091 private static final long serialVersionUID = -2938130009392721813L;
092
093 /**
094 * Creates a new <code>AccessibleJProgressBar</code> instance.
095 */
096 protected AccessibleJProgressBar()
097 {
098 // Nothing to do here.
099 }
100
101 /**
102 * Returns a set containing the current state of the {@link JProgressBar}
103 * component.
104 *
105 * @return The accessible state set.
106 */
107 public AccessibleStateSet getAccessibleStateSet()
108 {
109 AccessibleStateSet result = super.getAccessibleStateSet();
110 if (orientation == JProgressBar.HORIZONTAL)
111 result.add(AccessibleState.HORIZONTAL);
112 else if (orientation == JProgressBar.VERTICAL)
113 result.add(AccessibleState.VERTICAL);
114 return result;
115 }
116
117 /**
118 * Returns the accessible role for the <code>JProgressBar</code> component.
119 *
120 * @return {@link AccessibleRole#PROGRESS_BAR}.
121 */
122 public AccessibleRole getAccessibleRole()
123 {
124 return AccessibleRole.PROGRESS_BAR;
125 }
126
127 /**
128 * Returns an object that provides access to the current, minimum and
129 * maximum values.
130 *
131 * @return The accessible value.
132 */
133 public AccessibleValue getAccessibleValue()
134 {
135 return this;
136 }
137
138 /**
139 * Returns the current value of the {@link JProgressBar} component, as an
140 * {@link Integer}.
141 *
142 * @return The current value of the {@link JProgressBar} component.
143 */
144 public Number getCurrentAccessibleValue()
145 {
146 return new Integer(getValue());
147 }
148
149 /**
150 * Sets the current value of the {@link JProgressBar} component and sends a
151 * {@link PropertyChangeEvent} (with the property name
152 * {@link AccessibleContext#ACCESSIBLE_VALUE_PROPERTY}) to all registered
153 * listeners. If the supplied value is <code>null</code>, this method
154 * does nothing and returns <code>false</code>.
155 *
156 * @param value the new progress bar value (<code>null</code> permitted).
157 *
158 * @return <code>true</code> if the slider value is updated, and
159 * <code>false</code> otherwise.
160 */
161 public boolean setCurrentAccessibleValue(Number value)
162 {
163 if (value == null)
164 return false;
165 Number oldValue = getCurrentAccessibleValue();
166 setValue(value.intValue());
167 firePropertyChange(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, oldValue,
168 new Integer(getValue()));
169 return true;
170 }
171
172 /**
173 * Returns the minimum value of the {@link JProgressBar} component, as an
174 * {@link Integer}.
175 *
176 * @return The minimum value of the {@link JProgressBar} component.
177 */
178 public Number getMinimumAccessibleValue()
179 {
180 return new Integer(getMinimum());
181 }
182
183 /**
184 * Returns the maximum value of the {@link JProgressBar} component, as an
185 * {@link Integer}.
186 *
187 * @return The maximum value of the {@link JProgressBar} component.
188 */
189 public Number getMaximumAccessibleValue()
190 {
191 return new Integer(getMaximum());
192 }
193 }
194
195 private static final long serialVersionUID = 1980046021813598781L;
196
197 /**
198 * A flag that determines the mode (<code>true</code> for indeterminate,
199 * <code>false</code> for determinate).
200 */
201 private transient boolean indeterminate = false;
202
203 /**
204 * The orientation of the <code>JProgressBar</code>
205 * ({@link SwingConstants#HORIZONTAL} or {@link SwingConstants#VERTICAL}).
206 * Defaults to {@link SwingConstants#HORIZONTAL}.
207 * @see #setOrientation(int)
208 */
209 protected int orientation;
210
211 /**
212 * A flag the controls whether or not the component's border is painted.
213 * The default is <code>true</code>.
214 * @see #setBorderPainted(boolean)
215 */
216 protected boolean paintBorder = true;
217
218 /**
219 * The model defining the bounds and current value for the progress bar.
220 * @see #setModel(BoundedRangeModel)
221 */
222 protected BoundedRangeModel model;
223
224 /**
225 * A custom string for display in the progress bar. If this is
226 * <code>null</code>, a default string will be generated.
227 * @see #setString(String)
228 */
229 protected String progressString;
230
231 /**
232 * A flag that controls whether a string is displayed within the progress
233 * bar.
234 * @see #setStringPainted(boolean)
235 */
236 protected boolean paintString = false;
237
238 /**
239 * A single change event reused for all events.
240 * @see #fireStateChanged()
241 */
242 protected transient ChangeEvent changeEvent;
243
244 /**
245 * The listener that is registered with the model. */
246 protected ChangeListener changeListener;
247
248 /**
249 * Creates a new <code>JProgressBar</code> with default attributes. The
250 * following defaults are used:
251 * <p>
252 * <ul>
253 * <li><code>value</code>: 0;</li>
254 * <li><code>minimum</code>: 0;</li>
255 * <li><code>maximum</code>: 100;</li>
256 * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li>
257 * </ul>
258 */
259 public JProgressBar()
260 {
261 this(HORIZONTAL, 0, 100);
262 }
263
264 /**
265 * Creates a new <code>JProgressBar</code> with the specified
266 * <code>orientation</code>. The following defaults are used:
267 * <p>
268 * <ul>
269 * <li><code>value</code>: 0;</li>
270 * <li><code>minimum</code>: 0;</li>
271 * <li><code>maximum</code>: 100;</li>
272 * </ul>
273 *
274 * @param orientation the orientation ({@link #HORIZONTAL} or
275 * {@link #VERTICAL}).
276 *
277 * @throws IllegalArgumentException if <code>orientation</code> is not one of
278 * the specified values.
279 */
280 public JProgressBar(int orientation)
281 {
282 this(orientation, 0, 100);
283 }
284
285 /**
286 * Creates a new <code>JProgressBar</code> with the specified value range.
287 * The following defaults are used:
288 * <p>
289 * <ul>
290 * <li><code>value</code>: <code>minimum</code>;</li>
291 * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li>
292 * </ul>
293 *
294 * @param minimum the lower bound of the value range.
295 * @param maximum the upper bound of the value range.
296 */
297 public JProgressBar(int minimum, int maximum)
298 {
299 this(HORIZONTAL, minimum, maximum);
300 }
301
302 /**
303 * Creates a new <code>JProgressBar</code> with the specified range and
304 * orientation. The following defaults are used:
305 * <p>
306 * <ul>
307 * <li><code>value</code>: <code>minimum</code>;</li>
308 * </ul>
309 *
310 * @param minimum the lower bound of the value range.
311 * @param maximum the upper bound of the value range.
312 * @param orientation the orientation ({@link #HORIZONTAL} or
313 * {@link #VERTICAL}).
314 *
315 * @throws IllegalArgumentException if <code>orientation</code> is not one of
316 * the specified values.
317 */
318 public JProgressBar(int orientation, int minimum, int maximum)
319 {
320 model = new DefaultBoundedRangeModel(minimum, 0, minimum, maximum);
321 if (orientation != HORIZONTAL && orientation != VERTICAL)
322 throw new IllegalArgumentException(orientation
323 + " is not a legal orientation");
324 this.orientation = orientation;
325 changeListener = createChangeListener();
326 model.addChangeListener(changeListener);
327 updateUI();
328 }
329
330 /**
331 * Creates a new <code>JProgressBar</code> with the specified model. The
332 * following defaults are used:
333 * <p>
334 * <ul>
335 * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li>
336 * </ul>
337 *
338 * @param model the model (<code>null</code> not permitted).
339 */
340 public JProgressBar(BoundedRangeModel model)
341 {
342 this.model = model;
343 changeListener = createChangeListener();
344 if (model != null)
345 model.addChangeListener(changeListener);
346 updateUI();
347 }
348
349 /**
350 * Returns the current value for the <code>JProgressBar</code>. This value
351 * is fetched from the model.
352 *
353 * @return The current value.
354 *
355 * @see #setValue(int)
356 */
357 public int getValue()
358 {
359 return model.getValue();
360 }
361
362 /**
363 * Sets the current value for the <code>JProgressBar</code>. The value is
364 * stored in the component's <code>model</code> (see {@link #getModel()}).
365 * If the new value is different to the old value, a {@link ChangeEvent} is
366 * sent to the model's registered listeners. In turn, this triggers a call
367 * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code>
368 * to this component's registered listeners.
369 * <p>
370 * If <code>value</code> is outside the range <code>minimum</code> to
371 * <code>maximum</code>, it will be set to the nearest of those boundary
372 * values.
373 *
374 * @param value the new value.
375 *
376 * @see #getValue()
377 */
378 public void setValue(int value)
379 {
380 model.setValue(value);
381 }
382
383 /**
384 * Paints the component's border, but only if {@link #isBorderPainted()}
385 * returns <code>true</code>.
386 *
387 * @param graphics the graphics object to paint with.
388 *
389 * @see #setBorderPainted(boolean)
390 */
391 protected void paintBorder(Graphics graphics)
392 {
393 Border border = getBorder();
394 if (paintBorder && border != null)
395 border.paintBorder(this, graphics, 0, 0, getWidth(), getHeight());
396 }
397
398 /**
399 * Returns the orientation of the <code>JProgressBar</code> component, which
400 * is either {@link SwingConstants#HORIZONTAL} or
401 * {@link SwingConstants#VERTICAL}. The default orientation is
402 * <code>HORIZONTAL</code>.
403 *
404 * @return The orientation.
405 *
406 * @see #setOrientation(int)
407 */
408 public int getOrientation()
409 {
410 return orientation;
411 }
412
413 /**
414 * Sets the orientation for this <code>JProgressBar</code> component and,
415 * if the value changes, sends a {@link PropertyChangeEvent} (with the
416 * property name <code>"orientation"</code>) to all registered listeners.
417 *
418 * @param orientation the orientation ({@link #HORIZONTAL} or
419 * {@link #VERTICAL}).
420 *
421 * @throws IllegalArgumentException if <code>orientation</code> is not
422 * one of the listed values.
423 *
424 * @see #getOrientation()
425 */
426 public void setOrientation(int orientation)
427 {
428 if (orientation != VERTICAL && orientation != HORIZONTAL)
429 throw new IllegalArgumentException(orientation
430 + " is not a legal orientation");
431 if (this.orientation != orientation)
432 {
433 int oldOrientation = this.orientation;
434 this.orientation = orientation;
435 firePropertyChange("orientation", oldOrientation, this.orientation);
436 }
437 }
438
439 /**
440 * Returns the flag that controls whether or not the string returned by
441 * {@link #getString()} is displayed by the <code>JProgressBar</code>
442 * component.
443 *
444 * @return <code>true</code> if the string should be displayed, and
445 * <code>false</code> otherwise.
446 *
447 * @see #setStringPainted(boolean)
448 */
449 public boolean isStringPainted()
450 {
451 return paintString;
452 }
453
454 /**
455 * Sets the flag that controls whether or not the string returned by
456 * {@link #getString()} is displayed by the <code>JProgressBar</code>
457 * component. If the flag value changes, a {@link PropertyChangeEvent} (with
458 * the property name <code>"stringPainted"</code>) is sent to all registered
459 * listeners.
460 *
461 * @param painted the new flag value.
462 *
463 * @see #isStringPainted()
464 * @see #setString(String)
465 */
466 public void setStringPainted(boolean painted)
467 {
468 if (paintString != painted)
469 {
470 boolean oldPainted = paintString;
471 paintString = painted;
472 firePropertyChange("stringPainted", oldPainted, paintString);
473 }
474 }
475
476 /**
477 * Returns the string that is painted on the <code>JProgressBar</code> if
478 * {@link #isStringPainted()} returns <code>true</code>. If no string has
479 * been explicitly set, this method will return a string displaying the
480 * value of {@link #getPercentComplete()}.
481 *
482 * @return The string.
483 *
484 * @see #setString(String)
485 * @see #setStringPainted(boolean)
486 */
487 public String getString()
488 {
489 if (progressString != null)
490 return progressString;
491 else
492 return (int) (getPercentComplete() * 100) + "%";
493 }
494
495 /**
496 * Sets the string to display within the progress bar and, if the new value
497 * is different to the old value, sends a {@link PropertyChangeEvent} (with
498 * the property name <code>"string"</code>) to all registered listeners. If
499 * the string is set to <code>null</code>, {@link #getString()} will return
500 * a default string.
501 *
502 * @param string the string (<code>null</code> permitted).
503 *
504 * @see #getString()
505 * @see #setStringPainted(boolean)
506 */
507 public void setString(String string)
508 {
509 if (((string == null || progressString == null) &&
510 string != progressString) || (string != null &&
511 ! string.equals(progressString)))
512 {
513 String oldString = progressString;
514 progressString = string;
515 firePropertyChange("string", oldString, progressString);
516 }
517 }
518
519 /**
520 * Returns the current value expressed as a percentage. This is calculated
521 * as <code>(value - min) / (max - min)</code>.
522 *
523 * @return The percentage (a value in the range 0.0 to 1.0).
524 */
525 public double getPercentComplete()
526 {
527 if (getMaximum() == getMinimum())
528 return 1.0;
529 else
530 return (double) (model.getValue() - model.getMinimum())
531 / (model.getMaximum() - model.getMinimum());
532 }
533
534 /**
535 * Returns a flag that controls whether or not the component's border is
536 * painted. The default value is <code>true</code>.
537 *
538 * @return <code>true</code> if the component's border should be painted,
539 * and <code>false</code> otherwise.
540 *
541 * @see #setBorderPainted(boolean)
542 */
543 public boolean isBorderPainted()
544 {
545 return paintBorder;
546 }
547
548 /**
549 * Sets the flag that controls whether or not the component's border is
550 * painted. If the flag value is changed, this method sends a
551 * {@link PropertyChangeEvent} (with the property name "borderPainted") to
552 * all registered listeners.
553 *
554 * @param painted the new flag value.
555 *
556 * @see #isBorderPainted()
557 * @see #paintBorder
558 */
559 public void setBorderPainted(boolean painted)
560 {
561 if (painted != paintBorder)
562 {
563 boolean oldPainted = paintBorder;
564 paintBorder = painted;
565 firePropertyChange("borderPainted", oldPainted, paintBorder);
566 }
567 }
568
569 /**
570 * Returns the UI delegate for this <code>JProgressBar</code>.
571 *
572 * @return The UI delegate.
573 */
574 public ProgressBarUI getUI()
575 {
576 return (ProgressBarUI) ui;
577 }
578
579 /**
580 * Sets the UI delegate for this component.
581 *
582 * @param ui the new UI delegate.
583 */
584 public void setUI(ProgressBarUI ui)
585 {
586 super.setUI(ui);
587 }
588
589 /**
590 * Sets this <code>JProgressBar</code>'s UI delegate to the default
591 * (obtained from the {@link UIManager}) for the current look and feel.
592 */
593 public void updateUI()
594 {
595 setUI((ProgressBarUI) UIManager.getUI(this));
596 }
597
598 /**
599 * Returns the suffix (<code>"ProgressBarUI"</code> in this case) used to
600 * determine the class name for a UI delegate that can provide the look and
601 * feel for a <code>JProgressBar</code>.
602 *
603 * @return <code>"ProgressBarUI"</code>.
604 */
605 public String getUIClassID()
606 {
607 return "ProgressBarUI";
608 }
609
610 /**
611 * Creates a new {@link ChangeListener} that calls
612 * {@link #fireStateChanged()} whenever it receives a {@link ChangeEvent}
613 * (typically from the component's <code>model</code>). This listener is
614 * registered with the progress bar's model, so that changes made to the
615 * model directly will automatically result in the progress bar's listeners
616 * being notified also.
617 *
618 * @return A new listener.
619 */
620 protected ChangeListener createChangeListener()
621 {
622 return new ChangeListener()
623 {
624 public void stateChanged(ChangeEvent ce)
625 {
626 fireStateChanged();
627 }
628 };
629 }
630
631 /**
632 * Registers a listener with this component so that it will receive
633 * notification of component state changes.
634 *
635 * @param listener the listener.
636 *
637 * @see #removeChangeListener(ChangeListener)
638 */
639 public void addChangeListener(ChangeListener listener)
640 {
641 listenerList.add(ChangeListener.class, listener);
642 }
643
644 /**
645 * Deregisters a listener so that it no longer receives notification of
646 * component state changes.
647 *
648 * @param listener the listener.
649 *
650 * @see #addChangeListener(ChangeListener)
651 */
652 public void removeChangeListener(ChangeListener listener)
653 {
654 listenerList.remove(ChangeListener.class, listener);
655 }
656
657 /**
658 * Returns an array of the listeners that are registered with this component.
659 * The array may be empty, but is never <code>null</code>.
660 *
661 * @return An array of listeners.
662 *
663 * @since 1.4
664 */
665 public ChangeListener[] getChangeListeners()
666 {
667 return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
668 }
669
670 /**
671 * Sends a {@link ChangeEvent} to all registered listeners to indicate that
672 * the state of the <code>JProgressBar</code> has changed.
673 *
674 * @see #createChangeListener()
675 */
676 protected void fireStateChanged()
677 {
678 Object[] changeListeners = listenerList.getListenerList();
679 if (changeEvent == null)
680 changeEvent = new ChangeEvent(this);
681 for (int i = changeListeners.length - 2; i >= 0; i -= 2)
682 {
683 if (changeListeners[i] == ChangeListener.class)
684 ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
685 }
686 }
687
688 /**
689 * Returns the model for the <code>JProgressBar</code>.
690 *
691 * @return The model (never <code>null</code>).
692 *
693 * @see #setModel(BoundedRangeModel)
694 */
695 public BoundedRangeModel getModel()
696 {
697 return model;
698 }
699
700 /**
701 * Sets the model for the <code>JProgressBar</code> and sends a
702 * {@link ChangeEvent} to all registered listeners.
703 *
704 * @param model the model (<code>null</code> not permitted).
705 *
706 * @see #getModel()
707 */
708 public void setModel(BoundedRangeModel model)
709 {
710 if (model != this.model)
711 {
712 this.model.removeChangeListener(changeListener);
713 this.model = model;
714 this.model.addChangeListener(changeListener);
715 fireStateChanged();
716 }
717 }
718
719 /**
720 * Returns the minimum value for the <code>JProgressBar</code>. This defines
721 * the lower bound for the current value, and is stored in the component's
722 * <code>model</code>.
723 *
724 * @return The minimum value.
725 *
726 * @see #setMinimum(int)
727 */
728 public int getMinimum()
729 {
730 return model.getMinimum();
731 }
732
733 /**
734 * Sets the minimum value for the <code>JProgressBar</code>. The value is
735 * stored in the component's <code>model</code> (see {@link #getModel()}).
736 * If the new value is different to the old value, a {@link ChangeEvent} is
737 * sent to the model's registered listeners. In turn, this triggers a call
738 * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code>
739 * to this component's registered listeners.
740 *
741 * @param minimum the minimum value.
742 *
743 * @see #getMinimum()
744 */
745 public void setMinimum(int minimum)
746 {
747 model.setMinimum(minimum);
748 }
749
750 /**
751 * Returns the maximum value for the <code>JProgressBar</code>. This defines
752 * the upper bound for the current value, and is stored in the component's
753 * <code>model</code>.
754 *
755 * @return The maximum value.
756 *
757 * @see #setMaximum(int)
758 */
759 public int getMaximum()
760 {
761 return model.getMaximum();
762 }
763
764 /**
765 * Sets the maximum value for the <code>JProgressBar</code>. The value is
766 * stored in the component's <code>model</code> (see {@link #getModel()}).
767 * If the new value is different to the old value, a {@link ChangeEvent} is
768 * sent to the model's registered listeners. In turn, this triggers a call
769 * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code>
770 * to this component's registered listeners.
771 *
772 * @param maximum the maximum value.
773 *
774 * @see #getMaximum()
775 */
776 public void setMaximum(int maximum)
777 {
778 model.setMaximum(maximum);
779 }
780
781 /**
782 * Returns an implementation-dependent string describing the attributes of
783 * this <code>JProgressBar</code>.
784 *
785 * @return A string describing the attributes of this
786 * <code>JProgressBar</code> (never <code>null</code>).
787 */
788 protected String paramString()
789 {
790 String superParamStr = super.paramString();
791 CPStringBuilder sb = new CPStringBuilder();
792 sb.append(",orientation=");
793 if (orientation == HORIZONTAL)
794 sb.append("HORIZONTAL");
795 else
796 sb.append("VERTICAL");
797 sb.append(",paintBorder=").append(isBorderPainted());
798 sb.append(",paintString=").append(isStringPainted());
799 sb.append(",progressString=");
800 if (progressString != null)
801 sb.append(progressString);
802 sb.append(",indeterminateString=").append(isIndeterminate());
803 return superParamStr + sb.toString();
804 }
805
806 /**
807 * Sets the flag that controls the mode for this <code>JProgressBar</code>
808 * (<code>true</code> for indeterminate mode, and <code>false</code> for
809 * determinate mode). If the flag value changes, this method sends a
810 * {@link PropertyChangeEvent} (with the property name
811 * <code>"indeterminate"</code>) to all registered listeners.
812 * <p>
813 * If the <code>JProgressBar</code> is determinate, it paints a percentage
814 * of the bar described by its value. If it is indeterminate, it simply
815 * bounces a box between the ends of the bar; the value of the
816 * <code>JProgressBar</code> is ignored.
817 *
818 * @param flag the new flag value.
819 *
820 * @see #isIndeterminate()
821 * @since 1.4
822 */
823 public void setIndeterminate(boolean flag)
824 {
825 if (indeterminate != flag)
826 {
827 indeterminate = flag;
828 firePropertyChange("indeterminate", !flag, indeterminate);
829 }
830 }
831
832 /**
833 * Returns a flag that indicates the mode for this <code>JProgressBar</code>
834 * (<code>true</code> for indeterminate mode, and <code>false</code> for
835 * determinate mode).
836 *
837 * @return A flag indicating the mode for the <code>JProgressBar</code>.
838 *
839 * @see #setIndeterminate(boolean)
840 * @since 1.4
841 */
842 public boolean isIndeterminate()
843 {
844 return indeterminate;
845 }
846
847 /**
848 * Returns the object that provides accessibility features for this
849 * <code>JProgressBar</code> component.
850 *
851 * @return The accessible context (an instance of
852 * {@link AccessibleJProgressBar}).
853 */
854 public AccessibleContext getAccessibleContext()
855 {
856 if (accessibleContext == null)
857 accessibleContext = new AccessibleJProgressBar();
858
859 return accessibleContext;
860 }
861 }