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