1 /* 2 * Copyright (c) 1997, 2008, 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://docs.oracle.com/javase/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™ 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™ 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 listenerList.getListeners(ChangeListener.class); 703 } 704 705 /** 706 * Send a {@code ChangeEvent}, whose source is this {@code JProgressBar}, to 707 * all {@code ChangeListener}s that have registered interest in 708 * {@code ChangeEvent}s. 709 * This method is called each time a {@code ChangeEvent} is received from 710 * the model. 711 * <p> 712 * 713 * The event instance is created if necessary, and stored in 714 * {@code changeEvent}. 715 * 716 * @see #addChangeListener 717 * @see EventListenerList 718 */ 719 protected void fireStateChanged() { 720 // Guaranteed to return a non-null array 721 Object[] listeners = listenerList.getListenerList(); 722 // Process the listeners last to first, notifying 723 // those that are interested in this event 724 for (int i = listeners.length-2; i>=0; i-=2) { 725 if (listeners[i]==ChangeListener.class) { 726 // Lazily create the event: 727 if (changeEvent == null) 728 changeEvent = new ChangeEvent(this); 729 ((ChangeListener)listeners[i+1]).stateChanged(changeEvent); 730 } 731 } 732 } 733 734 /** 735 * Returns the data model used by this progress bar. 736 * 737 * @return the <code>BoundedRangeModel</code> currently in use 738 * @see #setModel 739 * @see BoundedRangeModel 740 */ 741 public BoundedRangeModel getModel() { 742 return model; 743 } 744 745 /** 746 * Sets the data model used by the <code>JProgressBar</code>. 747 * Note that the {@code BoundedRangeModel}'s {@code extent} is not used, 748 * and is set to {@code 0}. 749 * 750 * @param newModel the <code>BoundedRangeModel</code> to use 751 * 752 * @beaninfo 753 * expert: true 754 * description: The data model used by the JProgressBar. 755 */ 756 public void setModel(BoundedRangeModel newModel) { 757 // PENDING(???) setting the same model to multiple bars is broken; listeners 758 BoundedRangeModel oldModel = getModel(); 759 760 if (newModel != oldModel) { 761 if (oldModel != null) { 762 oldModel.removeChangeListener(changeListener); 763 changeListener = null; 764 } 765 766 model = newModel; 767 768 if (newModel != null) { 769 changeListener = createChangeListener(); 770 newModel.addChangeListener(changeListener); 771 } 772 773 if (accessibleContext != null) { 774 accessibleContext.firePropertyChange( 775 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, 776 (oldModel== null 777 ? null : Integer.valueOf(oldModel.getValue())), 778 (newModel== null 779 ? null : Integer.valueOf(newModel.getValue()))); 780 } 781 782 if (model != null) { 783 model.setExtent(0); 784 } 785 repaint(); 786 } 787 } 788 789 790 /* All of the model methods are implemented by delegation. */ 791 792 /** 793 * Returns the progress bar's current {@code value} 794 * from the <code>BoundedRangeModel</code>. 795 * The value is always between the 796 * minimum and maximum values, inclusive. 797 * 798 * @return the current value of the progress bar 799 * @see #setValue 800 * @see BoundedRangeModel#getValue 801 */ 802 public int getValue() { return getModel().getValue(); } 803 804 /** 805 * Returns the progress bar's {@code minimum} value 806 * from the <code>BoundedRangeModel</code>. 807 * 808 * @return the progress bar's minimum value 809 * @see #setMinimum 810 * @see BoundedRangeModel#getMinimum 811 */ 812 public int getMinimum() { return getModel().getMinimum(); } 813 814 /** 815 * Returns the progress bar's {@code maximum} value 816 * from the <code>BoundedRangeModel</code>. 817 * 818 * @return the progress bar's maximum value 819 * @see #setMaximum 820 * @see BoundedRangeModel#getMaximum 821 */ 822 public int getMaximum() { return getModel().getMaximum(); } 823 824 /** 825 * Sets the progress bar's current value to {@code n}. This method 826 * forwards the new value to the model. 827 * <p> 828 * The data model (an instance of {@code BoundedRangeModel}) 829 * handles any mathematical 830 * issues arising from assigning faulty values. See the 831 * {@code BoundedRangeModel} documentation for details. 832 * <p> 833 * If the new value is different from the previous value, 834 * all change listeners are notified. 835 * 836 * @param n the new value 837 * @see #getValue 838 * @see #addChangeListener 839 * @see BoundedRangeModel#setValue 840 * @beaninfo 841 * preferred: true 842 * description: The progress bar's current value. 843 */ 844 public void setValue(int n) { 845 BoundedRangeModel brm = getModel(); 846 int oldValue = brm.getValue(); 847 brm.setValue(n); 848 849 if (accessibleContext != null) { 850 accessibleContext.firePropertyChange( 851 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, 852 Integer.valueOf(oldValue), 853 Integer.valueOf(brm.getValue())); 854 } 855 } 856 857 /** 858 * Sets the progress bar's minimum value 859 * (stored in the progress bar's data model) to <code>n</code>. 860 * <p> 861 * The data model (a <code>BoundedRangeModel</code> instance) 862 * handles any mathematical 863 * issues arising from assigning faulty values. 864 * See the {@code BoundedRangeModel} documentation for details. 865 * <p> 866 * If the minimum value is different from the previous minimum, 867 * all change listeners are notified. 868 * 869 * @param n the new minimum 870 * @see #getMinimum 871 * @see #addChangeListener 872 * @see BoundedRangeModel#setMinimum 873 * @beaninfo 874 * preferred: true 875 * description: The progress bar's minimum value. 876 */ 877 public void setMinimum(int n) { getModel().setMinimum(n); } 878 879 /** 880 * Sets the progress bar's maximum value 881 * (stored in the progress bar's data model) to <code>n</code>. 882 * <p> 883 * The underlying <code>BoundedRangeModel</code> handles any mathematical 884 * issues arising from assigning faulty values. 885 * See the {@code BoundedRangeModel} documentation for details. 886 * <p> 887 * If the maximum value is different from the previous maximum, 888 * all change listeners are notified. 889 * 890 * @param n the new maximum 891 * @see #getMaximum 892 * @see #addChangeListener 893 * @see BoundedRangeModel#setMaximum 894 * @beaninfo 895 * preferred: true 896 * description: The progress bar's maximum value. 897 */ 898 public void setMaximum(int n) { getModel().setMaximum(n); } 899 900 /** 901 * Sets the <code>indeterminate</code> property of the progress bar, 902 * which determines whether the progress bar is in determinate 903 * or indeterminate mode. 904 * An indeterminate progress bar continuously displays animation 905 * indicating that an operation of unknown length is occurring. 906 * By default, this property is <code>false</code>. 907 * Some look and feels might not support indeterminate progress bars; 908 * they will ignore this property. 909 * 910 * <p> 911 * 912 * See 913 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html" target="_top">How to Monitor Progress</a> 914 * for examples of using indeterminate progress bars. 915 * 916 * @param newValue <code>true</code> if the progress bar 917 * should change to indeterminate mode; 918 * <code>false</code> if it should revert to normal. 919 * 920 * @see #isIndeterminate 921 * @see javax.swing.plaf.basic.BasicProgressBarUI 922 * 923 * @since 1.4 924 * 925 * @beaninfo 926 * bound: true 927 * attribute: visualUpdate true 928 * description: Set whether the progress bar is indeterminate (true) 929 * or normal (false). 930 */ 931 public void setIndeterminate(boolean newValue) { 932 boolean oldValue = indeterminate; 933 indeterminate = newValue; 934 firePropertyChange("indeterminate", oldValue, indeterminate); 935 } 936 937 /** 938 * Returns the value of the <code>indeterminate</code> property. 939 * 940 * @return the value of the <code>indeterminate</code> property 941 * @see #setIndeterminate 942 * 943 * @since 1.4 944 * 945 * @beaninfo 946 * description: Is the progress bar indeterminate (true) 947 * or normal (false)? 948 */ 949 public boolean isIndeterminate() { 950 return indeterminate; 951 } 952 953 954 /** 955 * See readObject() and writeObject() in JComponent for more 956 * information about serialization in Swing. 957 */ 958 private void writeObject(ObjectOutputStream s) throws IOException { 959 s.defaultWriteObject(); 960 if (getUIClassID().equals(uiClassID)) { 961 byte count = JComponent.getWriteObjCounter(this); 962 JComponent.setWriteObjCounter(this, --count); 963 if (count == 0 && ui != null) { 964 ui.installUI(this); 965 } 966 } 967 } 968 969 970 /** 971 * Returns a string representation of this <code>JProgressBar</code>. 972 * This method is intended to be used only for debugging purposes. The 973 * content and format of the returned string may vary between 974 * implementations. The returned string may be empty but may not 975 * be <code>null</code>. 976 * 977 * @return a string representation of this <code>JProgressBar</code> 978 */ 979 protected String paramString() { 980 String orientationString = (orientation == HORIZONTAL ? 981 "HORIZONTAL" : "VERTICAL"); 982 String paintBorderString = (paintBorder ? 983 "true" : "false"); 984 String progressStringString = (progressString != null ? 985 progressString : ""); 986 String paintStringString = (paintString ? 987 "true" : "false"); 988 String indeterminateString = (indeterminate ? 989 "true" : "false"); 990 991 return super.paramString() + 992 ",orientation=" + orientationString + 993 ",paintBorder=" + paintBorderString + 994 ",paintString=" + paintStringString + 995 ",progressString=" + progressStringString + 996 ",indeterminateString=" + indeterminateString; 997 } 998 999 ///////////////// 1000 // Accessibility support 1001 //////////////// 1002 1003 /** 1004 * Gets the <code>AccessibleContext</code> associated with this 1005 * <code>JProgressBar</code>. For progress bars, the 1006 * <code>AccessibleContext</code> takes the form of an 1007 * <code>AccessibleJProgressBar</code>. 1008 * A new <code>AccessibleJProgressBar</code> instance is created if necessary. 1009 * 1010 * @return an <code>AccessibleJProgressBar</code> that serves as the 1011 * <code>AccessibleContext</code> of this <code>JProgressBar</code> 1012 * @beaninfo 1013 * expert: true 1014 * description: The AccessibleContext associated with this ProgressBar. 1015 */ 1016 public AccessibleContext getAccessibleContext() { 1017 if (accessibleContext == null) { 1018 accessibleContext = new AccessibleJProgressBar(); 1019 } 1020 return accessibleContext; 1021 } 1022 1023 /** 1024 * This class implements accessibility support for the 1025 * <code>JProgressBar</code> class. It provides an implementation of the 1026 * Java Accessibility API appropriate to progress bar user-interface 1027 * elements. 1028 * <p> 1029 * <strong>Warning:</strong> 1030 * Serialized objects of this class will not be compatible with 1031 * future Swing releases. The current serialization support is 1032 * appropriate for short term storage or RMI between applications running 1033 * the same version of Swing. As of 1.4, support for long term storage 1034 * of all JavaBeans™ 1035 * has been added to the <code>java.beans</code> package. 1036 * Please see {@link java.beans.XMLEncoder}. 1037 */ 1038 protected class AccessibleJProgressBar extends AccessibleJComponent 1039 implements AccessibleValue { 1040 1041 /** 1042 * Gets the state set of this object. 1043 * 1044 * @return an instance of AccessibleState containing the current state 1045 * of the object 1046 * @see AccessibleState 1047 */ 1048 public AccessibleStateSet getAccessibleStateSet() { 1049 AccessibleStateSet states = super.getAccessibleStateSet(); 1050 if (getModel().getValueIsAdjusting()) { 1051 states.add(AccessibleState.BUSY); 1052 } 1053 if (getOrientation() == VERTICAL) { 1054 states.add(AccessibleState.VERTICAL); 1055 } else { 1056 states.add(AccessibleState.HORIZONTAL); 1057 } 1058 return states; 1059 } 1060 1061 /** 1062 * Gets the role of this object. 1063 * 1064 * @return an instance of AccessibleRole describing the role of the 1065 * object 1066 */ 1067 public AccessibleRole getAccessibleRole() { 1068 return AccessibleRole.PROGRESS_BAR; 1069 } 1070 1071 /** 1072 * Gets the <code>AccessibleValue</code> associated with this object. In the 1073 * implementation of the Java Accessibility API for this class, 1074 * returns this object, which is responsible for implementing the 1075 * <code>AccessibleValue</code> interface on behalf of itself. 1076 * 1077 * @return this object 1078 */ 1079 public AccessibleValue getAccessibleValue() { 1080 return this; 1081 } 1082 1083 /** 1084 * Gets the accessible value of this object. 1085 * 1086 * @return the current value of this object 1087 */ 1088 public Number getCurrentAccessibleValue() { 1089 return Integer.valueOf(getValue()); 1090 } 1091 1092 /** 1093 * Sets the value of this object as a <code>Number</code>. 1094 * 1095 * @return <code>true</code> if the value was set 1096 */ 1097 public boolean setCurrentAccessibleValue(Number n) { 1098 // TIGER- 4422535 1099 if (n == null) { 1100 return false; 1101 } 1102 setValue(n.intValue()); 1103 return true; 1104 } 1105 1106 /** 1107 * Gets the minimum accessible value of this object. 1108 * 1109 * @return the minimum value of this object 1110 */ 1111 public Number getMinimumAccessibleValue() { 1112 return Integer.valueOf(getMinimum()); 1113 } 1114 1115 /** 1116 * Gets the maximum accessible value of this object. 1117 * 1118 * @return the maximum value of this object 1119 */ 1120 public Number getMaximumAccessibleValue() { 1121 // TIGER - 4422362 1122 return Integer.valueOf(model.getMaximum() - model.getExtent()); 1123 } 1124 1125 } // AccessibleJProgressBar 1126 }