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