libjava/ChangeLog:
[official-gcc.git] / libjava / classpath / javax / swing / JProgressBar.java
blobb20b02a060653d9243f93f19dc7ead76fc927627
1 /* JProgressBar.java --
2 Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing;
41 import gnu.java.lang.CPStringBuilder;
43 import java.awt.Graphics;
44 import java.beans.PropertyChangeEvent;
46 import javax.accessibility.Accessible;
47 import javax.accessibility.AccessibleContext;
48 import javax.accessibility.AccessibleRole;
49 import javax.accessibility.AccessibleState;
50 import javax.accessibility.AccessibleStateSet;
51 import javax.accessibility.AccessibleValue;
52 import javax.swing.border.Border;
53 import javax.swing.event.ChangeEvent;
54 import javax.swing.event.ChangeListener;
55 import javax.swing.plaf.ProgressBarUI;
57 /**
58 * A component that displays a visual indicator of the progress of a task. The
59 * component has two modes: determinate and indeterminate. In determinate mode,
60 * the <code>JProgressBar</code> fills a percentage of its bar based on its
61 * current value. In indeterminate mode, it creates box and bounces it between
62 * its bounds.
63 * <p>
64 * This component has the following properties:
65 * </p>
66 * <table>
67 * <tr><th> Property </th><th> Stored in </th><th> Bound? </th></tr>
68 * <tr><td> borderPainted </td><td> progressBar </td><td> yes </td></tr>
69 * <tr><td> changeListeners </td><td> progressBar </td><td> no </td></tr>
70 * <tr><td> indeterminate </td><td> progressBar </td><td> yes </td></tr>
71 * <tr><td> maximum </td><td> model </td><td> no </td></tr>
72 * <tr><td> minimum </td><td> model </td><td> no </td></tr>
73 * <tr><td> model </td><td> progressBar </td><td> no </td></tr>
74 * <tr><td> orientation </td><td> progressBar </td><td> yes </td></tr>
75 * <tr><td> percentComplete </td><td> progressBar </td><td> no </td></tr>
76 * <tr><td> string </td><td> progressBar </td><td> yes </td></tr>
77 * <tr><td> stringPainted </td><td> progressBar </td><td> yes </td></tr>
78 * <tr><td> value </td><td> model </td><td> no </td></tr>
79 * </table>
81 public class JProgressBar extends JComponent implements SwingConstants,
82 Accessible
84 /**
85 * Provides the accessibility features for the <code>JProgressBar</code>
86 * component.
88 protected class AccessibleJProgressBar extends AccessibleJComponent
89 implements AccessibleValue
91 private static final long serialVersionUID = -2938130009392721813L;
93 /**
94 * Creates a new <code>AccessibleJProgressBar</code> instance.
96 protected AccessibleJProgressBar()
98 // Nothing to do here.
102 * Returns a set containing the current state of the {@link JProgressBar}
103 * component.
105 * @return The accessible state set.
107 public AccessibleStateSet getAccessibleStateSet()
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;
118 * Returns the accessible role for the <code>JProgressBar</code> component.
120 * @return {@link AccessibleRole#PROGRESS_BAR}.
122 public AccessibleRole getAccessibleRole()
124 return AccessibleRole.PROGRESS_BAR;
128 * Returns an object that provides access to the current, minimum and
129 * maximum values.
131 * @return The accessible value.
133 public AccessibleValue getAccessibleValue()
135 return this;
139 * Returns the current value of the {@link JProgressBar} component, as an
140 * {@link Integer}.
142 * @return The current value of the {@link JProgressBar} component.
144 public Number getCurrentAccessibleValue()
146 return new Integer(getValue());
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>.
156 * @param value the new progress bar value (<code>null</code> permitted).
158 * @return <code>true</code> if the slider value is updated, and
159 * <code>false</code> otherwise.
161 public boolean setCurrentAccessibleValue(Number value)
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;
173 * Returns the minimum value of the {@link JProgressBar} component, as an
174 * {@link Integer}.
176 * @return The minimum value of the {@link JProgressBar} component.
178 public Number getMinimumAccessibleValue()
180 return new Integer(getMinimum());
184 * Returns the maximum value of the {@link JProgressBar} component, as an
185 * {@link Integer}.
187 * @return The maximum value of the {@link JProgressBar} component.
189 public Number getMaximumAccessibleValue()
191 return new Integer(getMaximum());
195 private static final long serialVersionUID = 1980046021813598781L;
197 /**
198 * A flag that determines the mode (<code>true</code> for indeterminate,
199 * <code>false</code> for determinate).
201 private transient boolean indeterminate = false;
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)
209 protected int orientation;
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)
216 protected boolean paintBorder = true;
218 /**
219 * The model defining the bounds and current value for the progress bar.
220 * @see #setModel(BoundedRangeModel)
222 protected BoundedRangeModel model;
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)
229 protected String progressString;
231 /**
232 * A flag that controls whether a string is displayed within the progress
233 * bar.
234 * @see #setStringPainted(boolean)
236 protected boolean paintString = false;
238 /**
239 * A single change event reused for all events.
240 * @see #fireStateChanged()
242 protected transient ChangeEvent changeEvent;
244 /**
245 * The listener that is registered with the model. */
246 protected ChangeListener changeListener;
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>
259 public JProgressBar()
261 this(HORIZONTAL, 0, 100);
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>
274 * @param orientation the orientation ({@link #HORIZONTAL} or
275 * {@link #VERTICAL}).
277 * @throws IllegalArgumentException if <code>orientation</code> is not one of
278 * the specified values.
280 public JProgressBar(int orientation)
282 this(orientation, 0, 100);
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>
294 * @param minimum the lower bound of the value range.
295 * @param maximum the upper bound of the value range.
297 public JProgressBar(int minimum, int maximum)
299 this(HORIZONTAL, minimum, maximum);
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>
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}).
315 * @throws IllegalArgumentException if <code>orientation</code> is not one of
316 * the specified values.
318 public JProgressBar(int orientation, int minimum, int maximum)
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();
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>
338 * @param model the model (<code>null</code> not permitted).
340 public JProgressBar(BoundedRangeModel model)
342 this.model = model;
343 changeListener = createChangeListener();
344 if (model != null)
345 model.addChangeListener(changeListener);
346 updateUI();
350 * Returns the current value for the <code>JProgressBar</code>. This value
351 * is fetched from the model.
353 * @return The current value.
355 * @see #setValue(int)
357 public int getValue()
359 return model.getValue();
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.
374 * @param value the new value.
376 * @see #getValue()
378 public void setValue(int value)
380 model.setValue(value);
384 * Paints the component's border, but only if {@link #isBorderPainted()}
385 * returns <code>true</code>.
387 * @param graphics the graphics object to paint with.
389 * @see #setBorderPainted(boolean)
391 protected void paintBorder(Graphics graphics)
393 Border border = getBorder();
394 if (paintBorder && border != null)
395 border.paintBorder(this, graphics, 0, 0, getWidth(), getHeight());
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>.
404 * @return The orientation.
406 * @see #setOrientation(int)
408 public int getOrientation()
410 return orientation;
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.
418 * @param orientation the orientation ({@link #HORIZONTAL} or
419 * {@link #VERTICAL}).
421 * @throws IllegalArgumentException if <code>orientation</code> is not
422 * one of the listed values.
424 * @see #getOrientation()
426 public void setOrientation(int orientation)
428 if (orientation != VERTICAL && orientation != HORIZONTAL)
429 throw new IllegalArgumentException(orientation
430 + " is not a legal orientation");
431 if (this.orientation != orientation)
433 int oldOrientation = this.orientation;
434 this.orientation = orientation;
435 firePropertyChange("orientation", oldOrientation, this.orientation);
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.
444 * @return <code>true</code> if the string should be displayed, and
445 * <code>false</code> otherwise.
447 * @see #setStringPainted(boolean)
449 public boolean isStringPainted()
451 return paintString;
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.
461 * @param painted the new flag value.
463 * @see #isStringPainted()
464 * @see #setString(String)
466 public void setStringPainted(boolean painted)
468 if (paintString != painted)
470 boolean oldPainted = paintString;
471 paintString = painted;
472 firePropertyChange("stringPainted", oldPainted, paintString);
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()}.
482 * @return The string.
484 * @see #setString(String)
485 * @see #setStringPainted(boolean)
487 public String getString()
489 if (progressString != null)
490 return progressString;
491 else
492 return (int) (getPercentComplete() * 100) + "%";
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.
502 * @param string the string (<code>null</code> permitted).
504 * @see #getString()
505 * @see #setStringPainted(boolean)
507 public void setString(String string)
509 if (((string == null || progressString == null) &&
510 string != progressString) || (string != null &&
511 ! string.equals(progressString)))
513 String oldString = progressString;
514 progressString = string;
515 firePropertyChange("string", oldString, progressString);
520 * Returns the current value expressed as a percentage. This is calculated
521 * as <code>(value - min) / (max - min)</code>.
523 * @return The percentage (a value in the range 0.0 to 1.0).
525 public double getPercentComplete()
527 if (getMaximum() == getMinimum())
528 return 1.0;
529 else
530 return (double) (model.getValue() - model.getMinimum())
531 / (model.getMaximum() - model.getMinimum());
535 * Returns a flag that controls whether or not the component's border is
536 * painted. The default value is <code>true</code>.
538 * @return <code>true</code> if the component's border should be painted,
539 * and <code>false</code> otherwise.
541 * @see #setBorderPainted(boolean)
543 public boolean isBorderPainted()
545 return paintBorder;
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.
554 * @param painted the new flag value.
556 * @see #isBorderPainted()
557 * @see #paintBorder
559 public void setBorderPainted(boolean painted)
561 if (painted != paintBorder)
563 boolean oldPainted = paintBorder;
564 paintBorder = painted;
565 firePropertyChange("borderPainted", oldPainted, paintBorder);
570 * Returns the UI delegate for this <code>JProgressBar</code>.
572 * @return The UI delegate.
574 public ProgressBarUI getUI()
576 return (ProgressBarUI) ui;
580 * Sets the UI delegate for this component.
582 * @param ui the new UI delegate.
584 public void setUI(ProgressBarUI ui)
586 super.setUI(ui);
590 * Sets this <code>JProgressBar</code>'s UI delegate to the default
591 * (obtained from the {@link UIManager}) for the current look and feel.
593 public void updateUI()
595 setUI((ProgressBarUI) UIManager.getUI(this));
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>.
603 * @return <code>"ProgressBarUI"</code>.
605 public String getUIClassID()
607 return "ProgressBarUI";
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.
618 * @return A new listener.
620 protected ChangeListener createChangeListener()
622 return new ChangeListener()
624 public void stateChanged(ChangeEvent ce)
626 fireStateChanged();
632 * Registers a listener with this component so that it will receive
633 * notification of component state changes.
635 * @param listener the listener.
637 * @see #removeChangeListener(ChangeListener)
639 public void addChangeListener(ChangeListener listener)
641 listenerList.add(ChangeListener.class, listener);
645 * Deregisters a listener so that it no longer receives notification of
646 * component state changes.
648 * @param listener the listener.
650 * @see #addChangeListener(ChangeListener)
652 public void removeChangeListener(ChangeListener listener)
654 listenerList.remove(ChangeListener.class, listener);
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>.
661 * @return An array of listeners.
663 * @since 1.4
665 public ChangeListener[] getChangeListeners()
667 return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
671 * Sends a {@link ChangeEvent} to all registered listeners to indicate that
672 * the state of the <code>JProgressBar</code> has changed.
674 * @see #createChangeListener()
676 protected void fireStateChanged()
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)
683 if (changeListeners[i] == ChangeListener.class)
684 ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
689 * Returns the model for the <code>JProgressBar</code>.
691 * @return The model (never <code>null</code>).
693 * @see #setModel(BoundedRangeModel)
695 public BoundedRangeModel getModel()
697 return model;
701 * Sets the model for the <code>JProgressBar</code> and sends a
702 * {@link ChangeEvent} to all registered listeners.
704 * @param model the model (<code>null</code> not permitted).
706 * @see #getModel()
708 public void setModel(BoundedRangeModel model)
710 if (model != this.model)
712 this.model.removeChangeListener(changeListener);
713 this.model = model;
714 this.model.addChangeListener(changeListener);
715 fireStateChanged();
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>.
724 * @return The minimum value.
726 * @see #setMinimum(int)
728 public int getMinimum()
730 return model.getMinimum();
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.
741 * @param minimum the minimum value.
743 * @see #getMinimum()
745 public void setMinimum(int minimum)
747 model.setMinimum(minimum);
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>.
755 * @return The maximum value.
757 * @see #setMaximum(int)
759 public int getMaximum()
761 return model.getMaximum();
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.
772 * @param maximum the maximum value.
774 * @see #getMaximum()
776 public void setMaximum(int maximum)
778 model.setMaximum(maximum);
782 * Returns an implementation-dependent string describing the attributes of
783 * this <code>JProgressBar</code>.
785 * @return A string describing the attributes of this
786 * <code>JProgressBar</code> (never <code>null</code>).
788 protected String paramString()
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();
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.
818 * @param flag the new flag value.
820 * @see #isIndeterminate()
821 * @since 1.4
823 public void setIndeterminate(boolean flag)
825 if (indeterminate != flag)
827 indeterminate = flag;
828 firePropertyChange("indeterminate", !flag, indeterminate);
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).
837 * @return A flag indicating the mode for the <code>JProgressBar</code>.
839 * @see #setIndeterminate(boolean)
840 * @since 1.4
842 public boolean isIndeterminate()
844 return indeterminate;
848 * Returns the object that provides accessibility features for this
849 * <code>JProgressBar</code> component.
851 * @return The accessible context (an instance of
852 * {@link AccessibleJProgressBar}).
854 public AccessibleContext getAccessibleContext()
856 if (accessibleContext == null)
857 accessibleContext = new AccessibleJProgressBar();
859 return accessibleContext;