1 /* 2 * Copyright (c) 1997, 2006, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.swing; 27 28 import java.awt.Color; 29 import java.awt.Graphics; 30 31 import java.text.Format; 32 import java.text.NumberFormat; 33 34 import java.io.Serializable; 35 import java.io.ObjectOutputStream; 36 import java.io.ObjectInputStream; 37 import java.io.IOException; 38 39 import javax.swing.event.*; 40 import javax.accessibility.*; 41 import 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 */ 132 public 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 }