0001 /*
0002 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 package javax.swing;
0027
0028 import java.awt.Color;
0029 import java.awt.Graphics;
0030
0031 import java.text.Format;
0032 import java.text.NumberFormat;
0033
0034 import java.io.Serializable;
0035 import java.io.ObjectOutputStream;
0036 import java.io.ObjectInputStream;
0037 import java.io.IOException;
0038
0039 import javax.swing.event.*;
0040 import javax.accessibility.*;
0041 import javax.swing.plaf.ProgressBarUI;
0042
0043 /**
0044 * A component that visually displays the progress of some task. As the task
0045 * progresses towards completion, the progress bar displays the
0046 * task's percentage of completion.
0047 * This percentage is typically represented visually by a rectangle which
0048 * starts out empty and gradually becomes filled in as the task progresses.
0049 * In addition, the progress bar can display a textual representation of this
0050 * percentage.
0051 * <p>
0052 * {@code JProgressBar} uses a {@code BoundedRangeModel} as its data model,
0053 * with the {@code value} property representing the "current" state of the task,
0054 * and the {@code minimum} and {@code maximum} properties representing the
0055 * beginning and end points, respectively.
0056 * <p>
0057 * To indicate that a task of unknown length is executing,
0058 * you can put a progress bar into indeterminate mode.
0059 * While the bar is in indeterminate mode,
0060 * it animates constantly to show that work is occurring.
0061 * As soon as you can determine the task's length and amount of progress,
0062 * you should update the progress bar's value
0063 * and switch it back to determinate mode.
0064 *
0065 * <p>
0066 *
0067 * Here is an example of creating a progress bar,
0068 * where <code>task</code> is an object (representing some piece of work)
0069 * which returns information about the progress of the task:
0070 *
0071 *<pre>
0072 *progressBar = new JProgressBar(0, task.getLengthOfTask());
0073 *progressBar.setValue(0);
0074 *progressBar.setStringPainted(true);
0075 *</pre>
0076 *
0077 * Here is an example of querying the current state of the task, and using
0078 * the returned value to update the progress bar:
0079 *
0080 *<pre>
0081 *progressBar.setValue(task.getCurrent());
0082 *</pre>
0083 *
0084 * Here is an example of putting a progress bar into
0085 * indeterminate mode,
0086 * and then switching back to determinate mode
0087 * once the length of the task is known:
0088 *
0089 *<pre>
0090 *progressBar = new JProgressBar();
0091 *<em>...//when the task of (initially) unknown length begins:</em>
0092 *progressBar.setIndeterminate(true);
0093 *<em>...//do some work; get length of task...</em>
0094 *progressBar.setMaximum(newLength);
0095 *progressBar.setValue(newValue);
0096 *progressBar.setIndeterminate(false);
0097 *</pre>
0098 *
0099 * <p>
0100 *
0101 * For complete examples and further documentation see
0102 * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html" target="_top">How to Monitor Progress</a>,
0103 * a section in <em>The Java Tutorial.</em>
0104 *
0105 * <p>
0106 * <strong>Warning:</strong> Swing is not thread safe. For more
0107 * information see <a
0108 * href="package-summary.html#threading">Swing's Threading
0109 * Policy</a>.
0110 * <p>
0111 * <strong>Warning:</strong>
0112 * Serialized objects of this class will not be compatible with
0113 * future Swing releases. The current serialization support is
0114 * appropriate for short term storage or RMI between applications running
0115 * the same version of Swing. As of 1.4, support for long term storage
0116 * of all JavaBeans<sup><font size="-2">TM</font></sup>
0117 * has been added to the <code>java.beans</code> package.
0118 * Please see {@link java.beans.XMLEncoder}.
0119 *
0120 * @see javax.swing.plaf.basic.BasicProgressBarUI
0121 * @see javax.swing.BoundedRangeModel
0122 * @see javax.swing.SwingWorker
0123 *
0124 * @beaninfo
0125 * attribute: isContainer false
0126 * description: A component that displays an integer value.
0127 *
0128 * @version 1.102 05/05/07
0129 * @author Michael C. Albers
0130 * @author Kathy Walrath
0131 */
0132 public class JProgressBar extends JComponent implements SwingConstants,
0133 Accessible {
0134 /**
0135 * @see #getUIClassID
0136 */
0137 private static final String uiClassID = "ProgressBarUI";
0138
0139 /**
0140 * Whether the progress bar is horizontal or vertical.
0141 * The default is <code>HORIZONTAL</code>.
0142 *
0143 * @see #setOrientation
0144 */
0145 protected int orientation;
0146
0147 /**
0148 * Whether to display a border around the progress bar.
0149 * The default is <code>true</code>.
0150 *
0151 * @see #setBorderPainted
0152 */
0153 protected boolean paintBorder;
0154
0155 /**
0156 * The object that holds the data for the progress bar.
0157 *
0158 * @see #setModel
0159 */
0160 protected BoundedRangeModel model;
0161
0162 /**
0163 * An optional string that can be displayed on the progress bar.
0164 * The default is <code>null</code>. Setting this to a non-<code>null</code>
0165 * value does not imply that the string will be displayed.
0166 * To display the string, {@code paintString} must be {@code true}.
0167 *
0168 * @see #setString
0169 * @see #setStringPainted
0170 */
0171 protected String progressString;
0172
0173 /**
0174 * Whether to display a string of text on the progress bar.
0175 * The default is <code>false</code>.
0176 * Setting this to <code>true</code> causes a textual
0177 * display of the progress to be rendered on the progress bar. If
0178 * the <code>progressString</code> is <code>null</code>,
0179 * the percentage of completion is displayed on the progress bar.
0180 * Otherwise, the <code>progressString</code> is
0181 * rendered on the progress bar.
0182 *
0183 * @see #setStringPainted
0184 * @see #setString
0185 */
0186 protected boolean paintString;
0187
0188 /**
0189 * The default minimum for a progress bar is 0.
0190 */
0191 static final private int defaultMinimum = 0;
0192 /**
0193 * The default maximum for a progress bar is 100.
0194 */
0195 static final private int defaultMaximum = 100;
0196 /**
0197 * The default orientation for a progress bar is <code>HORIZONTAL</code>.
0198 */
0199 static final private int defaultOrientation = HORIZONTAL;
0200
0201 /**
0202 * Only one <code>ChangeEvent</code> is needed per instance since the
0203 * event's only interesting property is the immutable source, which
0204 * is the progress bar.
0205 * The event is lazily created the first time that an
0206 * event notification is fired.
0207 *
0208 * @see #fireStateChanged
0209 */
0210 protected transient ChangeEvent changeEvent = null;
0211
0212 /**
0213 * Listens for change events sent by the progress bar's model,
0214 * redispatching them
0215 * to change-event listeners registered upon
0216 * this progress bar.
0217 *
0218 * @see #createChangeListener
0219 */
0220 protected ChangeListener changeListener = null;
0221
0222 /**
0223 * Format used when displaying percent complete.
0224 */
0225 private transient Format format;
0226
0227 /**
0228 * Whether the progress bar is indeterminate (<code>true</code>) or
0229 * normal (<code>false</code>); the default is <code>false</code>.
0230 *
0231 * @see #setIndeterminate
0232 * @since 1.4
0233 */
0234 private boolean indeterminate;
0235
0236 /**
0237 * Creates a horizontal progress bar
0238 * that displays a border but no progress string.
0239 * The initial and minimum values are 0,
0240 * and the maximum is 100.
0241 *
0242 * @see #setOrientation
0243 * @see #setBorderPainted
0244 * @see #setStringPainted
0245 * @see #setString
0246 * @see #setIndeterminate
0247 */
0248 public JProgressBar() {
0249 this (defaultOrientation);
0250 }
0251
0252 /**
0253 * Creates a progress bar with the specified orientation,
0254 * which can be
0255 * either {@code SwingConstants.VERTICAL} or
0256 * {@code SwingConstants.HORIZONTAL}.
0257 * By default, a border is painted but a progress string is not.
0258 * The initial and minimum values are 0,
0259 * and the maximum is 100.
0260 *
0261 * @param orient the desired orientation of the progress bar
0262 * @throws IllegalArgumentException if {@code orient} is an illegal value
0263 *
0264 * @see #setOrientation
0265 * @see #setBorderPainted
0266 * @see #setStringPainted
0267 * @see #setString
0268 * @see #setIndeterminate
0269 */
0270 public JProgressBar(int orient) {
0271 this (orient, defaultMinimum, defaultMaximum);
0272 }
0273
0274 /**
0275 * Creates a horizontal progress bar
0276 * with the specified minimum and maximum.
0277 * Sets the initial value of the progress bar to the specified minimum.
0278 * By default, a border is painted but a progress string is not.
0279 * <p>
0280 * The <code>BoundedRangeModel</code> that holds the progress bar's data
0281 * handles any issues that may arise from improperly setting the
0282 * minimum, initial, and maximum values on the progress bar.
0283 * See the {@code BoundedRangeModel} documentation for details.
0284 *
0285 * @param min the minimum value of the progress bar
0286 * @param max the maximum value of the progress bar
0287 *
0288 * @see BoundedRangeModel
0289 * @see #setOrientation
0290 * @see #setBorderPainted
0291 * @see #setStringPainted
0292 * @see #setString
0293 * @see #setIndeterminate
0294 */
0295 public JProgressBar(int min, int max) {
0296 this (defaultOrientation, min, max);
0297 }
0298
0299 /**
0300 * Creates a progress bar using the specified orientation,
0301 * minimum, and maximum.
0302 * By default, a border is painted but a progress string is not.
0303 * Sets the initial value of the progress bar to the specified minimum.
0304 * <p>
0305 * The <code>BoundedRangeModel</code> that holds the progress bar's data
0306 * handles any issues that may arise from improperly setting the
0307 * minimum, initial, and maximum values on the progress bar.
0308 * See the {@code BoundedRangeModel} documentation for details.
0309 *
0310 * @param orient the desired orientation of the progress bar
0311 * @param min the minimum value of the progress bar
0312 * @param max the maximum value of the progress bar
0313 * @throws IllegalArgumentException if {@code orient} is an illegal value
0314 *
0315 * @see BoundedRangeModel
0316 * @see #setOrientation
0317 * @see #setBorderPainted
0318 * @see #setStringPainted
0319 * @see #setString
0320 * @see #setIndeterminate
0321 */
0322 public JProgressBar(int orient, int min, int max) {
0323 // Creating the model this way is a bit simplistic, but
0324 // I believe that it is the the most common usage of this
0325 // component - it's what people will expect.
0326 setModel(new DefaultBoundedRangeModel(min, 0, min, max));
0327 updateUI();
0328
0329 setOrientation(orient); // documented with set/getOrientation()
0330 setBorderPainted(true); // documented with is/setBorderPainted()
0331 setStringPainted(false); // see setStringPainted
0332 setString(null); // see getString
0333 setIndeterminate(false); // see setIndeterminate
0334 }
0335
0336 /**
0337 * Creates a horizontal progress bar
0338 * that uses the specified model
0339 * to hold the progress bar's data.
0340 * By default, a border is painted but a progress string is not.
0341 *
0342 * @param newModel the data model for the progress bar
0343 *
0344 * @see #setOrientation
0345 * @see #setBorderPainted
0346 * @see #setStringPainted
0347 * @see #setString
0348 * @see #setIndeterminate
0349 */
0350 public JProgressBar(BoundedRangeModel newModel) {
0351 setModel(newModel);
0352 updateUI();
0353
0354 setOrientation(defaultOrientation); // see setOrientation()
0355 setBorderPainted(true); // see setBorderPainted()
0356 setStringPainted(false); // see setStringPainted
0357 setString(null); // see getString
0358 setIndeterminate(false); // see setIndeterminate
0359 }
0360
0361 /**
0362 * Returns {@code SwingConstants.VERTICAL} or
0363 * {@code SwingConstants.HORIZONTAL}, depending on the orientation
0364 * of the progress bar. The default orientation is
0365 * {@code SwingConstants.HORIZONTAL}.
0366 *
0367 * @return <code>HORIZONTAL</code> or <code>VERTICAL</code>
0368 * @see #setOrientation
0369 */
0370 public int getOrientation() {
0371 return orientation;
0372 }
0373
0374 /**
0375 * Sets the progress bar's orientation to <code>newOrientation</code>,
0376 * which must be {@code SwingConstants.VERTICAL} or
0377 * {@code SwingConstants.HORIZONTAL}. The default orientation
0378 * is {@code SwingConstants.HORIZONTAL}.
0379 *
0380 * @param newOrientation <code>HORIZONTAL</code> or <code>VERTICAL</code>
0381 * @exception IllegalArgumentException if <code>newOrientation</code>
0382 * is an illegal value
0383 * @see #getOrientation
0384 *
0385 * @beaninfo
0386 * preferred: true
0387 * bound: true
0388 * attribute: visualUpdate true
0389 * description: Set the progress bar's orientation.
0390 */
0391 public void setOrientation(int newOrientation) {
0392 if (orientation != newOrientation) {
0393 switch (newOrientation) {
0394 case VERTICAL:
0395 case HORIZONTAL:
0396 int oldOrientation = orientation;
0397 orientation = newOrientation;
0398 firePropertyChange("orientation", oldOrientation,
0399 newOrientation);
0400 if (accessibleContext != null) {
0401 accessibleContext
0402 .firePropertyChange(
0403 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
0404 ((oldOrientation == VERTICAL) ? AccessibleState.VERTICAL
0405 : AccessibleState.HORIZONTAL),
0406 ((orientation == VERTICAL) ? AccessibleState.VERTICAL
0407 : AccessibleState.HORIZONTAL));
0408 }
0409 break;
0410 default:
0411 throw new IllegalArgumentException(newOrientation
0412 + " is not a legal orientation");
0413 }
0414 revalidate();
0415 }
0416 }
0417
0418 /**
0419 * Returns the value of the <code>stringPainted</code> property.
0420 *
0421 * @return the value of the <code>stringPainted</code> property
0422 * @see #setStringPainted
0423 * @see #setString
0424 */
0425 public boolean isStringPainted() {
0426 return paintString;
0427 }
0428
0429 /**
0430 * Sets the value of the <code>stringPainted</code> property,
0431 * which determines whether the progress bar
0432 * should render a progress string.
0433 * The default is <code>false</code>, meaning
0434 * no string is painted.
0435 * Some look and feels might not support progress strings
0436 * or might support them only when the progress bar is in determinate mode.
0437 *
0438 * @param b <code>true</code> if the progress bar should render a string
0439 * @see #isStringPainted
0440 * @see #setString
0441 * @beaninfo
0442 * bound: true
0443 * attribute: visualUpdate true
0444 * description: Whether the progress bar should render a string.
0445 */
0446 public void setStringPainted(boolean b) {
0447 //PENDING: specify that string not painted when in indeterminate mode?
0448 // or just leave that to the L&F?
0449 boolean oldValue = paintString;
0450 paintString = b;
0451 firePropertyChange("stringPainted", oldValue, paintString);
0452 if (paintString != oldValue) {
0453 revalidate();
0454 repaint();
0455 }
0456 }
0457
0458 /**
0459 * Returns a {@code String} representation of the current progress.
0460 * By default, this returns a simple percentage {@code String} based on
0461 * the value returned from {@code getPercentComplete}. An example
0462 * would be the "42%". You can change this by calling {@code setString}.
0463 *
0464 * @return the value of the progress string, or a simple percentage string
0465 * if the progress string is {@code null}
0466 * @see #setString
0467 */
0468 public String getString() {
0469 if (progressString != null) {
0470 return progressString;
0471 } else {
0472 if (format == null) {
0473 format = NumberFormat.getPercentInstance();
0474 }
0475 return format.format(new Double(getPercentComplete()));
0476 }
0477 }
0478
0479 /**
0480 * Sets the value of the progress string. By default,
0481 * this string is <code>null</code>, implying the built-in behavior of
0482 * using a simple percent string.
0483 * If you have provided a custom progress string and want to revert to
0484 * the built-in behavior, set the string back to <code>null</code>.
0485 * <p>
0486 * The progress string is painted only if
0487 * the <code>isStringPainted</code> method returns <code>true</code>.
0488 *
0489 * @param s the value of the progress string
0490 * @see #getString
0491 * @see #setStringPainted
0492 * @see #isStringPainted
0493 * @beaninfo
0494 * bound: true
0495 * attribute: visualUpdate true
0496 * description: Specifies the progress string to paint
0497 */
0498 public void setString(String s) {
0499 String oldValue = progressString;
0500 progressString = s;
0501 firePropertyChange("string", oldValue, progressString);
0502 if (progressString == null || oldValue == null
0503 || !progressString.equals(oldValue)) {
0504 repaint();
0505 }
0506 }
0507
0508 /**
0509 * Returns the percent complete for the progress bar.
0510 * Note that this number is between 0.0 and 1.0.
0511 *
0512 * @return the percent complete for this progress bar
0513 */
0514 public double getPercentComplete() {
0515 long span = model.getMaximum() - model.getMinimum();
0516 double currentValue = model.getValue();
0517 double pc = (currentValue - model.getMinimum()) / span;
0518 return pc;
0519 }
0520
0521 /**
0522 * Returns the <code>borderPainted</code> property.
0523 *
0524 * @return the value of the <code>borderPainted</code> property
0525 * @see #setBorderPainted
0526 * @beaninfo
0527 * description: Does the progress bar paint its border
0528 */
0529 public boolean isBorderPainted() {
0530 return paintBorder;
0531 }
0532
0533 /**
0534 * Sets the <code>borderPainted</code> property, which is
0535 * <code>true</code> if the progress bar should paint its border.
0536 * The default value for this property is <code>true</code>.
0537 * Some look and feels might not implement painted borders;
0538 * they will ignore this property.
0539 *
0540 * @param b <code>true</code> if the progress bar
0541 * should paint its border;
0542 * otherwise, <code>false</code>
0543 * @see #isBorderPainted
0544 * @beaninfo
0545 * bound: true
0546 * attribute: visualUpdate true
0547 * description: Whether the progress bar should paint its border.
0548 */
0549 public void setBorderPainted(boolean b) {
0550 boolean oldValue = paintBorder;
0551 paintBorder = b;
0552 firePropertyChange("borderPainted", oldValue, paintBorder);
0553 if (paintBorder != oldValue) {
0554 repaint();
0555 }
0556 }
0557
0558 /**
0559 * Paints the progress bar's border if the <code>borderPainted</code>
0560 * property is <code>true</code>.
0561 *
0562 * @param g the <code>Graphics</code> context within which to paint the border
0563 * @see #paint
0564 * @see #setBorder
0565 * @see #isBorderPainted
0566 * @see #setBorderPainted
0567 */
0568 protected void paintBorder(Graphics g) {
0569 if (isBorderPainted()) {
0570 super .paintBorder(g);
0571 }
0572 }
0573
0574 /**
0575 * Returns the look-and-feel object that renders this component.
0576 *
0577 * @return the <code>ProgressBarUI</code> object that renders this component
0578 */
0579 public ProgressBarUI getUI() {
0580 return (ProgressBarUI) ui;
0581 }
0582
0583 /**
0584 * Sets the look-and-feel object that renders this component.
0585 *
0586 * @param ui a <code>ProgressBarUI</code> object
0587 * @see UIDefaults#getUI
0588 * @beaninfo
0589 * bound: true
0590 * hidden: true
0591 * attribute: visualUpdate true
0592 * description: The UI object that implements the Component's LookAndFeel.
0593 */
0594 public void setUI(ProgressBarUI ui) {
0595 super .setUI(ui);
0596 }
0597
0598 /**
0599 * Resets the UI property to a value from the current look and feel.
0600 *
0601 * @see JComponent#updateUI
0602 */
0603 public void updateUI() {
0604 setUI((ProgressBarUI) UIManager.getUI(this ));
0605 }
0606
0607 /**
0608 * Returns the name of the look-and-feel class that renders this component.
0609 *
0610 * @return the string "ProgressBarUI"
0611 * @see JComponent#getUIClassID
0612 * @see UIDefaults#getUI
0613 * @beaninfo
0614 * expert: true
0615 * description: A string that specifies the name of the look-and-feel class.
0616 */
0617 public String getUIClassID() {
0618 return uiClassID;
0619 }
0620
0621 /* We pass each Change event to the listeners with the
0622 * the progress bar as the event source.
0623 * <p>
0624 * <strong>Warning:</strong>
0625 * Serialized objects of this class will not be compatible with
0626 * future Swing releases. The current serialization support is
0627 * appropriate for short term storage or RMI between applications running
0628 * the same version of Swing. As of 1.4, support for long term storage
0629 * of all JavaBeans<sup><font size="-2">TM</font></sup>
0630 * has been added to the <code>java.beans</code> package.
0631 * Please see {@link java.beans.XMLEncoder}.
0632 */
0633 private class ModelListener implements ChangeListener, Serializable {
0634 public void stateChanged(ChangeEvent e) {
0635 fireStateChanged();
0636 }
0637 }
0638
0639 /**
0640 * Subclasses that want to handle change events
0641 * from the model differently
0642 * can override this to return
0643 * an instance of a custom <code>ChangeListener</code> implementation.
0644 * The default {@code ChangeListener} simply calls the
0645 * {@code fireStateChanged} method to forward {@code ChangeEvent}s
0646 * to the {@code ChangeListener}s that have been added directly to the
0647 * progress bar.
0648 *
0649 * @see #changeListener
0650 * @see #fireStateChanged
0651 * @see javax.swing.event.ChangeListener
0652 * @see javax.swing.BoundedRangeModel
0653 */
0654 protected ChangeListener createChangeListener() {
0655 return new ModelListener();
0656 }
0657
0658 /**
0659 * Adds the specified <code>ChangeListener</code> to the progress bar.
0660 *
0661 * @param l the <code>ChangeListener</code> to add
0662 */
0663 public void addChangeListener(ChangeListener l) {
0664 listenerList.add(ChangeListener.class, l);
0665 }
0666
0667 /**
0668 * Removes a <code>ChangeListener</code> from the progress bar.
0669 *
0670 * @param l the <code>ChangeListener</code> to remove
0671 */
0672 public void removeChangeListener(ChangeListener l) {
0673 listenerList.remove(ChangeListener.class, l);
0674 }
0675
0676 /**
0677 * Returns an array of all the <code>ChangeListener</code>s added
0678 * to this progress bar with <code>addChangeListener</code>.
0679 *
0680 * @return all of the <code>ChangeListener</code>s added or an empty
0681 * array if no listeners have been added
0682 * @since 1.4
0683 */
0684 public ChangeListener[] getChangeListeners() {
0685 return (ChangeListener[]) listenerList
0686 .getListeners(ChangeListener.class);
0687 }
0688
0689 /**
0690 * Send a {@code ChangeEvent}, whose source is this {@code JProgressBar}, to
0691 * all {@code ChangeListener}s that have registered interest in
0692 * {@code ChangeEvent}s.
0693 * This method is called each time a {@code ChangeEvent} is received from
0694 * the model.
0695 * <p>
0696 *
0697 * The event instance is created if necessary, and stored in
0698 * {@code changeEvent}.
0699 *
0700 * @see #addChangeListener
0701 * @see EventListenerList
0702 */
0703 protected void fireStateChanged() {
0704 // Guaranteed to return a non-null array
0705 Object[] listeners = listenerList.getListenerList();
0706 // Process the listeners last to first, notifying
0707 // those that are interested in this event
0708 for (int i = listeners.length - 2; i >= 0; i -= 2) {
0709 if (listeners[i] == ChangeListener.class) {
0710 // Lazily create the event:
0711 if (changeEvent == null)
0712 changeEvent = new ChangeEvent(this );
0713 ((ChangeListener) listeners[i + 1])
0714 .stateChanged(changeEvent);
0715 }
0716 }
0717 }
0718
0719 /**
0720 * Returns the data model used by this progress bar.
0721 *
0722 * @return the <code>BoundedRangeModel</code> currently in use
0723 * @see #setModel
0724 * @see BoundedRangeModel
0725 */
0726 public BoundedRangeModel getModel() {
0727 return model;
0728 }
0729
0730 /**
0731 * Sets the data model used by the <code>JProgressBar</code>.
0732 * Note that the {@code BoundedRangeModel}'s {@code extent} is not used,
0733 * and is set to {@code 0}.
0734 *
0735 * @param newModel the <code>BoundedRangeModel</code> to use
0736 *
0737 * @beaninfo
0738 * expert: true
0739 * description: The data model used by the JProgressBar.
0740 */
0741 public void setModel(BoundedRangeModel newModel) {
0742 // PENDING(???) setting the same model to multiple bars is broken; listeners
0743 BoundedRangeModel oldModel = getModel();
0744
0745 if (newModel != oldModel) {
0746 if (oldModel != null) {
0747 oldModel.removeChangeListener(changeListener);
0748 changeListener = null;
0749 }
0750
0751 model = newModel;
0752
0753 if (newModel != null) {
0754 changeListener = createChangeListener();
0755 newModel.addChangeListener(changeListener);
0756 }
0757
0758 if (accessibleContext != null) {
0759 accessibleContext.firePropertyChange(
0760 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
0761 (oldModel == null ? null : new Integer(oldModel
0762 .getValue())), (newModel == null ? null
0763 : new Integer(newModel.getValue())));
0764 }
0765
0766 if (model != null) {
0767 model.setExtent(0);
0768 }
0769 repaint();
0770 }
0771 }
0772
0773 /* All of the model methods are implemented by delegation. */
0774
0775 /**
0776 * Returns the progress bar's current {@code value}
0777 * from the <code>BoundedRangeModel</code>.
0778 * The value is always between the
0779 * minimum and maximum values, inclusive.
0780 *
0781 * @return the current value of the progress bar
0782 * @see #setValue
0783 * @see BoundedRangeModel#getValue
0784 */
0785 public int getValue() {
0786 return getModel().getValue();
0787 }
0788
0789 /**
0790 * Returns the progress bar's {@code minimum} value
0791 * from the <code>BoundedRangeModel</code>.
0792 *
0793 * @return the progress bar's minimum value
0794 * @see #setMinimum
0795 * @see BoundedRangeModel#getMinimum
0796 */
0797 public int getMinimum() {
0798 return getModel().getMinimum();
0799 }
0800
0801 /**
0802 * Returns the progress bar's {@code maximum} value
0803 * from the <code>BoundedRangeModel</code>.
0804 *
0805 * @return the progress bar's maximum value
0806 * @see #setMaximum
0807 * @see BoundedRangeModel#getMaximum
0808 */
0809 public int getMaximum() {
0810 return getModel().getMaximum();
0811 }
0812
0813 /**
0814 * Sets the progress bar's current value to {@code n}. This method
0815 * forwards the new value to the model.
0816 * <p>
0817 * The data model (an instance of {@code BoundedRangeModel})
0818 * handles any mathematical
0819 * issues arising from assigning faulty values. See the
0820 * {@code BoundedRangeModel} documentation for details.
0821 * <p>
0822 * If the new value is different from the previous value,
0823 * all change listeners are notified.
0824 *
0825 * @param n the new value
0826 * @see #getValue
0827 * @see #addChangeListener
0828 * @see BoundedRangeModel#setValue
0829 * @beaninfo
0830 * preferred: true
0831 * description: The progress bar's current value.
0832 */
0833 public void setValue(int n) {
0834 BoundedRangeModel brm = getModel();
0835 int oldValue = brm.getValue();
0836 brm.setValue(n);
0837
0838 if (accessibleContext != null) {
0839 accessibleContext.firePropertyChange(
0840 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
0841 new Integer(oldValue), new Integer(brm.getValue()));
0842 }
0843 }
0844
0845 /**
0846 * Sets the progress bar's minimum value
0847 * (stored in the progress bar's data model) to <code>n</code>.
0848 * <p>
0849 * The data model (a <code>BoundedRangeModel</code> instance)
0850 * handles any mathematical
0851 * issues arising from assigning faulty values.
0852 * See the {@code BoundedRangeModel} documentation for details.
0853 * <p>
0854 * If the minimum value is different from the previous minimum,
0855 * all change listeners are notified.
0856 *
0857 * @param n the new minimum
0858 * @see #getMinimum
0859 * @see #addChangeListener
0860 * @see BoundedRangeModel#setMinimum
0861 * @beaninfo
0862 * preferred: true
0863 * description: The progress bar's minimum value.
0864 */
0865 public void setMinimum(int n) {
0866 getModel().setMinimum(n);
0867 }
0868
0869 /**
0870 * Sets the progress bar's maximum value
0871 * (stored in the progress bar's data model) to <code>n</code>.
0872 * <p>
0873 * The underlying <code>BoundedRangeModel</code> handles any mathematical
0874 * issues arising from assigning faulty values.
0875 * See the {@code BoundedRangeModel} documentation for details.
0876 * <p>
0877 * If the maximum value is different from the previous maximum,
0878 * all change listeners are notified.
0879 *
0880 * @param n the new maximum
0881 * @see #getMaximum
0882 * @see #addChangeListener
0883 * @see BoundedRangeModel#setMaximum
0884 * @beaninfo
0885 * preferred: true
0886 * description: The progress bar's maximum value.
0887 */
0888 public void setMaximum(int n) {
0889 getModel().setMaximum(n);
0890 }
0891
0892 /**
0893 * Sets the <code>indeterminate</code> property of the progress bar,
0894 * which determines whether the progress bar is in determinate
0895 * or indeterminate mode.
0896 * An indeterminate progress bar continuously displays animation
0897 * indicating that an operation of unknown length is occurring.
0898 * By default, this property is <code>false</code>.
0899 * Some look and feels might not support indeterminate progress bars;
0900 * they will ignore this property.
0901 *
0902 * <p>
0903 *
0904 * See
0905 * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html" target="_top">How to Monitor Progress</a>
0906 * for examples of using indeterminate progress bars.
0907 *
0908 * @param newValue <code>true</code> if the progress bar
0909 * should change to indeterminate mode;
0910 * <code>false</code> if it should revert to normal.
0911 *
0912 * @see #isIndeterminate
0913 * @see javax.swing.plaf.basic.BasicProgressBarUI
0914 *
0915 * @since 1.4
0916 *
0917 * @beaninfo
0918 * bound: true
0919 * attribute: visualUpdate true
0920 * description: Set whether the progress bar is indeterminate (true)
0921 * or normal (false).
0922 */
0923 public void setIndeterminate(boolean newValue) {
0924 boolean oldValue = indeterminate;
0925 indeterminate = newValue;
0926 firePropertyChange("indeterminate", oldValue, indeterminate);
0927 }
0928
0929 /**
0930 * Returns the value of the <code>indeterminate</code> property.
0931 *
0932 * @return the value of the <code>indeterminate</code> property
0933 * @see #setIndeterminate
0934 *
0935 * @since 1.4
0936 *
0937 * @beaninfo
0938 * description: Is the progress bar indeterminate (true)
0939 * or normal (false)?
0940 */
0941 public boolean isIndeterminate() {
0942 return indeterminate;
0943 }
0944
0945 /**
0946 * See readObject() and writeObject() in JComponent for more
0947 * information about serialization in Swing.
0948 */
0949 private void writeObject(ObjectOutputStream s) throws IOException {
0950 s.defaultWriteObject();
0951 if (getUIClassID().equals(uiClassID)) {
0952 byte count = JComponent.getWriteObjCounter(this );
0953 JComponent.setWriteObjCounter(this , --count);
0954 if (count == 0 && ui != null) {
0955 ui.installUI(this );
0956 }
0957 }
0958 }
0959
0960 /**
0961 * Returns a string representation of this <code>JProgressBar</code>.
0962 * This method is intended to be used only for debugging purposes. The
0963 * content and format of the returned string may vary between
0964 * implementations. The returned string may be empty but may not
0965 * be <code>null</code>.
0966 *
0967 * @return a string representation of this <code>JProgressBar</code>
0968 */
0969 protected String paramString() {
0970 String orientationString = (orientation == HORIZONTAL ? "HORIZONTAL"
0971 : "VERTICAL");
0972 String paintBorderString = (paintBorder ? "true" : "false");
0973 String progressStringString = (progressString != null ? progressString
0974 : "");
0975 String paintStringString = (paintString ? "true" : "false");
0976 String indeterminateString = (indeterminate ? "true" : "false");
0977
0978 return super .paramString() + ",orientation="
0979 + orientationString + ",paintBorder="
0980 + paintBorderString + ",paintString="
0981 + paintStringString + ",progressString="
0982 + progressStringString + ",indeterminateString="
0983 + indeterminateString;
0984 }
0985
0986 /////////////////
0987 // Accessibility support
0988 ////////////////
0989
0990 /**
0991 * Gets the <code>AccessibleContext</code> associated with this
0992 * <code>JProgressBar</code>. For progress bars, the
0993 * <code>AccessibleContext</code> takes the form of an
0994 * <code>AccessibleJProgressBar</code>.
0995 * A new <code>AccessibleJProgressBar</code> instance is created if necessary.
0996 *
0997 * @return an <code>AccessibleJProgressBar</code> that serves as the
0998 * <code>AccessibleContext</code> of this <code>JProgressBar</code>
0999 * @beaninfo
1000 * expert: true
1001 * description: The AccessibleContext associated with this ProgressBar.
1002 */
1003 public AccessibleContext getAccessibleContext() {
1004 if (accessibleContext == null) {
1005 accessibleContext = new AccessibleJProgressBar();
1006 }
1007 return accessibleContext;
1008 }
1009
1010 /**
1011 * This class implements accessibility support for the
1012 * <code>JProgressBar</code> class. It provides an implementation of the
1013 * Java Accessibility API appropriate to progress bar user-interface
1014 * elements.
1015 * <p>
1016 * <strong>Warning:</strong>
1017 * Serialized objects of this class will not be compatible with
1018 * future Swing releases. The current serialization support is
1019 * appropriate for short term storage or RMI between applications running
1020 * the same version of Swing. As of 1.4, support for long term storage
1021 * of all JavaBeans<sup><font size="-2">TM</font></sup>
1022 * has been added to the <code>java.beans</code> package.
1023 * Please see {@link java.beans.XMLEncoder}.
1024 */
1025 protected class AccessibleJProgressBar extends AccessibleJComponent
1026 implements AccessibleValue {
1027
1028 /**
1029 * Gets the state set of this object.
1030 *
1031 * @return an instance of AccessibleState containing the current state
1032 * of the object
1033 * @see AccessibleState
1034 */
1035 public AccessibleStateSet getAccessibleStateSet() {
1036 AccessibleStateSet states = super .getAccessibleStateSet();
1037 if (getModel().getValueIsAdjusting()) {
1038 states.add(AccessibleState.BUSY);
1039 }
1040 if (getOrientation() == VERTICAL) {
1041 states.add(AccessibleState.VERTICAL);
1042 } else {
1043 states.add(AccessibleState.HORIZONTAL);
1044 }
1045 return states;
1046 }
1047
1048 /**
1049 * Gets the role of this object.
1050 *
1051 * @return an instance of AccessibleRole describing the role of the
1052 * object
1053 */
1054 public AccessibleRole getAccessibleRole() {
1055 return AccessibleRole.PROGRESS_BAR;
1056 }
1057
1058 /**
1059 * Gets the <code>AccessibleValue</code> associated with this object. In the
1060 * implementation of the Java Accessibility API for this class,
1061 * returns this object, which is responsible for implementing the
1062 * <code>AccessibleValue</code> interface on behalf of itself.
1063 *
1064 * @return this object
1065 */
1066 public AccessibleValue getAccessibleValue() {
1067 return this ;
1068 }
1069
1070 /**
1071 * Gets the accessible value of this object.
1072 *
1073 * @return the current value of this object
1074 */
1075 public Number getCurrentAccessibleValue() {
1076 return new Integer(getValue());
1077 }
1078
1079 /**
1080 * Sets the value of this object as a <code>Number</code>.
1081 *
1082 * @return <code>true</code> if the value was set
1083 */
1084 public boolean setCurrentAccessibleValue(Number n) {
1085 // TIGER- 4422535
1086 if (n == null) {
1087 return false;
1088 }
1089 setValue(n.intValue());
1090 return true;
1091 }
1092
1093 /**
1094 * Gets the minimum accessible value of this object.
1095 *
1096 * @return the minimum value of this object
1097 */
1098 public Number getMinimumAccessibleValue() {
1099 return new Integer(getMinimum());
1100 }
1101
1102 /**
1103 * Gets the maximum accessible value of this object.
1104 *
1105 * @return the maximum value of this object
1106 */
1107 public Number getMaximumAccessibleValue() {
1108 // TIGER - 4422362
1109 return new Integer(model.getMaximum() - model.getExtent());
1110 }
1111
1112 } // AccessibleJProgressBar
1113 }
|