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