1 /* JProgressBar.java -- 2 Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package javax.swing; 40 41 import gnu.java.lang.CPStringBuilder; 42 43 import java.awt.Graphics; 44 import java.beans.PropertyChangeEvent; 45 46 import javax.accessibility.Accessible; 47 import javax.accessibility.AccessibleContext; 48 import javax.accessibility.AccessibleRole; 49 import javax.accessibility.AccessibleState; 50 import javax.accessibility.AccessibleStateSet; 51 import javax.accessibility.AccessibleValue; 52 import javax.swing.border.Border; 53 import javax.swing.event.ChangeEvent; 54 import javax.swing.event.ChangeListener; 55 import javax.swing.plaf.ProgressBarUI; 56 57 /** 58 * A component that displays a visual indicator of the progress of a task. The 59 * component has two modes: determinate and indeterminate. In determinate mode, 60 * the <code>JProgressBar</code> fills a percentage of its bar based on its 61 * current value. In indeterminate mode, it creates box and bounces it between 62 * its bounds. 63 * <p> 64 * This component has the following properties: 65 * </p> 66 * <table> 67 * <tr><th> Property </th><th> Stored in </th><th> Bound? </th></tr> 68 * <tr><td> borderPainted </td><td> progressBar </td><td> yes </td></tr> 69 * <tr><td> changeListeners </td><td> progressBar </td><td> no </td></tr> 70 * <tr><td> indeterminate </td><td> progressBar </td><td> yes </td></tr> 71 * <tr><td> maximum </td><td> model </td><td> no </td></tr> 72 * <tr><td> minimum </td><td> model </td><td> no </td></tr> 73 * <tr><td> model </td><td> progressBar </td><td> no </td></tr> 74 * <tr><td> orientation </td><td> progressBar </td><td> yes </td></tr> 75 * <tr><td> percentComplete </td><td> progressBar </td><td> no </td></tr> 76 * <tr><td> string </td><td> progressBar </td><td> yes </td></tr> 77 * <tr><td> stringPainted </td><td> progressBar </td><td> yes </td></tr> 78 * <tr><td> value </td><td> model </td><td> no </td></tr> 79 * </table> 80 */ 81 public class JProgressBar extends JComponent implements SwingConstants, 82 Accessible 83 { 84 /** 85 * Provides the accessibility features for the <code>JProgressBar</code> 86 * component. 87 */ 88 protected class AccessibleJProgressBar extends AccessibleJComponent 89 implements AccessibleValue 90 { 91 private static final long serialVersionUID = -2938130009392721813L; 92 93 /** 94 * Creates a new <code>AccessibleJProgressBar</code> instance. 95 */ AccessibleJProgressBar()96 protected AccessibleJProgressBar() 97 { 98 // Nothing to do here. 99 } 100 101 /** 102 * Returns a set containing the current state of the {@link JProgressBar} 103 * component. 104 * 105 * @return The accessible state set. 106 */ getAccessibleStateSet()107 public AccessibleStateSet getAccessibleStateSet() 108 { 109 AccessibleStateSet result = super.getAccessibleStateSet(); 110 if (orientation == JProgressBar.HORIZONTAL) 111 result.add(AccessibleState.HORIZONTAL); 112 else if (orientation == JProgressBar.VERTICAL) 113 result.add(AccessibleState.VERTICAL); 114 return result; 115 } 116 117 /** 118 * Returns the accessible role for the <code>JProgressBar</code> component. 119 * 120 * @return {@link AccessibleRole#PROGRESS_BAR}. 121 */ getAccessibleRole()122 public AccessibleRole getAccessibleRole() 123 { 124 return AccessibleRole.PROGRESS_BAR; 125 } 126 127 /** 128 * Returns an object that provides access to the current, minimum and 129 * maximum values. 130 * 131 * @return The accessible value. 132 */ getAccessibleValue()133 public AccessibleValue getAccessibleValue() 134 { 135 return this; 136 } 137 138 /** 139 * Returns the current value of the {@link JProgressBar} component, as an 140 * {@link Integer}. 141 * 142 * @return The current value of the {@link JProgressBar} component. 143 */ getCurrentAccessibleValue()144 public Number getCurrentAccessibleValue() 145 { 146 return new Integer(getValue()); 147 } 148 149 /** 150 * Sets the current value of the {@link JProgressBar} component and sends a 151 * {@link PropertyChangeEvent} (with the property name 152 * {@link AccessibleContext#ACCESSIBLE_VALUE_PROPERTY}) to all registered 153 * listeners. If the supplied value is <code>null</code>, this method 154 * does nothing and returns <code>false</code>. 155 * 156 * @param value the new progress bar value (<code>null</code> permitted). 157 * 158 * @return <code>true</code> if the slider value is updated, and 159 * <code>false</code> otherwise. 160 */ setCurrentAccessibleValue(Number value)161 public boolean setCurrentAccessibleValue(Number value) 162 { 163 if (value == null) 164 return false; 165 Number oldValue = getCurrentAccessibleValue(); 166 setValue(value.intValue()); 167 firePropertyChange(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, oldValue, 168 new Integer(getValue())); 169 return true; 170 } 171 172 /** 173 * Returns the minimum value of the {@link JProgressBar} component, as an 174 * {@link Integer}. 175 * 176 * @return The minimum value of the {@link JProgressBar} component. 177 */ getMinimumAccessibleValue()178 public Number getMinimumAccessibleValue() 179 { 180 return new Integer(getMinimum()); 181 } 182 183 /** 184 * Returns the maximum value of the {@link JProgressBar} component, as an 185 * {@link Integer}. 186 * 187 * @return The maximum value of the {@link JProgressBar} component. 188 */ getMaximumAccessibleValue()189 public Number getMaximumAccessibleValue() 190 { 191 return new Integer(getMaximum()); 192 } 193 } 194 195 private static final long serialVersionUID = 1980046021813598781L; 196 197 /** 198 * A flag that determines the mode (<code>true</code> for indeterminate, 199 * <code>false</code> for determinate). 200 */ 201 private transient boolean indeterminate = false; 202 203 /** 204 * The orientation of the <code>JProgressBar</code> 205 * ({@link SwingConstants#HORIZONTAL} or {@link SwingConstants#VERTICAL}). 206 * Defaults to {@link SwingConstants#HORIZONTAL}. 207 * @see #setOrientation(int) 208 */ 209 protected int orientation; 210 211 /** 212 * A flag the controls whether or not the component's border is painted. 213 * The default is <code>true</code>. 214 * @see #setBorderPainted(boolean) 215 */ 216 protected boolean paintBorder = true; 217 218 /** 219 * The model defining the bounds and current value for the progress bar. 220 * @see #setModel(BoundedRangeModel) 221 */ 222 protected BoundedRangeModel model; 223 224 /** 225 * A custom string for display in the progress bar. If this is 226 * <code>null</code>, a default string will be generated. 227 * @see #setString(String) 228 */ 229 protected String progressString; 230 231 /** 232 * A flag that controls whether a string is displayed within the progress 233 * bar. 234 * @see #setStringPainted(boolean) 235 */ 236 protected boolean paintString = false; 237 238 /** 239 * A single change event reused for all events. 240 * @see #fireStateChanged() 241 */ 242 protected transient ChangeEvent changeEvent; 243 244 /** 245 * The listener that is registered with the model. */ 246 protected ChangeListener changeListener; 247 248 /** 249 * Creates a new <code>JProgressBar</code> with default attributes. The 250 * following defaults are used: 251 * <p> 252 * <ul> 253 * <li><code>value</code>: 0;</li> 254 * <li><code>minimum</code>: 0;</li> 255 * <li><code>maximum</code>: 100;</li> 256 * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li> 257 * </ul> 258 */ JProgressBar()259 public JProgressBar() 260 { 261 this(HORIZONTAL, 0, 100); 262 } 263 264 /** 265 * Creates a new <code>JProgressBar</code> with the specified 266 * <code>orientation</code>. The following defaults are used: 267 * <p> 268 * <ul> 269 * <li><code>value</code>: 0;</li> 270 * <li><code>minimum</code>: 0;</li> 271 * <li><code>maximum</code>: 100;</li> 272 * </ul> 273 * 274 * @param orientation the orientation ({@link #HORIZONTAL} or 275 * {@link #VERTICAL}). 276 * 277 * @throws IllegalArgumentException if <code>orientation</code> is not one of 278 * the specified values. 279 */ JProgressBar(int orientation)280 public JProgressBar(int orientation) 281 { 282 this(orientation, 0, 100); 283 } 284 285 /** 286 * Creates a new <code>JProgressBar</code> with the specified value range. 287 * The following defaults are used: 288 * <p> 289 * <ul> 290 * <li><code>value</code>: <code>minimum</code>;</li> 291 * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li> 292 * </ul> 293 * 294 * @param minimum the lower bound of the value range. 295 * @param maximum the upper bound of the value range. 296 */ JProgressBar(int minimum, int maximum)297 public JProgressBar(int minimum, int maximum) 298 { 299 this(HORIZONTAL, minimum, maximum); 300 } 301 302 /** 303 * Creates a new <code>JProgressBar</code> with the specified range and 304 * orientation. The following defaults are used: 305 * <p> 306 * <ul> 307 * <li><code>value</code>: <code>minimum</code>;</li> 308 * </ul> 309 * 310 * @param minimum the lower bound of the value range. 311 * @param maximum the upper bound of the value range. 312 * @param orientation the orientation ({@link #HORIZONTAL} or 313 * {@link #VERTICAL}). 314 * 315 * @throws IllegalArgumentException if <code>orientation</code> is not one of 316 * the specified values. 317 */ JProgressBar(int orientation, int minimum, int maximum)318 public JProgressBar(int orientation, int minimum, int maximum) 319 { 320 model = new DefaultBoundedRangeModel(minimum, 0, minimum, maximum); 321 if (orientation != HORIZONTAL && orientation != VERTICAL) 322 throw new IllegalArgumentException(orientation 323 + " is not a legal orientation"); 324 this.orientation = orientation; 325 changeListener = createChangeListener(); 326 model.addChangeListener(changeListener); 327 updateUI(); 328 } 329 330 /** 331 * Creates a new <code>JProgressBar</code> with the specified model. The 332 * following defaults are used: 333 * <p> 334 * <ul> 335 * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li> 336 * </ul> 337 * 338 * @param model the model (<code>null</code> not permitted). 339 */ JProgressBar(BoundedRangeModel model)340 public JProgressBar(BoundedRangeModel model) 341 { 342 this.model = model; 343 changeListener = createChangeListener(); 344 if (model != null) 345 model.addChangeListener(changeListener); 346 updateUI(); 347 } 348 349 /** 350 * Returns the current value for the <code>JProgressBar</code>. This value 351 * is fetched from the model. 352 * 353 * @return The current value. 354 * 355 * @see #setValue(int) 356 */ getValue()357 public int getValue() 358 { 359 return model.getValue(); 360 } 361 362 /** 363 * Sets the current value for the <code>JProgressBar</code>. The value is 364 * stored in the component's <code>model</code> (see {@link #getModel()}). 365 * If the new value is different to the old value, a {@link ChangeEvent} is 366 * sent to the model's registered listeners. In turn, this triggers a call 367 * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code> 368 * to this component's registered listeners. 369 * <p> 370 * If <code>value</code> is outside the range <code>minimum</code> to 371 * <code>maximum</code>, it will be set to the nearest of those boundary 372 * values. 373 * 374 * @param value the new value. 375 * 376 * @see #getValue() 377 */ setValue(int value)378 public void setValue(int value) 379 { 380 model.setValue(value); 381 } 382 383 /** 384 * Paints the component's border, but only if {@link #isBorderPainted()} 385 * returns <code>true</code>. 386 * 387 * @param graphics the graphics object to paint with. 388 * 389 * @see #setBorderPainted(boolean) 390 */ paintBorder(Graphics graphics)391 protected void paintBorder(Graphics graphics) 392 { 393 Border border = getBorder(); 394 if (paintBorder && border != null) 395 border.paintBorder(this, graphics, 0, 0, getWidth(), getHeight()); 396 } 397 398 /** 399 * Returns the orientation of the <code>JProgressBar</code> component, which 400 * is either {@link SwingConstants#HORIZONTAL} or 401 * {@link SwingConstants#VERTICAL}. The default orientation is 402 * <code>HORIZONTAL</code>. 403 * 404 * @return The orientation. 405 * 406 * @see #setOrientation(int) 407 */ getOrientation()408 public int getOrientation() 409 { 410 return orientation; 411 } 412 413 /** 414 * Sets the orientation for this <code>JProgressBar</code> component and, 415 * if the value changes, sends a {@link PropertyChangeEvent} (with the 416 * property name <code>"orientation"</code>) to all registered listeners. 417 * 418 * @param orientation the orientation ({@link #HORIZONTAL} or 419 * {@link #VERTICAL}). 420 * 421 * @throws IllegalArgumentException if <code>orientation</code> is not 422 * one of the listed values. 423 * 424 * @see #getOrientation() 425 */ setOrientation(int orientation)426 public void setOrientation(int orientation) 427 { 428 if (orientation != VERTICAL && orientation != HORIZONTAL) 429 throw new IllegalArgumentException(orientation 430 + " is not a legal orientation"); 431 if (this.orientation != orientation) 432 { 433 int oldOrientation = this.orientation; 434 this.orientation = orientation; 435 firePropertyChange("orientation", oldOrientation, this.orientation); 436 } 437 } 438 439 /** 440 * Returns the flag that controls whether or not the string returned by 441 * {@link #getString()} is displayed by the <code>JProgressBar</code> 442 * component. 443 * 444 * @return <code>true</code> if the string should be displayed, and 445 * <code>false</code> otherwise. 446 * 447 * @see #setStringPainted(boolean) 448 */ isStringPainted()449 public boolean isStringPainted() 450 { 451 return paintString; 452 } 453 454 /** 455 * Sets the flag that controls whether or not the string returned by 456 * {@link #getString()} is displayed by the <code>JProgressBar</code> 457 * component. If the flag value changes, a {@link PropertyChangeEvent} (with 458 * the property name <code>"stringPainted"</code>) is sent to all registered 459 * listeners. 460 * 461 * @param painted the new flag value. 462 * 463 * @see #isStringPainted() 464 * @see #setString(String) 465 */ setStringPainted(boolean painted)466 public void setStringPainted(boolean painted) 467 { 468 if (paintString != painted) 469 { 470 boolean oldPainted = paintString; 471 paintString = painted; 472 firePropertyChange("stringPainted", oldPainted, paintString); 473 } 474 } 475 476 /** 477 * Returns the string that is painted on the <code>JProgressBar</code> if 478 * {@link #isStringPainted()} returns <code>true</code>. If no string has 479 * been explicitly set, this method will return a string displaying the 480 * value of {@link #getPercentComplete()}. 481 * 482 * @return The string. 483 * 484 * @see #setString(String) 485 * @see #setStringPainted(boolean) 486 */ getString()487 public String getString() 488 { 489 if (progressString != null) 490 return progressString; 491 else 492 return (int) (getPercentComplete() * 100) + "%"; 493 } 494 495 /** 496 * Sets the string to display within the progress bar and, if the new value 497 * is different to the old value, sends a {@link PropertyChangeEvent} (with 498 * the property name <code>"string"</code>) to all registered listeners. If 499 * the string is set to <code>null</code>, {@link #getString()} will return 500 * a default string. 501 * 502 * @param string the string (<code>null</code> permitted). 503 * 504 * @see #getString() 505 * @see #setStringPainted(boolean) 506 */ setString(String string)507 public void setString(String string) 508 { 509 if (((string == null || progressString == null) && 510 string != progressString) || (string != null && 511 ! string.equals(progressString))) 512 { 513 String oldString = progressString; 514 progressString = string; 515 firePropertyChange("string", oldString, progressString); 516 } 517 } 518 519 /** 520 * Returns the current value expressed as a percentage. This is calculated 521 * as <code>(value - min) / (max - min)</code>. 522 * 523 * @return The percentage (a value in the range 0.0 to 1.0). 524 */ getPercentComplete()525 public double getPercentComplete() 526 { 527 if (getMaximum() == getMinimum()) 528 return 1.0; 529 else 530 return (double) (model.getValue() - model.getMinimum()) 531 / (model.getMaximum() - model.getMinimum()); 532 } 533 534 /** 535 * Returns a flag that controls whether or not the component's border is 536 * painted. The default value is <code>true</code>. 537 * 538 * @return <code>true</code> if the component's border should be painted, 539 * and <code>false</code> otherwise. 540 * 541 * @see #setBorderPainted(boolean) 542 */ isBorderPainted()543 public boolean isBorderPainted() 544 { 545 return paintBorder; 546 } 547 548 /** 549 * Sets the flag that controls whether or not the component's border is 550 * painted. If the flag value is changed, this method sends a 551 * {@link PropertyChangeEvent} (with the property name "borderPainted") to 552 * all registered listeners. 553 * 554 * @param painted the new flag value. 555 * 556 * @see #isBorderPainted() 557 * @see #paintBorder 558 */ setBorderPainted(boolean painted)559 public void setBorderPainted(boolean painted) 560 { 561 if (painted != paintBorder) 562 { 563 boolean oldPainted = paintBorder; 564 paintBorder = painted; 565 firePropertyChange("borderPainted", oldPainted, paintBorder); 566 } 567 } 568 569 /** 570 * Returns the UI delegate for this <code>JProgressBar</code>. 571 * 572 * @return The UI delegate. 573 */ getUI()574 public ProgressBarUI getUI() 575 { 576 return (ProgressBarUI) ui; 577 } 578 579 /** 580 * Sets the UI delegate for this component. 581 * 582 * @param ui the new UI delegate. 583 */ setUI(ProgressBarUI ui)584 public void setUI(ProgressBarUI ui) 585 { 586 super.setUI(ui); 587 } 588 589 /** 590 * Sets this <code>JProgressBar</code>'s UI delegate to the default 591 * (obtained from the {@link UIManager}) for the current look and feel. 592 */ updateUI()593 public void updateUI() 594 { 595 setUI((ProgressBarUI) UIManager.getUI(this)); 596 } 597 598 /** 599 * Returns the suffix (<code>"ProgressBarUI"</code> in this case) used to 600 * determine the class name for a UI delegate that can provide the look and 601 * feel for a <code>JProgressBar</code>. 602 * 603 * @return <code>"ProgressBarUI"</code>. 604 */ getUIClassID()605 public String getUIClassID() 606 { 607 return "ProgressBarUI"; 608 } 609 610 /** 611 * Creates a new {@link ChangeListener} that calls 612 * {@link #fireStateChanged()} whenever it receives a {@link ChangeEvent} 613 * (typically from the component's <code>model</code>). This listener is 614 * registered with the progress bar's model, so that changes made to the 615 * model directly will automatically result in the progress bar's listeners 616 * being notified also. 617 * 618 * @return A new listener. 619 */ createChangeListener()620 protected ChangeListener createChangeListener() 621 { 622 return new ChangeListener() 623 { 624 public void stateChanged(ChangeEvent ce) 625 { 626 fireStateChanged(); 627 } 628 }; 629 } 630 631 /** 632 * Registers a listener with this component so that it will receive 633 * notification of component state changes. 634 * 635 * @param listener the listener. 636 * 637 * @see #removeChangeListener(ChangeListener) 638 */ 639 public void addChangeListener(ChangeListener listener) 640 { 641 listenerList.add(ChangeListener.class, listener); 642 } 643 644 /** 645 * Deregisters a listener so that it no longer receives notification of 646 * component state changes. 647 * 648 * @param listener the listener. 649 * 650 * @see #addChangeListener(ChangeListener) 651 */ 652 public void removeChangeListener(ChangeListener listener) 653 { 654 listenerList.remove(ChangeListener.class, listener); 655 } 656 657 /** 658 * Returns an array of the listeners that are registered with this component. 659 * The array may be empty, but is never <code>null</code>. 660 * 661 * @return An array of listeners. 662 * 663 * @since 1.4 664 */ 665 public ChangeListener[] getChangeListeners() 666 { 667 return (ChangeListener[]) listenerList.getListeners(ChangeListener.class); 668 } 669 670 /** 671 * Sends a {@link ChangeEvent} to all registered listeners to indicate that 672 * the state of the <code>JProgressBar</code> has changed. 673 * 674 * @see #createChangeListener() 675 */ 676 protected void fireStateChanged() 677 { 678 Object[] changeListeners = listenerList.getListenerList(); 679 if (changeEvent == null) 680 changeEvent = new ChangeEvent(this); 681 for (int i = changeListeners.length - 2; i >= 0; i -= 2) 682 { 683 if (changeListeners[i] == ChangeListener.class) 684 ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent); 685 } 686 } 687 688 /** 689 * Returns the model for the <code>JProgressBar</code>. 690 * 691 * @return The model (never <code>null</code>). 692 * 693 * @see #setModel(BoundedRangeModel) 694 */ 695 public BoundedRangeModel getModel() 696 { 697 return model; 698 } 699 700 /** 701 * Sets the model for the <code>JProgressBar</code> and sends a 702 * {@link ChangeEvent} to all registered listeners. 703 * 704 * @param model the model (<code>null</code> not permitted). 705 * 706 * @see #getModel() 707 */ 708 public void setModel(BoundedRangeModel model) 709 { 710 if (model != this.model) 711 { 712 this.model.removeChangeListener(changeListener); 713 this.model = model; 714 this.model.addChangeListener(changeListener); 715 fireStateChanged(); 716 } 717 } 718 719 /** 720 * Returns the minimum value for the <code>JProgressBar</code>. This defines 721 * the lower bound for the current value, and is stored in the component's 722 * <code>model</code>. 723 * 724 * @return The minimum value. 725 * 726 * @see #setMinimum(int) 727 */ 728 public int getMinimum() 729 { 730 return model.getMinimum(); 731 } 732 733 /** 734 * Sets the minimum value for the <code>JProgressBar</code>. The value is 735 * stored in the component's <code>model</code> (see {@link #getModel()}). 736 * If the new value is different to the old value, a {@link ChangeEvent} is 737 * sent to the model's registered listeners. In turn, this triggers a call 738 * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code> 739 * to this component's registered listeners. 740 * 741 * @param minimum the minimum value. 742 * 743 * @see #getMinimum() 744 */ 745 public void setMinimum(int minimum) 746 { 747 model.setMinimum(minimum); 748 } 749 750 /** 751 * Returns the maximum value for the <code>JProgressBar</code>. This defines 752 * the upper bound for the current value, and is stored in the component's 753 * <code>model</code>. 754 * 755 * @return The maximum value. 756 * 757 * @see #setMaximum(int) 758 */ 759 public int getMaximum() 760 { 761 return model.getMaximum(); 762 } 763 764 /** 765 * Sets the maximum value for the <code>JProgressBar</code>. The value is 766 * stored in the component's <code>model</code> (see {@link #getModel()}). 767 * If the new value is different to the old value, a {@link ChangeEvent} is 768 * sent to the model's registered listeners. In turn, this triggers a call 769 * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code> 770 * to this component's registered listeners. 771 * 772 * @param maximum the maximum value. 773 * 774 * @see #getMaximum() 775 */ 776 public void setMaximum(int maximum) 777 { 778 model.setMaximum(maximum); 779 } 780 781 /** 782 * Returns an implementation-dependent string describing the attributes of 783 * this <code>JProgressBar</code>. 784 * 785 * @return A string describing the attributes of this 786 * <code>JProgressBar</code> (never <code>null</code>). 787 */ 788 protected String paramString() 789 { 790 String superParamStr = super.paramString(); 791 CPStringBuilder sb = new CPStringBuilder(); 792 sb.append(",orientation="); 793 if (orientation == HORIZONTAL) 794 sb.append("HORIZONTAL"); 795 else 796 sb.append("VERTICAL"); 797 sb.append(",paintBorder=").append(isBorderPainted()); 798 sb.append(",paintString=").append(isStringPainted()); 799 sb.append(",progressString="); 800 if (progressString != null) 801 sb.append(progressString); 802 sb.append(",indeterminateString=").append(isIndeterminate()); 803 return superParamStr + sb.toString(); 804 } 805 806 /** 807 * Sets the flag that controls the mode for this <code>JProgressBar</code> 808 * (<code>true</code> for indeterminate mode, and <code>false</code> for 809 * determinate mode). If the flag value changes, this method sends a 810 * {@link PropertyChangeEvent} (with the property name 811 * <code>"indeterminate"</code>) to all registered listeners. 812 * <p> 813 * If the <code>JProgressBar</code> is determinate, it paints a percentage 814 * of the bar described by its value. If it is indeterminate, it simply 815 * bounces a box between the ends of the bar; the value of the 816 * <code>JProgressBar</code> is ignored. 817 * 818 * @param flag the new flag value. 819 * 820 * @see #isIndeterminate() 821 * @since 1.4 822 */ 823 public void setIndeterminate(boolean flag) 824 { 825 if (indeterminate != flag) 826 { 827 indeterminate = flag; 828 firePropertyChange("indeterminate", !flag, indeterminate); 829 } 830 } 831 832 /** 833 * Returns a flag that indicates the mode for this <code>JProgressBar</code> 834 * (<code>true</code> for indeterminate mode, and <code>false</code> for 835 * determinate mode). 836 * 837 * @return A flag indicating the mode for the <code>JProgressBar</code>. 838 * 839 * @see #setIndeterminate(boolean) 840 * @since 1.4 841 */ 842 public boolean isIndeterminate() 843 { 844 return indeterminate; 845 } 846 847 /** 848 * Returns the object that provides accessibility features for this 849 * <code>JProgressBar</code> component. 850 * 851 * @return The accessible context (an instance of 852 * {@link AccessibleJProgressBar}). 853 */ 854 public AccessibleContext getAccessibleContext() 855 { 856 if (accessibleContext == null) 857 accessibleContext = new AccessibleJProgressBar(); 858 859 return accessibleContext; 860 } 861 } 862