Source for javax.swing.JScrollBar

   1: /* JScrollBar.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 java.awt.Adjustable;
  42: import java.awt.Dimension;
  43: import java.awt.event.AdjustmentEvent;
  44: import java.awt.event.AdjustmentListener;
  45: import java.beans.PropertyChangeEvent;
  46: 
  47: import javax.accessibility.Accessible;
  48: import javax.accessibility.AccessibleContext;
  49: import javax.accessibility.AccessibleRole;
  50: import javax.accessibility.AccessibleState;
  51: import javax.accessibility.AccessibleStateSet;
  52: import javax.accessibility.AccessibleValue;
  53: import javax.swing.plaf.ScrollBarUI;
  54: 
  55: /**
  56:  * The JScrollBar. Two buttons control how the values that the 
  57:  * scroll bar can take. You can also drag the thumb or click the track
  58:  * to move the scroll bar. Typically, the JScrollBar is used with
  59:  * other components to translate the value of the bar to the viewable
  60:  * contents of the other components.
  61:  */
  62: public class JScrollBar extends JComponent implements Adjustable, Accessible
  63: {
  64:   /**
  65:    * Provides the accessibility features for the <code>JScrollBar</code>
  66:    * component.
  67:    */
  68:   protected class AccessibleJScrollBar extends JComponent.AccessibleJComponent
  69:     implements AccessibleValue
  70:   {
  71:     private static final long serialVersionUID = -7758162392045586663L;
  72:     
  73:     /**
  74:      * Creates a new <code>AccessibleJScrollBar</code> instance.
  75:      */
  76:     protected AccessibleJScrollBar()
  77:     {
  78:       super();
  79:     }
  80: 
  81:     /**
  82:      * Returns a set containing the current state of the {@link JScrollBar} 
  83:      * component.
  84:      *
  85:      * @return The accessible state set.
  86:      */
  87:     public AccessibleStateSet getAccessibleStateSet()
  88:     {
  89:       AccessibleStateSet result = super.getAccessibleStateSet();
  90:       if (orientation == JScrollBar.HORIZONTAL)
  91:         result.add(AccessibleState.HORIZONTAL);
  92:       else if (orientation == JScrollBar.VERTICAL)
  93:         result.add(AccessibleState.VERTICAL);
  94:       return result;
  95:     }
  96: 
  97:     /**
  98:      * Returns the accessible role for the <code>JScrollBar</code> component.
  99:      *
 100:      * @return {@link AccessibleRole#SCROLL_BAR}.
 101:      */
 102:     public AccessibleRole getAccessibleRole()
 103:     {
 104:       return AccessibleRole.SCROLL_BAR;
 105:     }
 106: 
 107:     /**
 108:      * Returns an object that provides access to the current, minimum and 
 109:      * maximum values.
 110:      *
 111:      * @return The accessible value.
 112:      */
 113:     public AccessibleValue getAccessibleValue()
 114:     {
 115:       return this;
 116:     }
 117: 
 118:     /**
 119:      * Returns the current value of the {@link JScrollBar} component, as an
 120:      * {@link Integer}.
 121:      *
 122:      * @return The current value of the {@link JScrollBar} component.
 123:      */
 124:     public Number getCurrentAccessibleValue()
 125:     {
 126:       return new Integer(getValue());
 127:     }
 128: 
 129:     /**
 130:      * Sets the current value of the {@link JScrollBar} component and sends a
 131:      * {@link PropertyChangeEvent} (with the property name 
 132:      * {@link AccessibleContext#ACCESSIBLE_VALUE_PROPERTY}) to all registered
 133:      * listeners.  If the supplied value is <code>null</code>, this method 
 134:      * does nothing and returns <code>false</code>.
 135:      *
 136:      * @param value  the new slider value (<code>null</code> permitted).
 137:      *
 138:      * @return <code>true</code> if the slider value is updated, and 
 139:      *     <code>false</code> otherwise.
 140:      */
 141:     public boolean setCurrentAccessibleValue(Number value)
 142:     {
 143:       if (value == null)
 144:         return false;
 145:       Number oldValue = getCurrentAccessibleValue();
 146:       setValue(value.intValue());
 147:       firePropertyChange(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, oldValue, 
 148:                          new Integer(getValue()));
 149:       return true;
 150:     }
 151: 
 152:     /**
 153:      * Returns the minimum value of the {@link JScrollBar} component, as an
 154:      * {@link Integer}.
 155:      *
 156:      * @return The minimum value of the {@link JScrollBar} component.
 157:      */
 158:     public Number getMinimumAccessibleValue()
 159:     {
 160:       return new Integer(getMinimum());
 161:     }
 162: 
 163:     /**
 164:      * Returns the maximum value of the {@link JScrollBar} component, as an
 165:      * {@link Integer}.
 166:      *
 167:      * @return The maximum value of the {@link JScrollBar} component.
 168:      */
 169:     public Number getMaximumAccessibleValue()
 170:     {
 171:       return new Integer(getMaximum() - model.getExtent());
 172:     }
 173:   }
 174: 
 175:   private static final long serialVersionUID = -8195169869225066566L;
 176:   
 177:   /** How much the thumb moves when moving in a block. */
 178:   protected int blockIncrement = 10;
 179: 
 180:   /** The model that holds the scroll bar's data. */
 181:   protected BoundedRangeModel model;
 182: 
 183:   /** The orientation of the scroll bar. */
 184:   protected int orientation = SwingConstants.VERTICAL;
 185: 
 186:   /** How much the thumb moves when moving in a unit. */
 187:   protected int unitIncrement = 1;
 188: 
 189:   /** 
 190:    * Creates a new horizontal JScrollBar object with a minimum
 191:    * of 0, a maxmium of 100, a value of 0 and an extent of 10.
 192:    */
 193:   public JScrollBar()
 194:   {
 195:     this(SwingConstants.VERTICAL, 0, 10, 0, 100);
 196:   }
 197: 
 198:   /**
 199:    * Creates a new JScrollBar object with a minimum of 0, a 
 200:    * maximum of 100, a value of 0, an extent of 10 and the given
 201:    * orientation.
 202:    *
 203:    * @param orientation The orientation of the JScrollBar.
 204:    */
 205:   public JScrollBar(int orientation)
 206:   {
 207:     this(orientation, 0, 10, 0, 100);
 208:   }
 209: 
 210:   /**
 211:    * Creates a new JScrollBar object with the given orientation, 
 212:    * value, min, max, and extent.
 213:    *
 214:    * @param orientation The orientation to use.
 215:    * @param value The value to use.
 216:    * @param extent The extent to use.
 217:    * @param min The minimum value of the scrollbar.
 218:    * @param max The maximum value of the scrollbar.
 219:    */
 220:   public JScrollBar(int orientation, int value, int extent, int min, int max)
 221:   {
 222:     model = new DefaultBoundedRangeModel(value, extent, min, max);
 223:     if (orientation != SwingConstants.HORIZONTAL
 224:         && orientation != SwingConstants.VERTICAL)
 225:       throw new IllegalArgumentException(orientation
 226:                                          + " is not a legal orientation");
 227:     this.orientation = orientation;
 228:     updateUI();
 229:   }
 230: 
 231:   /**
 232:    * This method sets the UI of this scrollbar to
 233:    * the given UI.
 234:    *
 235:    * @param ui The UI to use with this scrollbar.
 236:    */
 237:   public void setUI(ScrollBarUI ui)
 238:   {
 239:     super.setUI(ui);
 240:   }
 241: 
 242:   /**
 243:    * This method returns the UI that is being used
 244:    * with this scrollbar.
 245:    *
 246:    * @return The scrollbar's current UI.
 247:    */
 248:   public ScrollBarUI getUI()
 249:   {
 250:     return (ScrollBarUI) ui;
 251:   }
 252: 
 253:   /**
 254:    * This method changes the UI to be the
 255:    * default for the current look and feel.
 256:    */
 257:   public void updateUI()
 258:   {
 259:     setUI((ScrollBarUI) UIManager.getUI(this));
 260:   }
 261: 
 262:   /**
 263:    * This method returns an identifier to 
 264:    * choose the correct UI delegate for the
 265:    * scrollbar.
 266:    *
 267:    * @return The identifer to choose the UI delegate; "ScrollBarUI"
 268:    */
 269:   public String getUIClassID()
 270:   {
 271:     return "ScrollBarUI";
 272:   }
 273: 
 274:   /**
 275:    * This method returns the orientation of the scrollbar.
 276:    *
 277:    * @return The orientation of the scrollbar.
 278:    */
 279:   public int getOrientation()
 280:   {
 281:     return orientation;
 282:   }
 283: 
 284:   /**
 285:    * This method sets the orientation of the scrollbar.
 286:    *
 287:    * @param orientation The orientation of the scrollbar.
 288:    */
 289:   public void setOrientation(int orientation)
 290:   {
 291:     if (orientation != SwingConstants.HORIZONTAL
 292:         && orientation != SwingConstants.VERTICAL)
 293:       throw new IllegalArgumentException("orientation must be one of HORIZONTAL or VERTICAL");
 294:     if (orientation != this.orientation)
 295:       {
 296:     int oldOrientation = this.orientation;
 297:     this.orientation = orientation;
 298:     firePropertyChange("orientation", oldOrientation,
 299:                        this.orientation);
 300:       }
 301:   }
 302: 
 303:   /**
 304:    * This method returns the model being used with 
 305:    * the scrollbar.
 306:    *
 307:    * @return The scrollbar's model.
 308:    */
 309:   public BoundedRangeModel getModel()
 310:   {
 311:     return model;
 312:   }
 313: 
 314:   /**
 315:    * This method sets the model to use with
 316:    * the scrollbar.
 317:    *
 318:    * @param newModel The new model to use with the scrollbar.
 319:    */
 320:   public void setModel(BoundedRangeModel newModel)
 321:   {
 322:     if (model != newModel)
 323:       {
 324:     BoundedRangeModel oldModel = model;
 325:     model = newModel;
 326:     firePropertyChange("model", oldModel, model);
 327:       }
 328:   }
 329: 
 330:   /**
 331:    * This method returns how much the scrollbar's value
 332:    * should change for a unit increment depending on the 
 333:    * given direction.
 334:    *
 335:    * @param direction The direction to scroll in.
 336:    *
 337:    * @return The amount the scrollbar's value will change given the direction.
 338:    */
 339:   public int getUnitIncrement(int direction)
 340:   {
 341:     return direction * unitIncrement;
 342:   }
 343: 
 344:   /**
 345:    * This method sets the unitIncrement property.
 346:    *
 347:    * @param unitIncrement The new unitIncrement.
 348:    */
 349:   public void setUnitIncrement(int unitIncrement)
 350:   {
 351:     if (unitIncrement != this.unitIncrement)
 352:       {
 353:     int oldInc = this.unitIncrement;
 354:     this.unitIncrement = unitIncrement;
 355:     firePropertyChange("unitIncrement", oldInc,
 356:                        this.unitIncrement);
 357:       }
 358:   }
 359: 
 360:   /**
 361:    * The method returns how much the scrollbar's value
 362:    * should change for a block increment depending on
 363:    * the given direction.
 364:    *
 365:    * @param direction The direction to scroll in.
 366:    *
 367:    * @return The amount the scrollbar's value will change given the direction.
 368:    */
 369:   public int getBlockIncrement(int direction)
 370:   {
 371:     return direction * blockIncrement;
 372:   }
 373: 
 374:   /**
 375:    * This method sets the blockIncrement property.
 376:    *
 377:    * @param blockIncrement The new blockIncrement.
 378:    */
 379:   public void setBlockIncrement(int blockIncrement)
 380:   {
 381:     if (blockIncrement != this.blockIncrement)
 382:       {
 383:     int oldInc = this.blockIncrement;
 384:     this.blockIncrement = blockIncrement;
 385:     firePropertyChange("blockIncrement", oldInc,
 386:                        this.blockIncrement);
 387:       }
 388:   }
 389: 
 390:   /**
 391:    * This method returns the unitIncrement.
 392:    *
 393:    * @return The unitIncrement.
 394:    */
 395:   public int getUnitIncrement()
 396:   {
 397:     return unitIncrement;
 398:   }
 399: 
 400:   /**
 401:    * This method returns the blockIncrement.
 402:    *
 403:    * @return The blockIncrement.
 404:    */
 405:   public int getBlockIncrement()
 406:   {
 407:     return blockIncrement;
 408:   }
 409: 
 410:   /**
 411:    * This method returns the value of the scrollbar.
 412:    *
 413:    * @return The value of the scrollbar.
 414:    */
 415:   public int getValue()
 416:   {
 417:     return model.getValue();
 418:   }
 419: 
 420:   /**
 421:    * This method changes the value of the scrollbar.
 422:    *
 423:    * @param value The new value of the scrollbar.
 424:    */
 425:   public void setValue(int value)
 426:   {
 427:     if (isEnabled() && value != getValue())
 428:     {
 429:       model.setValue(value);
 430:       fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
 431:                                  AdjustmentEvent.TRACK, value);
 432:     }
 433:   }
 434: 
 435:   /**
 436:    * This method returns the visible amount (AKA extent). 
 437:    * The visible amount can be used by UI delegates to 
 438:    * determine the size of the thumb.
 439:    *
 440:    * @return The visible amount (AKA extent).
 441:    */
 442:   public int getVisibleAmount()
 443:   {
 444:     return model.getExtent();
 445:   }
 446: 
 447:   /**
 448:    * This method sets the visible amount (AKA extent).
 449:    *
 450:    * @param extent The visible amount (AKA extent).
 451:    */
 452:   public void setVisibleAmount(int extent)
 453:   {
 454:     if (extent != getVisibleAmount())
 455:     {
 456:       model.setExtent(extent);
 457:       fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
 458:                                  AdjustmentEvent.TRACK, extent);
 459:     }
 460:   }
 461: 
 462:   /**
 463:    * This method returns the minimum value of the scrollbar.
 464:    *
 465:    * @return The minimum value of the scrollbar.
 466:    */
 467:   public int getMinimum()
 468:   {
 469:     return model.getMinimum();
 470:   }
 471: 
 472:   /**
 473:    * This method sets the minimum value of the scrollbar.
 474:    *
 475:    * @param minimum The minimum value of the scrollbar.
 476:    */
 477:   public void setMinimum(int minimum)
 478:   {
 479:     if (minimum != getMinimum())
 480:     {
 481:       model.setMinimum(minimum);
 482:       fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
 483:                                  AdjustmentEvent.TRACK, minimum);
 484:     }
 485:   }
 486: 
 487:   /**
 488:    * This method returns the maximum value of the scrollbar.
 489:    *
 490:    * @return The maximum value of the scrollbar.
 491:    */
 492:   public int getMaximum()
 493:   {
 494:     return model.getMaximum();
 495:   }
 496: 
 497:   /**
 498:    * This method sets the maximum value of the scrollbar.
 499:    *
 500:    * @param maximum The maximum value of the scrollbar.
 501:    */
 502:   public void setMaximum(int maximum)
 503:   {
 504:     if (maximum != getMaximum())
 505:     {
 506:       model.setMaximum(maximum);
 507:       fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
 508:                                  AdjustmentEvent.TRACK, maximum);
 509:     }
 510:   }
 511: 
 512:   /**
 513:    * This method returns the model's isAjusting value.
 514:    *
 515:    * @return The model's isAdjusting value.
 516:    */
 517:   public boolean getValueIsAdjusting()
 518:   {
 519:     return model.getValueIsAdjusting();
 520:   }
 521: 
 522:   /**
 523:    * This method sets the model's isAdjusting value.
 524:    *
 525:    * @param b The new isAdjusting value.
 526:    */
 527:   public void setValueIsAdjusting(boolean b)
 528:   {
 529:     model.setValueIsAdjusting(b);
 530:   }
 531: 
 532:   /**
 533:    * This method sets the value, extent, minimum and 
 534:    * maximum.
 535:    *
 536:    * @param newValue The new value.
 537:    * @param newExtent The new extent.
 538:    * @param newMin The new minimum.
 539:    * @param newMax The new maximum.
 540:    */
 541:   public void setValues(int newValue, int newExtent, int newMin, int newMax)
 542:   {
 543:     if (!isEnabled())
 544:       newValue = model.getValue();
 545:     // It seems to be that on any change the value is fired.
 546:     if (newValue != getValue() || newExtent != getVisibleAmount() ||
 547:         newMin != getMinimum() || newMax != getMaximum())
 548:     {
 549:       model.setRangeProperties(newValue, newExtent, newMin, newMax,
 550:                                model.getValueIsAdjusting());
 551:       fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
 552:                                  AdjustmentEvent.TRACK, newValue);
 553:     }
 554:   }
 555: 
 556:   /**
 557:    * This method adds an AdjustmentListener to the scroll bar.
 558:    *
 559:    * @param listener The listener to add.
 560:    */
 561:   public void addAdjustmentListener(AdjustmentListener listener)
 562:   {
 563:     listenerList.add(AdjustmentListener.class, listener);
 564:   }
 565: 
 566:   /**
 567:    * This method removes an AdjustmentListener from the scroll bar. 
 568:    *
 569:    * @param listener The listener to remove.
 570:    */
 571:   public void removeAdjustmentListener(AdjustmentListener listener)
 572:   {
 573:     listenerList.remove(AdjustmentListener.class, listener);
 574:   }
 575: 
 576:   /**
 577:    * This method returns an arry of all AdjustmentListeners listening to 
 578:    * this scroll bar.
 579:    *
 580:    * @return An array of AdjustmentListeners listening to this scroll bar.
 581:    */
 582:   public AdjustmentListener[] getAdjustmentListeners()
 583:   {
 584:     return (AdjustmentListener[]) listenerList.getListeners(AdjustmentListener.class);
 585:   }
 586: 
 587:   /**
 588:    * This method is called to fired AdjustmentEvents to the listeners
 589:    * of this scroll bar. All AdjustmentEvents that are fired
 590:    * will have an ID of ADJUSTMENT_VALUE_CHANGED and a type of
 591:    * TRACK. 
 592:    *
 593:    * @param id The ID of the adjustment event.
 594:    * @param type The Type of change.
 595:    * @param value The new value for the property that was changed..
 596:    */
 597:   protected void fireAdjustmentValueChanged(int id, int type, int value)
 598:   {
 599:     Object[] adjustmentListeners = listenerList.getListenerList();
 600:     AdjustmentEvent adjustmentEvent = new AdjustmentEvent(this, 
 601:                                             AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
 602:                         AdjustmentEvent.TRACK,
 603:                         value);
 604:     for (int i = adjustmentListeners.length - 2; i >= 0; i -= 2)
 605:       {
 606:     if (adjustmentListeners[i] == AdjustmentListener.class)
 607:       ((AdjustmentListener) adjustmentListeners[i + 1]).adjustmentValueChanged(adjustmentEvent);
 608:       }
 609:   }
 610: 
 611:   /**
 612:    * This method returns the minimum size for this scroll bar.
 613:    *
 614:    * @return The minimum size.
 615:    */
 616:   public Dimension getMinimumSize()
 617:   {
 618:     return ui.getMinimumSize(this);
 619:   }
 620: 
 621:   /**
 622:    * This method returns the maximum size for this scroll bar.
 623:    *
 624:    * @return The maximum size.
 625:    */
 626:   public Dimension getMaximumSize()
 627:   {
 628:     return ui.getMaximumSize(this);
 629:   }
 630: 
 631:   /**
 632:    * This method overrides the setEnabled in JComponent.
 633:    * When the scroll bar is disabled, the knob cannot
 634:    * be moved.
 635:    *
 636:    * @param x Whether the scrollbar is enabled.
 637:    */
 638:   public void setEnabled(boolean x)
 639:   {
 640:     // nothing special needs to be done here since we 
 641:     // just check the enabled setting before changing the value.
 642:     super.setEnabled(x);
 643:   }
 644: 
 645:   /**
 646:    * Returns a string describing the attributes for the <code>JScrollBar</code>
 647:    * component, for use in debugging.  The return value is guaranteed to be 
 648:    * non-<code>null</code>, but the format of the string may vary between
 649:    * implementations.
 650:    *
 651:    * @return A string describing the attributes of the <code>JScrollBar</code>.
 652:    */
 653:   protected String paramString()
 654:   {
 655:     StringBuffer sb = new StringBuffer(super.paramString());
 656:     sb.append(",blockIncrement=").append(blockIncrement);
 657:     sb.append(",orientation=");
 658:     if (this.orientation == JScrollBar.HORIZONTAL)
 659:       sb.append("HORIZONTAL");
 660:     else 
 661:       sb.append("VERTICAL");
 662:     sb.append(",unitIncrement=").append(unitIncrement);
 663:     return sb.toString();
 664:   }
 665: 
 666:   /**
 667:    * Returns the object that provides accessibility features for this
 668:    * <code>JScrollBar</code> component.
 669:    *
 670:    * @return The accessible context (an instance of 
 671:    *     {@link AccessibleJScrollBar}).
 672:    */
 673:   public AccessibleContext getAccessibleContext()
 674:   {
 675:     if (accessibleContext == null)
 676:       accessibleContext = new AccessibleJScrollBar();
 677:     return accessibleContext;
 678:   }
 679: }