blob: 337f5b118efd8d85cdb4af17b056904330ab85ba [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package javax.swing;
27
28import java.awt.Color;
29import java.awt.Graphics;
30
31import java.text.Format;
32import java.text.NumberFormat;
33
34import java.io.Serializable;
35import java.io.ObjectOutputStream;
36import java.io.ObjectInputStream;
37import java.io.IOException;
38
39import javax.swing.event.*;
40import javax.accessibility.*;
41import javax.swing.plaf.ProgressBarUI;
42
43
44/**
45 * A component that visually displays the progress of some task. As the task
46 * progresses towards completion, the progress bar displays the
47 * task's percentage of completion.
48 * This percentage is typically represented visually by a rectangle which
49 * starts out empty and gradually becomes filled in as the task progresses.
50 * In addition, the progress bar can display a textual representation of this
51 * percentage.
52 * <p>
53 * {@code JProgressBar} uses a {@code BoundedRangeModel} as its data model,
54 * with the {@code value} property representing the "current" state of the task,
55 * and the {@code minimum} and {@code maximum} properties representing the
56 * beginning and end points, respectively.
57 * <p>
58 * To indicate that a task of unknown length is executing,
59 * you can put a progress bar into indeterminate mode.
60 * While the bar is in indeterminate mode,
61 * it animates constantly to show that work is occurring.
62 * As soon as you can determine the task's length and amount of progress,
63 * you should update the progress bar's value
64 * and switch it back to determinate mode.
65 *
66 * <p>
67 *
68 * Here is an example of creating a progress bar,
69 * where <code>task</code> is an object (representing some piece of work)
70 * which returns information about the progress of the task:
71 *
72 *<pre>
73 *progressBar = new JProgressBar(0, task.getLengthOfTask());
74 *progressBar.setValue(0);
75 *progressBar.setStringPainted(true);
76 *</pre>
77 *
78 * Here is an example of querying the current state of the task, and using
79 * the returned value to update the progress bar:
80 *
81 *<pre>
82 *progressBar.setValue(task.getCurrent());
83 *</pre>
84 *
85 * Here is an example of putting a progress bar into
86 * indeterminate mode,
87 * and then switching back to determinate mode
88 * once the length of the task is known:
89 *
90 *<pre>
91 *progressBar = new JProgressBar();
92 *<em>...//when the task of (initially) unknown length begins:</em>
93 *progressBar.setIndeterminate(true);
94 *<em>...//do some work; get length of task...</em>
95 *progressBar.setMaximum(newLength);
96 *progressBar.setValue(newValue);
97 *progressBar.setIndeterminate(false);
98 *</pre>
99 *
100 * <p>
101 *
102 * For complete examples and further documentation see
103 * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html" target="_top">How to Monitor Progress</a>,
104 * a section in <em>The Java Tutorial.</em>
105 *
106 * <p>
107 * <strong>Warning:</strong> Swing is not thread safe. For more
108 * information see <a
109 * href="package-summary.html#threading">Swing's Threading
110 * Policy</a>.
111 * <p>
112 * <strong>Warning:</strong>
113 * Serialized objects of this class will not be compatible with
114 * future Swing releases. The current serialization support is
115 * appropriate for short term storage or RMI between applications running
116 * the same version of Swing. As of 1.4, support for long term storage
117 * of all JavaBeans<sup><font size="-2">TM</font></sup>
118 * has been added to the <code>java.beans</code> package.
119 * Please see {@link java.beans.XMLEncoder}.
120 *
121 * @see javax.swing.plaf.basic.BasicProgressBarUI
122 * @see javax.swing.BoundedRangeModel
123 * @see javax.swing.SwingWorker
124 *
125 * @beaninfo
126 * attribute: isContainer false
127 * description: A component that displays an integer value.
128 *
129 * @author Michael C. Albers
130 * @author Kathy Walrath
131 */
132public class JProgressBar extends JComponent implements SwingConstants, Accessible
133{
134 /**
135 * @see #getUIClassID
136 */
137 private static final String uiClassID = "ProgressBarUI";
138
139 /**
140 * Whether the progress bar is horizontal or vertical.
141 * The default is <code>HORIZONTAL</code>.
142 *
143 * @see #setOrientation
144 */
145 protected int orientation;
146
147 /**
148 * Whether to display a border around the progress bar.
149 * The default is <code>true</code>.
150 *
151 * @see #setBorderPainted
152 */
153 protected boolean paintBorder;
154
155 /**
156 * The object that holds the data for the progress bar.
157 *
158 * @see #setModel
159 */
160 protected BoundedRangeModel model;
161
162 /**
163 * An optional string that can be displayed on the progress bar.
164 * The default is <code>null</code>. Setting this to a non-<code>null</code>
165 * value does not imply that the string will be displayed.
166 * To display the string, {@code paintString} must be {@code true}.
167 *
168 * @see #setString
169 * @see #setStringPainted
170 */
171 protected String progressString;
172
173 /**
174 * Whether to display a string of text on the progress bar.
175 * The default is <code>false</code>.
176 * Setting this to <code>true</code> causes a textual
177 * display of the progress to be rendered on the progress bar. If
178 * the <code>progressString</code> is <code>null</code>,
179 * the percentage of completion is displayed on the progress bar.
180 * Otherwise, the <code>progressString</code> is
181 * rendered on the progress bar.
182 *
183 * @see #setStringPainted
184 * @see #setString
185 */
186 protected boolean paintString;
187
188 /**
189 * The default minimum for a progress bar is 0.
190 */
191 static final private int defaultMinimum = 0;
192 /**
193 * The default maximum for a progress bar is 100.
194 */
195 static final private int defaultMaximum = 100;
196 /**
197 * The default orientation for a progress bar is <code>HORIZONTAL</code>.
198 */
199 static final private int defaultOrientation = HORIZONTAL;
200
201 /**
202 * Only one <code>ChangeEvent</code> is needed per instance since the
203 * event's only interesting property is the immutable source, which
204 * is the progress bar.
205 * The event is lazily created the first time that an
206 * event notification is fired.
207 *
208 * @see #fireStateChanged
209 */
210 protected transient ChangeEvent changeEvent = null;
211
212 /**
213 * Listens for change events sent by the progress bar's model,
214 * redispatching them
215 * to change-event listeners registered upon
216 * this progress bar.
217 *
218 * @see #createChangeListener
219 */
220 protected ChangeListener changeListener = null;
221
222 /**
223 * Format used when displaying percent complete.
224 */
225 private transient Format format;
226
227 /**
228 * Whether the progress bar is indeterminate (<code>true</code>) or
229 * normal (<code>false</code>); the default is <code>false</code>.
230 *
231 * @see #setIndeterminate
232 * @since 1.4
233 */
234 private boolean indeterminate;
235
236
237 /**
238 * Creates a horizontal progress bar
239 * that displays a border but no progress string.
240 * The initial and minimum values are 0,
241 * and the maximum is 100.
242 *
243 * @see #setOrientation
244 * @see #setBorderPainted
245 * @see #setStringPainted
246 * @see #setString
247 * @see #setIndeterminate
248 */
249 public JProgressBar()
250 {
251 this(defaultOrientation);
252 }
253
254 /**
255 * Creates a progress bar with the specified orientation,
256 * which can be
257 * either {@code SwingConstants.VERTICAL} or
258 * {@code SwingConstants.HORIZONTAL}.
259 * By default, a border is painted but a progress string is not.
260 * The initial and minimum values are 0,
261 * and the maximum is 100.
262 *
263 * @param orient the desired orientation of the progress bar
264 * @throws IllegalArgumentException if {@code orient} is an illegal value
265 *
266 * @see #setOrientation
267 * @see #setBorderPainted
268 * @see #setStringPainted
269 * @see #setString
270 * @see #setIndeterminate
271 */
272 public JProgressBar(int orient)
273 {
274 this(orient, defaultMinimum, defaultMaximum);
275 }
276
277
278 /**
279 * Creates a horizontal progress bar
280 * with the specified minimum and maximum.
281 * Sets the initial value of the progress bar to the specified minimum.
282 * By default, a border is painted but a progress string is not.
283 * <p>
284 * The <code>BoundedRangeModel</code> that holds the progress bar's data
285 * handles any issues that may arise from improperly setting the
286 * minimum, initial, and maximum values on the progress bar.
287 * See the {@code BoundedRangeModel} documentation for details.
288 *
289 * @param min the minimum value of the progress bar
290 * @param max the maximum value of the progress bar
291 *
292 * @see BoundedRangeModel
293 * @see #setOrientation
294 * @see #setBorderPainted
295 * @see #setStringPainted
296 * @see #setString
297 * @see #setIndeterminate
298 */
299 public JProgressBar(int min, int max)
300 {
301 this(defaultOrientation, min, max);
302 }
303
304
305 /**
306 * Creates a progress bar using the specified orientation,
307 * minimum, and maximum.
308 * By default, a border is painted but a progress string is not.
309 * Sets the initial value of the progress bar to the specified minimum.
310 * <p>
311 * The <code>BoundedRangeModel</code> that holds the progress bar's data
312 * handles any issues that may arise from improperly setting the
313 * minimum, initial, and maximum values on the progress bar.
314 * See the {@code BoundedRangeModel} documentation for details.
315 *
316 * @param orient the desired orientation of the progress bar
317 * @param min the minimum value of the progress bar
318 * @param max the maximum value of the progress bar
319 * @throws IllegalArgumentException if {@code orient} is an illegal value
320 *
321 * @see BoundedRangeModel
322 * @see #setOrientation
323 * @see #setBorderPainted
324 * @see #setStringPainted
325 * @see #setString
326 * @see #setIndeterminate
327 */
328 public JProgressBar(int orient, int min, int max)
329 {
330 // Creating the model this way is a bit simplistic, but
331 // I believe that it is the the most common usage of this
332 // component - it's what people will expect.
333 setModel(new DefaultBoundedRangeModel(min, 0, min, max));
334 updateUI();
335
336 setOrientation(orient); // documented with set/getOrientation()
337 setBorderPainted(true); // documented with is/setBorderPainted()
338 setStringPainted(false); // see setStringPainted
339 setString(null); // see getString
340 setIndeterminate(false); // see setIndeterminate
341 }
342
343
344 /**
345 * Creates a horizontal progress bar
346 * that uses the specified model
347 * to hold the progress bar's data.
348 * By default, a border is painted but a progress string is not.
349 *
350 * @param newModel the data model for the progress bar
351 *
352 * @see #setOrientation
353 * @see #setBorderPainted
354 * @see #setStringPainted
355 * @see #setString
356 * @see #setIndeterminate
357 */
358 public JProgressBar(BoundedRangeModel newModel)
359 {
360 setModel(newModel);
361 updateUI();
362
363 setOrientation(defaultOrientation); // see setOrientation()
364 setBorderPainted(true); // see setBorderPainted()
365 setStringPainted(false); // see setStringPainted
366 setString(null); // see getString
367 setIndeterminate(false); // see setIndeterminate
368 }
369
370
371 /**
372 * Returns {@code SwingConstants.VERTICAL} or
373 * {@code SwingConstants.HORIZONTAL}, depending on the orientation
374 * of the progress bar. The default orientation is
375 * {@code SwingConstants.HORIZONTAL}.
376 *
377 * @return <code>HORIZONTAL</code> or <code>VERTICAL</code>
378 * @see #setOrientation
379 */
380 public int getOrientation() {
381 return orientation;
382 }
383
384
385 /**
386 * Sets the progress bar's orientation to <code>newOrientation</code>,
387 * which must be {@code SwingConstants.VERTICAL} or
388 * {@code SwingConstants.HORIZONTAL}. The default orientation
389 * is {@code SwingConstants.HORIZONTAL}.
390 *
391 * @param newOrientation <code>HORIZONTAL</code> or <code>VERTICAL</code>
392 * @exception IllegalArgumentException if <code>newOrientation</code>
393 * is an illegal value
394 * @see #getOrientation
395 *
396 * @beaninfo
397 * preferred: true
398 * bound: true
399 * attribute: visualUpdate true
400 * description: Set the progress bar's orientation.
401 */
402 public void setOrientation(int newOrientation) {
403 if (orientation != newOrientation) {
404 switch (newOrientation) {
405 case VERTICAL:
406 case HORIZONTAL:
407 int oldOrientation = orientation;
408 orientation = newOrientation;
409 firePropertyChange("orientation", oldOrientation, newOrientation);
410 if (accessibleContext != null) {
411 accessibleContext.firePropertyChange(
412 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
413 ((oldOrientation == VERTICAL)
414 ? AccessibleState.VERTICAL
415 : AccessibleState.HORIZONTAL),
416 ((orientation == VERTICAL)
417 ? AccessibleState.VERTICAL
418 : AccessibleState.HORIZONTAL));
419 }
420 break;
421 default:
422 throw new IllegalArgumentException(newOrientation +
423 " is not a legal orientation");
424 }
425 revalidate();
426 }
427 }
428
429
430 /**
431 * Returns the value of the <code>stringPainted</code> property.
432 *
433 * @return the value of the <code>stringPainted</code> property
434 * @see #setStringPainted
435 * @see #setString
436 */
437 public boolean isStringPainted() {
438 return paintString;
439 }
440
441
442 /**
443 * Sets the value of the <code>stringPainted</code> property,
444 * which determines whether the progress bar
445 * should render a progress string.
446 * The default is <code>false</code>, meaning
447 * no string is painted.
448 * Some look and feels might not support progress strings
449 * or might support them only when the progress bar is in determinate mode.
450 *
451 * @param b <code>true</code> if the progress bar should render a string
452 * @see #isStringPainted
453 * @see #setString
454 * @beaninfo
455 * bound: true
456 * attribute: visualUpdate true
457 * description: Whether the progress bar should render a string.
458 */
459 public void setStringPainted(boolean b) {
460 //PENDING: specify that string not painted when in indeterminate mode?
461 // or just leave that to the L&F?
462 boolean oldValue = paintString;
463 paintString = b;
464 firePropertyChange("stringPainted", oldValue, paintString);
465 if (paintString != oldValue) {
466 revalidate();
467 repaint();
468 }
469 }
470
471
472 /**
473 * Returns a {@code String} representation of the current progress.
474 * By default, this returns a simple percentage {@code String} based on
475 * the value returned from {@code getPercentComplete}. An example
476 * would be the "42%". You can change this by calling {@code setString}.
477 *
478 * @return the value of the progress string, or a simple percentage string
479 * if the progress string is {@code null}
480 * @see #setString
481 */
482 public String getString(){
483 if (progressString != null) {
484 return progressString;
485 } else {
486 if (format == null) {
487 format = NumberFormat.getPercentInstance();
488 }
489 return format.format(new Double(getPercentComplete()));
490 }
491 }
492
493 /**
494 * Sets the value of the progress string. By default,
495 * this string is <code>null</code>, implying the built-in behavior of
496 * using a simple percent string.
497 * If you have provided a custom progress string and want to revert to
498 * the built-in behavior, set the string back to <code>null</code>.
499 * <p>
500 * The progress string is painted only if
501 * the <code>isStringPainted</code> method returns <code>true</code>.
502 *
503 * @param s the value of the progress string
504 * @see #getString
505 * @see #setStringPainted
506 * @see #isStringPainted
507 * @beaninfo
508 * bound: true
509 * attribute: visualUpdate true
510 * description: Specifies the progress string to paint
511 */
512 public void setString(String s){
513 String oldValue = progressString;
514 progressString = s;
515 firePropertyChange("string", oldValue, progressString);
516 if (progressString == null || oldValue == null || !progressString.equals(oldValue)) {
517 repaint();
518 }
519 }
520
521 /**
522 * Returns the percent complete for the progress bar.
523 * Note that this number is between 0.0 and 1.0.
524 *
525 * @return the percent complete for this progress bar
526 */
527 public double getPercentComplete() {
528 long span = model.getMaximum() - model.getMinimum();
529 double currentValue = model.getValue();
530 double pc = (currentValue - model.getMinimum()) / span;
531 return pc;
532 }
533
534 /**
535 * Returns the <code>borderPainted</code> property.
536 *
537 * @return the value of the <code>borderPainted</code> property
538 * @see #setBorderPainted
539 * @beaninfo
540 * description: Does the progress bar paint its border
541 */
542 public boolean isBorderPainted() {
543 return paintBorder;
544 }
545
546 /**
547 * Sets the <code>borderPainted</code> property, which is
548 * <code>true</code> if the progress bar should paint its border.
549 * The default value for this property is <code>true</code>.
550 * Some look and feels might not implement painted borders;
551 * they will ignore this property.
552 *
553 * @param b <code>true</code> if the progress bar
554 * should paint its border;
555 * otherwise, <code>false</code>
556 * @see #isBorderPainted
557 * @beaninfo
558 * bound: true
559 * attribute: visualUpdate true
560 * description: Whether the progress bar should paint its border.
561 */
562 public void setBorderPainted(boolean b) {
563 boolean oldValue = paintBorder;
564 paintBorder = b;
565 firePropertyChange("borderPainted", oldValue, paintBorder);
566 if (paintBorder != oldValue) {
567 repaint();
568 }
569 }
570
571 /**
572 * Paints the progress bar's border if the <code>borderPainted</code>
573 * property is <code>true</code>.
574 *
575 * @param g the <code>Graphics</code> context within which to paint the border
576 * @see #paint
577 * @see #setBorder
578 * @see #isBorderPainted
579 * @see #setBorderPainted
580 */
581 protected void paintBorder(Graphics g) {
582 if (isBorderPainted()) {
583 super.paintBorder(g);
584 }
585 }
586
587
588 /**
589 * Returns the look-and-feel object that renders this component.
590 *
591 * @return the <code>ProgressBarUI</code> object that renders this component
592 */
593 public ProgressBarUI getUI() {
594 return (ProgressBarUI)ui;
595 }
596
597 /**
598 * Sets the look-and-feel object that renders this component.
599 *
600 * @param ui a <code>ProgressBarUI</code> object
601 * @see UIDefaults#getUI
602 * @beaninfo
603 * bound: true
604 * hidden: true
605 * attribute: visualUpdate true
606 * description: The UI object that implements the Component's LookAndFeel.
607 */
608 public void setUI(ProgressBarUI ui) {
609 super.setUI(ui);
610 }
611
612
613 /**
614 * Resets the UI property to a value from the current look and feel.
615 *
616 * @see JComponent#updateUI
617 */
618 public void updateUI() {
619 setUI((ProgressBarUI)UIManager.getUI(this));
620 }
621
622
623 /**
624 * Returns the name of the look-and-feel class that renders this component.
625 *
626 * @return the string "ProgressBarUI"
627 * @see JComponent#getUIClassID
628 * @see UIDefaults#getUI
629 * @beaninfo
630 * expert: true
631 * description: A string that specifies the name of the look-and-feel class.
632 */
633 public String getUIClassID() {
634 return uiClassID;
635 }
636
637
638 /* We pass each Change event to the listeners with the
639 * the progress bar as the event source.
640 * <p>
641 * <strong>Warning:</strong>
642 * Serialized objects of this class will not be compatible with
643 * future Swing releases. The current serialization support is
644 * appropriate for short term storage or RMI between applications running
645 * the same version of Swing. As of 1.4, support for long term storage
646 * of all JavaBeans<sup><font size="-2">TM</font></sup>
647 * has been added to the <code>java.beans</code> package.
648 * Please see {@link java.beans.XMLEncoder}.
649 */
650 private class ModelListener implements ChangeListener, Serializable {
651 public void stateChanged(ChangeEvent e) {
652 fireStateChanged();
653 }
654 }
655
656 /**
657 * Subclasses that want to handle change events
658 * from the model differently
659 * can override this to return
660 * an instance of a custom <code>ChangeListener</code> implementation.
661 * The default {@code ChangeListener} simply calls the
662 * {@code fireStateChanged} method to forward {@code ChangeEvent}s
663 * to the {@code ChangeListener}s that have been added directly to the
664 * progress bar.
665 *
666 * @see #changeListener
667 * @see #fireStateChanged
668 * @see javax.swing.event.ChangeListener
669 * @see javax.swing.BoundedRangeModel
670 */
671 protected ChangeListener createChangeListener() {
672 return new ModelListener();
673 }
674
675 /**
676 * Adds the specified <code>ChangeListener</code> to the progress bar.
677 *
678 * @param l the <code>ChangeListener</code> to add
679 */
680 public void addChangeListener(ChangeListener l) {
681 listenerList.add(ChangeListener.class, l);
682 }
683
684 /**
685 * Removes a <code>ChangeListener</code> from the progress bar.
686 *
687 * @param l the <code>ChangeListener</code> to remove
688 */
689 public void removeChangeListener(ChangeListener l) {
690 listenerList.remove(ChangeListener.class, l);
691 }
692
693 /**
694 * Returns an array of all the <code>ChangeListener</code>s added
695 * to this progress bar with <code>addChangeListener</code>.
696 *
697 * @return all of the <code>ChangeListener</code>s added or an empty
698 * array if no listeners have been added
699 * @since 1.4
700 */
701 public ChangeListener[] getChangeListeners() {
702 return (ChangeListener[])listenerList.getListeners(
703 ChangeListener.class);
704 }
705
706 /**
707 * Send a {@code ChangeEvent}, whose source is this {@code JProgressBar}, to
708 * all {@code ChangeListener}s that have registered interest in
709 * {@code ChangeEvent}s.
710 * This method is called each time a {@code ChangeEvent} is received from
711 * the model.
712 * <p>
713 *
714 * The event instance is created if necessary, and stored in
715 * {@code changeEvent}.
716 *
717 * @see #addChangeListener
718 * @see EventListenerList
719 */
720 protected void fireStateChanged() {
721 // Guaranteed to return a non-null array
722 Object[] listeners = listenerList.getListenerList();
723 // Process the listeners last to first, notifying
724 // those that are interested in this event
725 for (int i = listeners.length-2; i>=0; i-=2) {
726 if (listeners[i]==ChangeListener.class) {
727 // Lazily create the event:
728 if (changeEvent == null)
729 changeEvent = new ChangeEvent(this);
730 ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
731 }
732 }
733 }
734
735 /**
736 * Returns the data model used by this progress bar.
737 *
738 * @return the <code>BoundedRangeModel</code> currently in use
739 * @see #setModel
740 * @see BoundedRangeModel
741 */
742 public BoundedRangeModel getModel() {
743 return model;
744 }
745
746 /**
747 * Sets the data model used by the <code>JProgressBar</code>.
748 * Note that the {@code BoundedRangeModel}'s {@code extent} is not used,
749 * and is set to {@code 0}.
750 *
751 * @param newModel the <code>BoundedRangeModel</code> to use
752 *
753 * @beaninfo
754 * expert: true
755 * description: The data model used by the JProgressBar.
756 */
757 public void setModel(BoundedRangeModel newModel) {
758 // PENDING(???) setting the same model to multiple bars is broken; listeners
759 BoundedRangeModel oldModel = getModel();
760
761 if (newModel != oldModel) {
762 if (oldModel != null) {
763 oldModel.removeChangeListener(changeListener);
764 changeListener = null;
765 }
766
767 model = newModel;
768
769 if (newModel != null) {
770 changeListener = createChangeListener();
771 newModel.addChangeListener(changeListener);
772 }
773
774 if (accessibleContext != null) {
775 accessibleContext.firePropertyChange(
776 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
777 (oldModel== null
778 ? null : new Integer(oldModel.getValue())),
779 (newModel== null
780 ? null : new Integer(newModel.getValue())));
781 }
782
783 if (model != null) {
784 model.setExtent(0);
785 }
786 repaint();
787 }
788 }
789
790
791 /* All of the model methods are implemented by delegation. */
792
793 /**
794 * Returns the progress bar's current {@code value}
795 * from the <code>BoundedRangeModel</code>.
796 * The value is always between the
797 * minimum and maximum values, inclusive.
798 *
799 * @return the current value of the progress bar
800 * @see #setValue
801 * @see BoundedRangeModel#getValue
802 */
803 public int getValue() { return getModel().getValue(); }
804
805 /**
806 * Returns the progress bar's {@code minimum} value
807 * from the <code>BoundedRangeModel</code>.
808 *
809 * @return the progress bar's minimum value
810 * @see #setMinimum
811 * @see BoundedRangeModel#getMinimum
812 */
813 public int getMinimum() { return getModel().getMinimum(); }
814
815 /**
816 * Returns the progress bar's {@code maximum} value
817 * from the <code>BoundedRangeModel</code>.
818 *
819 * @return the progress bar's maximum value
820 * @see #setMaximum
821 * @see BoundedRangeModel#getMaximum
822 */
823 public int getMaximum() { return getModel().getMaximum(); }
824
825 /**
826 * Sets the progress bar's current value to {@code n}. This method
827 * forwards the new value to the model.
828 * <p>
829 * The data model (an instance of {@code BoundedRangeModel})
830 * handles any mathematical
831 * issues arising from assigning faulty values. See the
832 * {@code BoundedRangeModel} documentation for details.
833 * <p>
834 * If the new value is different from the previous value,
835 * all change listeners are notified.
836 *
837 * @param n the new value
838 * @see #getValue
839 * @see #addChangeListener
840 * @see BoundedRangeModel#setValue
841 * @beaninfo
842 * preferred: true
843 * description: The progress bar's current value.
844 */
845 public void setValue(int n) {
846 BoundedRangeModel brm = getModel();
847 int oldValue = brm.getValue();
848 brm.setValue(n);
849
850 if (accessibleContext != null) {
851 accessibleContext.firePropertyChange(
852 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
853 new Integer(oldValue),
854 new Integer(brm.getValue()));
855 }
856 }
857
858 /**
859 * Sets the progress bar's minimum value
860 * (stored in the progress bar's data model) to <code>n</code>.
861 * <p>
862 * The data model (a <code>BoundedRangeModel</code> instance)
863 * handles any mathematical
864 * issues arising from assigning faulty values.
865 * See the {@code BoundedRangeModel} documentation for details.
866 * <p>
867 * If the minimum value is different from the previous minimum,
868 * all change listeners are notified.
869 *
870 * @param n the new minimum
871 * @see #getMinimum
872 * @see #addChangeListener
873 * @see BoundedRangeModel#setMinimum
874 * @beaninfo
875 * preferred: true
876 * description: The progress bar's minimum value.
877 */
878 public void setMinimum(int n) { getModel().setMinimum(n); }
879
880 /**
881 * Sets the progress bar's maximum value
882 * (stored in the progress bar's data model) to <code>n</code>.
883 * <p>
884 * The underlying <code>BoundedRangeModel</code> handles any mathematical
885 * issues arising from assigning faulty values.
886 * See the {@code BoundedRangeModel} documentation for details.
887 * <p>
888 * If the maximum value is different from the previous maximum,
889 * all change listeners are notified.
890 *
891 * @param n the new maximum
892 * @see #getMaximum
893 * @see #addChangeListener
894 * @see BoundedRangeModel#setMaximum
895 * @beaninfo
896 * preferred: true
897 * description: The progress bar's maximum value.
898 */
899 public void setMaximum(int n) { getModel().setMaximum(n); }
900
901 /**
902 * Sets the <code>indeterminate</code> property of the progress bar,
903 * which determines whether the progress bar is in determinate
904 * or indeterminate mode.
905 * An indeterminate progress bar continuously displays animation
906 * indicating that an operation of unknown length is occurring.
907 * By default, this property is <code>false</code>.
908 * Some look and feels might not support indeterminate progress bars;
909 * they will ignore this property.
910 *
911 * <p>
912 *
913 * See
914 * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html" target="_top">How to Monitor Progress</a>
915 * for examples of using indeterminate progress bars.
916 *
917 * @param newValue <code>true</code> if the progress bar
918 * should change to indeterminate mode;
919 * <code>false</code> if it should revert to normal.
920 *
921 * @see #isIndeterminate
922 * @see javax.swing.plaf.basic.BasicProgressBarUI
923 *
924 * @since 1.4
925 *
926 * @beaninfo
927 * bound: true
928 * attribute: visualUpdate true
929 * description: Set whether the progress bar is indeterminate (true)
930 * or normal (false).
931 */
932 public void setIndeterminate(boolean newValue) {
933 boolean oldValue = indeterminate;
934 indeterminate = newValue;
935 firePropertyChange("indeterminate", oldValue, indeterminate);
936 }
937
938 /**
939 * Returns the value of the <code>indeterminate</code> property.
940 *
941 * @return the value of the <code>indeterminate</code> property
942 * @see #setIndeterminate
943 *
944 * @since 1.4
945 *
946 * @beaninfo
947 * description: Is the progress bar indeterminate (true)
948 * or normal (false)?
949 */
950 public boolean isIndeterminate() {
951 return indeterminate;
952 }
953
954
955 /**
956 * See readObject() and writeObject() in JComponent for more
957 * information about serialization in Swing.
958 */
959 private void writeObject(ObjectOutputStream s) throws IOException {
960 s.defaultWriteObject();
961 if (getUIClassID().equals(uiClassID)) {
962 byte count = JComponent.getWriteObjCounter(this);
963 JComponent.setWriteObjCounter(this, --count);
964 if (count == 0 && ui != null) {
965 ui.installUI(this);
966 }
967 }
968 }
969
970
971 /**
972 * Returns a string representation of this <code>JProgressBar</code>.
973 * This method is intended to be used only for debugging purposes. The
974 * content and format of the returned string may vary between
975 * implementations. The returned string may be empty but may not
976 * be <code>null</code>.
977 *
978 * @return a string representation of this <code>JProgressBar</code>
979 */
980 protected String paramString() {
981 String orientationString = (orientation == HORIZONTAL ?
982 "HORIZONTAL" : "VERTICAL");
983 String paintBorderString = (paintBorder ?
984 "true" : "false");
985 String progressStringString = (progressString != null ?
986 progressString : "");
987 String paintStringString = (paintString ?
988 "true" : "false");
989 String indeterminateString = (indeterminate ?
990 "true" : "false");
991
992 return super.paramString() +
993 ",orientation=" + orientationString +
994 ",paintBorder=" + paintBorderString +
995 ",paintString=" + paintStringString +
996 ",progressString=" + progressStringString +
997 ",indeterminateString=" + indeterminateString;
998 }
999
1000/////////////////
1001// Accessibility support
1002////////////////
1003
1004 /**
1005 * Gets the <code>AccessibleContext</code> associated with this
1006 * <code>JProgressBar</code>. For progress bars, the
1007 * <code>AccessibleContext</code> takes the form of an
1008 * <code>AccessibleJProgressBar</code>.
1009 * A new <code>AccessibleJProgressBar</code> instance is created if necessary.
1010 *
1011 * @return an <code>AccessibleJProgressBar</code> that serves as the
1012 * <code>AccessibleContext</code> of this <code>JProgressBar</code>
1013 * @beaninfo
1014 * expert: true
1015 * description: The AccessibleContext associated with this ProgressBar.
1016 */
1017 public AccessibleContext getAccessibleContext() {
1018 if (accessibleContext == null) {
1019 accessibleContext = new AccessibleJProgressBar();
1020 }
1021 return accessibleContext;
1022 }
1023
1024 /**
1025 * This class implements accessibility support for the
1026 * <code>JProgressBar</code> class. It provides an implementation of the
1027 * Java Accessibility API appropriate to progress bar user-interface
1028 * elements.
1029 * <p>
1030 * <strong>Warning:</strong>
1031 * Serialized objects of this class will not be compatible with
1032 * future Swing releases. The current serialization support is
1033 * appropriate for short term storage or RMI between applications running
1034 * the same version of Swing. As of 1.4, support for long term storage
1035 * of all JavaBeans<sup><font size="-2">TM</font></sup>
1036 * has been added to the <code>java.beans</code> package.
1037 * Please see {@link java.beans.XMLEncoder}.
1038 */
1039 protected class AccessibleJProgressBar extends AccessibleJComponent
1040 implements AccessibleValue {
1041
1042 /**
1043 * Gets the state set of this object.
1044 *
1045 * @return an instance of AccessibleState containing the current state
1046 * of the object
1047 * @see AccessibleState
1048 */
1049 public AccessibleStateSet getAccessibleStateSet() {
1050 AccessibleStateSet states = super.getAccessibleStateSet();
1051 if (getModel().getValueIsAdjusting()) {
1052 states.add(AccessibleState.BUSY);
1053 }
1054 if (getOrientation() == VERTICAL) {
1055 states.add(AccessibleState.VERTICAL);
1056 } else {
1057 states.add(AccessibleState.HORIZONTAL);
1058 }
1059 return states;
1060 }
1061
1062 /**
1063 * Gets the role of this object.
1064 *
1065 * @return an instance of AccessibleRole describing the role of the
1066 * object
1067 */
1068 public AccessibleRole getAccessibleRole() {
1069 return AccessibleRole.PROGRESS_BAR;
1070 }
1071
1072 /**
1073 * Gets the <code>AccessibleValue</code> associated with this object. In the
1074 * implementation of the Java Accessibility API for this class,
1075 * returns this object, which is responsible for implementing the
1076 * <code>AccessibleValue</code> interface on behalf of itself.
1077 *
1078 * @return this object
1079 */
1080 public AccessibleValue getAccessibleValue() {
1081 return this;
1082 }
1083
1084 /**
1085 * Gets the accessible value of this object.
1086 *
1087 * @return the current value of this object
1088 */
1089 public Number getCurrentAccessibleValue() {
1090 return new Integer(getValue());
1091 }
1092
1093 /**
1094 * Sets the value of this object as a <code>Number</code>.
1095 *
1096 * @return <code>true</code> if the value was set
1097 */
1098 public boolean setCurrentAccessibleValue(Number n) {
1099 // TIGER- 4422535
1100 if (n == null) {
1101 return false;
1102 }
1103 setValue(n.intValue());
1104 return true;
1105 }
1106
1107 /**
1108 * Gets the minimum accessible value of this object.
1109 *
1110 * @return the minimum value of this object
1111 */
1112 public Number getMinimumAccessibleValue() {
1113 return new Integer(getMinimum());
1114 }
1115
1116 /**
1117 * Gets the maximum accessible value of this object.
1118 *
1119 * @return the maximum value of this object
1120 */
1121 public Number getMaximumAccessibleValue() {
1122 // TIGER - 4422362
1123 return new Integer(model.getMaximum() - model.getExtent());
1124 }
1125
1126 } // AccessibleJProgressBar
1127}