Source for javax.swing.JProgressBar

   1: /* JProgressBar.java --
   2:    Copyright (C) 2002, 2004, 2005  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 java.awt.Graphics;
  42: 
  43: import javax.accessibility.Accessible;
  44: import javax.accessibility.AccessibleContext;
  45: import javax.accessibility.AccessibleRole;
  46: import javax.accessibility.AccessibleStateSet;
  47: import javax.accessibility.AccessibleValue;
  48: import javax.swing.border.Border;
  49: import javax.swing.event.ChangeEvent;
  50: import javax.swing.event.ChangeListener;
  51: import javax.swing.plaf.ProgressBarUI;
  52: 
  53: /**
  54:  * The ProgressBar is a widget that displays in two modes. In 
  55:  * determinate mode, it displays fills a percentage of its bar
  56:  * based on its current value. In indeterminate mode, it creates
  57:  * box and bounces it between its bounds.
  58:  *
  59:  * <p>
  60:  * JProgressBars have the following properties:
  61:  * </p>
  62:  * 
  63:  * <table>
  64:  * <tr><th> Property         </th><th> Stored in   </th><th> Bound? </th></tr>
  65:  * <tr><td> borderPainted    </td><td> progressBar </td><td> yes    </td></tr>
  66:  * <tr><td> changeListeners  </td><td> progressBar </td><td> no     </td></tr>
  67:  * <tr><td> indeterminate    </td><td> progressBar </td><td> yes    </td></tr> 
  68:  * <tr><td> maximum          </td><td> model       </td><td> no     </td></tr>
  69:  * <tr><td> minimum          </td><td> model       </td><td> no     </td></tr>
  70:  * <tr><td> model            </td><td> progressBar </td><td> no     </td></tr> 
  71:  * <tr><td> orientation      </td><td> progressBar </td><td> yes    </td></tr>
  72:  * <tr><td> percentComplete  </td><td> progressBar </td><td> no     </td></tr>
  73:  * <tr><td> string           </td><td> progressBar </td><td> yes    </td></tr>
  74:  * <tr><td> stringPainted    </td><td> progressBar </td><td> yes    </td></tr>
  75:  * <tr><td> value            </td><td> model       </td><td> no     </td></tr>
  76:  * </table>
  77:  */
  78: public class JProgressBar extends JComponent implements SwingConstants,
  79:                                                         Accessible
  80: {
  81:   /**
  82:    * AccessibleJProgressBar
  83:    */
  84:   // FIXME: This inner class is a complete stub and needs to be implemented
  85:   // properly.
  86:   protected class AccessibleJProgressBar extends AccessibleJComponent
  87:     implements AccessibleValue
  88:   {
  89:     private static final long serialVersionUID = -2938130009392721813L;
  90:   
  91:     /**
  92:      * Constructor AccessibleJProgressBar
  93:      */
  94:     protected AccessibleJProgressBar()
  95:     {
  96:       // Nothing to do here.
  97:     } 
  98: 
  99:     /**
 100:      * getAccessibleStateSet
 101:      *
 102:      * @return AccessibleStateSet
 103:      */
 104:     public AccessibleStateSet getAccessibleStateSet()
 105:     {
 106:       return null; 
 107:     } 
 108: 
 109:     /**
 110:      * getAccessibleRole
 111:      *
 112:      * @return AccessibleRole
 113:      */
 114:     public AccessibleRole getAccessibleRole()
 115:     {
 116:       return AccessibleRole.PROGRESS_BAR;
 117:     } 
 118: 
 119:     /**
 120:      * getAccessibleValue
 121:      *
 122:      * @return AccessibleValue
 123:      */
 124:     public AccessibleValue getAccessibleValue()
 125:     {
 126:       return null;
 127:     } 
 128: 
 129:     /**
 130:      * getCurrentAccessibleValue
 131:      *
 132:      * @return Number
 133:      */
 134:     public Number getCurrentAccessibleValue()
 135:     {
 136:       return null;
 137:     } 
 138: 
 139:     /**
 140:      * setCurrentAccessibleValue
 141:      *
 142:      * @param value0 TODO
 143:      *
 144:      * @return boolean
 145:      */
 146:     public boolean setCurrentAccessibleValue(Number value0)
 147:     {
 148:       return false; 
 149:     } 
 150: 
 151:     /**
 152:      * getMinimumAccessibleValue
 153:      *
 154:      * @return Number
 155:      */
 156:     public Number getMinimumAccessibleValue()
 157:     {
 158:       return null; 
 159:     } 
 160: 
 161:     /**
 162:      * getMaximumAccessibleValue
 163:      *
 164:      * @return Number
 165:      */
 166:     public Number getMaximumAccessibleValue()
 167:     {
 168:       return null; 
 169:     } 
 170:   } 
 171: 
 172:   private static final long serialVersionUID = 1980046021813598781L;
 173:   
 174:   /** Whether the ProgressBar is determinate. */
 175:   private transient boolean indeterminate = false;
 176: 
 177:   /** The orientation of the ProgressBar */
 178:   protected int orientation = HORIZONTAL;
 179: 
 180:   /** Whether borders should be painted. */
 181:   protected boolean paintBorder = true;
 182: 
 183:   /** The model describing this ProgressBar. */
 184:   protected BoundedRangeModel model;
 185: 
 186:   /** The string that is displayed by the ProgressBar. */
 187:   protected String progressString;
 188: 
 189:   /** Whether the string should be painted. */
 190:   protected boolean paintString = false;
 191: 
 192:   /** The static changeEvent passed to all ChangeListeners. */
 193:   protected transient ChangeEvent changeEvent;
 194: 
 195:   /** The ChangeListener that listens to the model. */
 196:   protected ChangeListener changeListener;
 197: 
 198:   /**
 199:    * Creates a new horizontally oriented JProgressBar object 
 200:    * with a minimum of 0 and a maximum of 100.
 201:    */
 202:   public JProgressBar()
 203:   {
 204:     this(HORIZONTAL, 0, 100);
 205:   }
 206: 
 207:   /**
 208:    * Creates a new JProgressBar object with a minimum of 0,
 209:    * a maximum of 100, and the given orientation.
 210:    *
 211:    * @param orientation The orientation of the JProgressBar.
 212:    * 
 213:    * @throws IllegalArgumentException if <code>orientation</code> is not either
 214:    *         {@link #HORIZONTAL} or {@link #VERTICAL}.
 215:    */
 216:   public JProgressBar(int orientation)
 217:   {
 218:     this(orientation, 0, 100);
 219:   }
 220: 
 221:   /**
 222:    * Creates a new horizontally oriented JProgressBar object
 223:    * with the given minimum and maximum.
 224:    *
 225:    * @param minimum The minimum of the JProgressBar.
 226:    * @param maximum The maximum of the JProgressBar.
 227:    */
 228:   public JProgressBar(int minimum, int maximum)
 229:   {
 230:     this(HORIZONTAL, minimum, maximum);
 231:   }
 232: 
 233:   /**
 234:    * Creates a new JProgressBar object with the given minimum,
 235:    * maximum, and orientation.
 236:    *
 237:    * @param minimum The minimum of the JProgressBar.
 238:    * @param maximum The maximum of the JProgressBar.
 239:    * @param orientation The orientation of the JProgressBar.
 240:    * 
 241:    * @throws IllegalArgumentException if <code>orientation</code> is not either
 242:    *         {@link #HORIZONTAL} or {@link #VERTICAL}.
 243:    */
 244:   public JProgressBar(int orientation, int minimum, int maximum)
 245:   {
 246:     model = new DefaultBoundedRangeModel(minimum, 0, minimum, maximum);
 247:     if (orientation != HORIZONTAL && orientation != VERTICAL)
 248:       throw new IllegalArgumentException(orientation + " is not a legal orientation");    
 249:     setOrientation(orientation);
 250:     changeListener = createChangeListener();
 251:     model.addChangeListener(changeListener);
 252:     updateUI();
 253:   }
 254: 
 255:   /**
 256:    * Creates a new horizontally oriented JProgressBar object 
 257:    * with the given model.
 258:    *
 259:    * @param model The model to be used with the JProgressBar.
 260:    */
 261:   public JProgressBar(BoundedRangeModel model)
 262:   {
 263:     this.model = model;
 264:     changeListener = createChangeListener();
 265:     model.addChangeListener(changeListener);
 266:     updateUI();    
 267:   }
 268: 
 269:   /**
 270:    * This method returns the current value of the JProgressBar.
 271:    *
 272:    * @return The current value of the JProgressBar.
 273:    */
 274:   public int getValue()
 275:   {
 276:     return model.getValue();
 277:   }
 278: 
 279:   /**
 280:    * This method sets the value of the JProgressBar.
 281:    *
 282:    * @param value The value of the JProgressBar.
 283:    */
 284:   public void setValue(int value)
 285:   {
 286:     model.setValue(value);
 287:   }
 288: 
 289:   /**
 290:    * This method paints the border of the JProgressBar
 291:    *
 292:    * @param graphics The graphics object to paint with.
 293:    */
 294:   protected void paintBorder(Graphics graphics)
 295:   {
 296:     Border border = getBorder();
 297:     if (paintBorder && border != null)
 298:       border.paintBorder(this, graphics, 0, 0,
 299:                          getWidth(),
 300:                          getHeight());
 301:   }
 302: 
 303:   /**
 304:    * This method returns the orientation of the JProgressBar.
 305:    *
 306:    * @return The orientation of the JProgressBar.
 307:    */
 308:   public int getOrientation()
 309:   {
 310:     return orientation;
 311:   }
 312: 
 313:   /**
 314:    * This method changes the orientation property. The orientation of the 
 315:    * JProgressBar can be either horizontal or vertical.
 316:    *
 317:    * @param orientation The orientation of the JProgressBar.
 318:    */
 319:   public void setOrientation(int orientation)
 320:   {
 321:     if (orientation != VERTICAL && orientation != HORIZONTAL)
 322:       throw new IllegalArgumentException("orientation must be one of VERTICAL or HORIZONTAL");
 323:     if (this.orientation != orientation)
 324:       {
 325:     int oldOrientation = this.orientation;
 326:     this.orientation = orientation;
 327:     firePropertyChange("orientation", oldOrientation,
 328:                        this.orientation);
 329:       }
 330:   }
 331: 
 332:   /**
 333:    * This method returns whether the progressString will be painted.
 334:    *
 335:    * @return Whether the string is painted.
 336:    */
 337:   public boolean isStringPainted()
 338:   {
 339:     return paintString;
 340:   }
 341: 
 342:   /**
 343:    * This method changes the stringPainted property.
 344:    *
 345:    * @param painted Whether the string is painted.
 346:    */
 347:   public void setStringPainted(boolean painted)
 348:   {
 349:     if (paintString != painted)
 350:       {
 351:     boolean oldPainted = paintString;
 352:     paintString = painted;
 353:     firePropertyChange("stringPainted", oldPainted,
 354:                        paintString);
 355:       }
 356:   }
 357: 
 358:   /**
 359:    * This method returns the string that is painted if the 
 360:    * stringPainted property is set to true. If there is no
 361:    * string set, it will return a string containing the 
 362:    * JProgressBar's value as a percent.
 363:    *
 364:    * @return The string that is painted.
 365:    */
 366:   public String getString()
 367:   {
 368:     if (progressString != null)
 369:       return progressString;
 370:     else
 371:       return (int) (getPercentComplete() * 100) + "%";
 372:   }
 373: 
 374:   /**
 375:    * This method changes the string property. The string
 376:    * given will be the one painted. If you want to 
 377:    * revert to the default string given, set the
 378:    * string to null.
 379:    *
 380:    * @param string The string to be painted.
 381:    */
 382:   public void setString(String string)
 383:   {
 384:     if (((string == null || progressString == null) &&
 385:         string != progressString) || (string != null &&
 386:     ! string.equals(progressString)))
 387:       {
 388:     String oldString = progressString;
 389:     progressString = string;
 390:     firePropertyChange("string", oldString, progressString);
 391:       }
 392:   }
 393: 
 394:   /**
 395:    * This method returns the percent of the bar
 396:    * that is "complete". (This is the amount value / (max - min)).
 397:    *
 398:    * @return DOCUMENT ME!
 399:    */
 400:   public double getPercentComplete()
 401:   {
 402:     if (getMaximum() == getMinimum())
 403:       return 1.0;
 404:     else
 405:       return (double) (model.getValue() - model.getMinimum()) / (model
 406:                                                                  .getMaximum()
 407:              - model.getMinimum());
 408:   }
 409: 
 410:   /**
 411:    * This method returns whether the border is painted.
 412:    *
 413:    * @return Whether the border is painted.
 414:    */
 415:   public boolean isBorderPainted()
 416:   {
 417:     return paintBorder;
 418:   }
 419: 
 420:   /**
 421:    * This method changes the borderPainted property.
 422:    *
 423:    * @param painted Whether the border is painted.
 424:    */
 425:   public void setBorderPainted(boolean painted)
 426:   {
 427:     if (painted != paintBorder)
 428:       {
 429:     boolean oldPainted = paintBorder;
 430:     paintBorder = painted;
 431:     firePropertyChange("borderPainted", oldPainted,
 432:                        paintBorder);
 433:       }
 434:   }
 435: 
 436:   /**
 437:    * This method returns the JProgressBar's UI delegate.
 438:    *
 439:    * @return This JProgressBar's UI delegate.
 440:    */
 441:   public ProgressBarUI getUI()
 442:   {
 443:     return (ProgressBarUI) ui;
 444:   }
 445: 
 446:   /**
 447:    * This method changes the UI property for this JProgressBar.
 448:    *
 449:    * @param ui The new UI delegate.
 450:    */
 451:   public void setUI(ProgressBarUI ui)
 452:   {
 453:     super.setUI(ui);
 454:   }
 455: 
 456:   /**
 457:    * This method reverts the UI delegate for this JProgressBar
 458:    * to the default for this Look and Feel.
 459:    */
 460:   public void updateUI()
 461:   {
 462:     setUI((ProgressBarUI) UIManager.getUI(this));
 463:     invalidate();
 464:   }
 465: 
 466:   /**
 467:    * This method returns the identifier to allow the UIManager
 468:    * to pick the correct class to act as the UI for
 469:    * this JProgressBar.
 470:    *
 471:    * @return The UIClassID: "ProgressBarUI".
 472:    */
 473:   public String getUIClassID()
 474:   {
 475:     return "ProgressBarUI";
 476:   }
 477: 
 478:   /**
 479:    * This method returns a ChangeListener that gets registered
 480:    * model. By default, the ChangeListener, propagates the 
 481:    * ChangeEvents to the ChangeListeners of the JProgressBar.
 482:    *
 483:    * @return A new ChangeListener.
 484:    */
 485:   protected ChangeListener createChangeListener()
 486:   {
 487:     return new ChangeListener()
 488:       {
 489:     public void stateChanged(ChangeEvent ce)
 490:     {
 491:       fireStateChanged();
 492:     }
 493:       };
 494:   }
 495: 
 496:   /**
 497:    * This method adds a ChangeListener to this JProgressBar.
 498:    *
 499:    * @param listener The ChangeListener to add to this JProgressBar.
 500:    */
 501:   public void addChangeListener(ChangeListener listener)
 502:   {
 503:     listenerList.add(ChangeListener.class, listener);
 504:   }
 505: 
 506:   /**
 507:    * This method removes a ChangeListener from this JProgressBar.
 508:    *
 509:    * @param listener The ChangeListener to remove from this JProgressBar.
 510:    */
 511:   public void removeChangeListener(ChangeListener listener)
 512:   {
 513:     listenerList.remove(ChangeListener.class, listener);
 514:   }
 515:   
 516:   /**
 517:    * This method returns an array of all ChangeListeners listening to this
 518:    * progress bar.
 519:    *
 520:    * @return An array of ChangeListeners listening to this progress bar.
 521:    */
 522:   public ChangeListener[] getChangeListeners()
 523:   {
 524:     return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
 525:   }  
 526: 
 527:   /**
 528:    * This method is called when the JProgressBar receives a ChangeEvent
 529:    * from its model. This simply propagates the event (changing the source
 530:    * to the JProgressBar) to the JProgressBar's listeners.
 531:    */
 532:   protected void fireStateChanged()
 533:   {
 534:     Object[] changeListeners = listenerList.getListenerList();
 535:     if (changeEvent == null)
 536:       changeEvent = new ChangeEvent(this);
 537:     for (int i = changeListeners.length - 2; i >= 0; i -= 2)
 538:       {
 539:     if (changeListeners[i] == ChangeListener.class)
 540:       ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
 541:       }
 542:   }
 543: 
 544:   /**
 545:    * This method returns the model used with this JProgressBar.
 546:    *
 547:    * @return The model used with this JProgressBar.
 548:    */
 549:   public BoundedRangeModel getModel()
 550:   {
 551:     return model;
 552:   }
 553: 
 554:   /**
 555:    * This method changes the model property for this JProgressBar.
 556:    *
 557:    * @param model The model to use with this JProgressBar.
 558:    */
 559:   public void setModel(BoundedRangeModel model)
 560:   {
 561:     if (model != this.model)
 562:       {
 563:         this.model.removeChangeListener(changeListener);
 564:     this.model = model;
 565:     this.model.addChangeListener(changeListener);
 566:     fireStateChanged();
 567:       }
 568:   }
 569: 
 570:   /**
 571:    * This method returns the minimum value of this JProgressBar.
 572:    *
 573:    * @return The minimum value of this JProgressBar.
 574:    */
 575:   public int getMinimum()
 576:   {
 577:     return model.getMinimum();
 578:   }
 579: 
 580:   /**
 581:    * This method sets the minimum value of this JProgressBar.
 582:    *
 583:    * @param minimum The minimum value of this JProgressBar.
 584:    */
 585:   public void setMinimum(int minimum)
 586:   {
 587:     model.setMinimum(minimum);
 588:   }
 589: 
 590:   /**
 591:    * This method returns the maximum value of this JProgressBar.
 592:    *
 593:    * @return The maximum value of this JProgressBar.
 594:    */
 595:   public int getMaximum()
 596:   {
 597:     return model.getMaximum();
 598:   }
 599: 
 600:   /**
 601:    * This method sets the maximum value of this JProgressBar.
 602:    *
 603:    * @param maximum The maximum value of this JProgressBar.
 604:    */
 605:   public void setMaximum(int maximum)
 606:   {
 607:     model.setMaximum(maximum);
 608:   }
 609: 
 610:   /**
 611:    * This method returns a string that can be used to 
 612:    * describe this JProgressBar. This method is usually
 613:    * only used for debugging purposes.
 614:    *
 615:    * @return A string that describes this JProgressBar.
 616:    */
 617:   protected String paramString()
 618:   {
 619:     return "JProgressBar";
 620:   }
 621: 
 622:   /**
 623:    * This method changes the indeterminate property. If the
 624:    * JProgressBar is determinate, it paints a percentage
 625:    * of the bar described by its value. If it is indeterminate,
 626:    * it simply bounces a box between the ends of the bar; the 
 627:    * value of the JProgressBar is ignored.
 628:    *
 629:    * @param newValue Whether the JProgressBar is indeterminate.
 630:    */
 631:   public void setIndeterminate(boolean newValue)
 632:   {
 633:     if (indeterminate != newValue)
 634:       {
 635:     boolean olddeter = indeterminate;
 636:     indeterminate = newValue;
 637:     firePropertyChange("indeterminate", olddeter,
 638:                        indeterminate);
 639:       }
 640:   }
 641: 
 642:   /**
 643:    * This method returns whether the JProgressBar is indeterminate.
 644:    *
 645:    * @return Whether this JProgressBar is indeterminate.
 646:    */
 647:   public boolean isIndeterminate()
 648:   {
 649:     return indeterminate;
 650:   }
 651: 
 652:   /**
 653:    * DOCUMENT ME!
 654:    *
 655:    * @return DOCUMENT ME!
 656:    */
 657:   public AccessibleContext getAccessibleContext()
 658:   {
 659:     if (accessibleContext == null)
 660:       accessibleContext = new AccessibleJProgressBar();
 661:     
 662:     return accessibleContext;
 663:   } 
 664: }