1 /* Scrollbar.java -- AWT Scrollbar widget
2 Copyright (C) 1999, 2000, 2001, 2002, 2003 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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 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 java.awt;
40
41 import java.awt.event.AdjustmentListener;
42 import java.awt.event.AdjustmentEvent;
43 import java.awt.peer.ScrollbarPeer;
44 import java.util.EventListener;
45 import javax.accessibility.Accessible;
46
47 /**
48 * This class implements a scrollbar widget.
49 *
50 * @author Aaron M. Renn (arenn@urbanophile.com)
51 * @author Tom Tromey <tromey@cygnus.com>
52 */
53 public class Scrollbar extends Component implements Accessible,
54 Adjustable
55 {
56
57 // FIXME: Serialization readObject/writeObject
58
59 /*
60 * Static Variables
61 */
62
63 /**
64 * Constant indicating that a scrollbar is horizontal.
65 */
66 public static final int HORIZONTAL = 0;
67
68 /**
69 * Constant indicating that a scrollbar is vertical.
70 */
71 public static final int VERTICAL = 1;
72
73 // Serialization Constant
74 private static final long serialVersionUID = 8451667562882310543L;
75
76 /*************************************************************************/
77
78 /**
79 * @serial The amount by which the value of the scrollbar is changed
80 * when incrementing in line mode.
81 */
82 private int lineIncrement;
83
84 /**
85 * @serial The amount by which the value of the scrollbar is changed
86 * when incrementing in page mode.
87 */
88 private int pageIncrement;
89
90 /**
91 * @serial The maximum value for this scrollbar
92 */
93 private int maximum;
94
95 /**
96 * @serial The minimum value for this scrollbar
97 */
98 private int minimum;
99
100 /**
101 * @serial The orientation of this scrollbar, which will be either
102 * the <code>HORIZONTAL</code> or <code>VERTICAL</code> constant
103 * from this class.
104 */
105 private int orientation;
106
107 /**
108 * @serial The current value of this scrollbar.
109 */
110 private int value;
111
112 /**
113 * @serial The width of the scrollbar's thumb, which is relative
114 * to the minimum and maximum value of the scrollbar.
115 */
116 private int visibleAmount;
117
118 // List of AdjustmentListener's.
119 private AdjustmentListener adjustment_listeners;
120
121 private transient boolean valueIsAdjusting = false;
122
123 /*************************************************************************/
124
125 /*
126 * Constructors
127 */
128
129 /**
130 * Initializes a new instance of <code>Scrollbar</code> with a
131 * vertical orientation and default values for all other parameters.
132 *
133 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
134 */
135 public
Scrollbar()136 Scrollbar()
137 {
138 this(VERTICAL);
139 }
140
141 /*************************************************************************/
142
143 /**
144 * Initializes a new instance of <code>Scrollbar</code> with the
145 * specified orientation and default values for all other parameters.
146 * The orientation must be either the constant <code>HORIZONTAL</code> or
147 * <code>VERTICAL</code> from this class. An incorrect value will throw
148 * an exception.
149 *
150 * @param orientation The orientation of this scrollbar.
151 *
152 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
153 * @exception IllegalArgumentException If the orientation value is not valid.
154 */
155 public
Scrollbar(int orientation)156 Scrollbar(int orientation) throws IllegalArgumentException
157 {
158 this(orientation, 0, 10, 0, 100);
159 }
160
161 /*************************************************************************/
162
163 /**
164 * Initializes a new instance of <code>Scrollbar</code> with the
165 * specified parameters. The orientation must be either the constant
166 * <code>HORIZONTAL</code> or <code>VERTICAL</code>. An incorrect value
167 * will throw an exception. Inconsistent values for other parameters
168 * are silently corrected to valid values.
169 *
170 * @param orientation The orientation of this scrollbar.
171 * @param value The initial value of the scrollbar.
172 * @param visibleAmount The width of the scrollbar thumb.
173 * @param minimum The minimum value of the scrollbar.
174 * @param maximum The maximum value of the scrollbar.
175 *
176 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
177 * @exception IllegalArgumentException If the orientation value is not valid.
178 */
179 public
Scrollbar(int orientation, int value, int visibleAmount, int minimum, int maximum)180 Scrollbar(int orientation, int value, int visibleAmount, int minimum,
181 int maximum) throws IllegalArgumentException
182 {
183 if (GraphicsEnvironment.isHeadless())
184 throw new HeadlessException ();
185
186 if ((orientation != HORIZONTAL) && (orientation != VERTICAL))
187 throw new IllegalArgumentException("Bad orientation value: "
188 + orientation);
189
190 this.orientation = orientation;
191
192 setValues(value, visibleAmount, minimum, maximum);
193
194 // Default is 1 according to online docs.
195 lineIncrement = 1;
196
197 pageIncrement = (maximum - minimum) / 5;
198 if (pageIncrement == 0)
199 pageIncrement = 1;
200 }
201
202 /*************************************************************************/
203
204 /*
205 * Instance Methods
206 */
207
208 /**
209 * Returns the orientation constant for this object.
210 *
211 * @return The orientation constant for this object.
212 */
213 public int
getOrientation()214 getOrientation()
215 {
216 return(orientation);
217 }
218
219 /*************************************************************************/
220
221 /**
222 * Sets the orientation of this scrollbar to the specified value. This
223 * value must be either the constant <code>HORIZONTAL</code> or
224 * <code>VERTICAL</code> from this class or an exception will be thrown.
225 *
226 * @param orientation The new orientation value.
227 *
228 * @exception IllegalArgumentException If the orientation value is not valid.
229 */
230 public void
setOrientation(int orientation)231 setOrientation(int orientation)
232 {
233 if ((orientation != HORIZONTAL) && (orientation != VERTICAL))
234 throw new IllegalArgumentException("Bad orientation value: "
235 + orientation);
236
237 // FIXME: Communicate to peer? Or must this be called before peer creation?
238 this.orientation = orientation;
239 }
240
241 /*************************************************************************/
242
243 /**
244 * Returns the current value for this scrollbar.
245 *
246 * @return The current value for this scrollbar.
247 */
248 public int
getValue()249 getValue()
250 {
251 return(value);
252 }
253
254 /*************************************************************************/
255
256 /**
257 * Sets the current value for this scrollbar to the specified value.
258 * If this is inconsistent with the minimum and maximum values for this
259 * scrollbar, the value is silently adjusted.
260 *
261 * @param value The new value for this scrollbar.
262 */
263 public void
setValue(int value)264 setValue(int value)
265 {
266 setValues(value, visibleAmount, minimum, maximum);
267 }
268
269 /*************************************************************************/
270
271 /**
272 * Returns the maximum value for this scrollbar.
273 *
274 * @return The maximum value for this scrollbar.
275 */
276 public int
getMaximum()277 getMaximum()
278 {
279 return(maximum);
280 }
281
282 /*************************************************************************/
283
284 /**
285 * Sets the maximum value for this scrollbar to the specified value.
286 * If the value is less than the current minimum value, it is silent
287 * set to equal the minimum value.
288 *
289 * @param maximum The new maximum value for this scrollbar.
290 */
291 public void
setMaximum(int maximum)292 setMaximum(int maximum)
293 {
294 setValues(value, visibleAmount, minimum, maximum);
295 }
296
297 /*************************************************************************/
298
299 /**
300 * Returns the minimum value for this scrollbar.
301 *
302 * @return The minimum value for this scrollbar.
303 */
304 public int
getMinimum()305 getMinimum()
306 {
307 return(minimum);
308 }
309
310 /*************************************************************************/
311
312 /**
313 * Sets the minimum value for this scrollbar to the specified value. If
314 * this is not consistent with the current value and maximum, it is
315 * silently adjusted to be consistent.
316 *
317 * @param minimum The new minimum value for this scrollbar.
318 */
319 public void
setMinimum(int minimum)320 setMinimum(int minimum)
321 {
322 setValues(value, visibleAmount, minimum, maximum);
323 }
324
325 /*************************************************************************/
326
327 /**
328 * Returns the width of the scrollbar's thumb, in units relative to the
329 * maximum and minimum value of the scrollbar.
330 *
331 * @return The width of the scrollbar's thumb.
332 */
333 public int
getVisibleAmount()334 getVisibleAmount()
335 {
336 return(visibleAmount);
337 }
338
339 /*************************************************************************/
340
341 /**
342 * Returns the width of the scrollbar's thumb, in units relative to the
343 * maximum and minimum value of the scrollbar.
344 *
345 * @return The width of the scrollbar's thumb.
346 *
347 * @deprecated This method is deprecated in favor of
348 * <code>getVisibleAmount()</code>.
349 */
350 public int
getVisible()351 getVisible()
352 {
353 return(getVisibleAmount());
354 }
355
356 /*************************************************************************/
357
358 /**
359 * Sets the width of the scrollbar's thumb, in units relative to the
360 * maximum and minimum value of the scrollbar.
361 *
362 * @param visibileAmount The new visible amount value of the scrollbar.
363 */
364 public void
setVisibleAmount(int visibleAmount)365 setVisibleAmount(int visibleAmount)
366 {
367 setValues(value, visibleAmount, minimum, maximum);
368 }
369
370 /*************************************************************************/
371
372 /**
373 * Sets the current value, visible amount, minimum, and maximum for this
374 * scrollbar. These values are adjusted to be internally consistent
375 * if necessary.
376 *
377 * @param value The new value for this scrollbar.
378 * @param visibleAmount The new visible amount for this scrollbar.
379 * @param minimum The new minimum value for this scrollbar.
380 * @param maximum The new maximum value for this scrollbar.
381 */
382 public synchronized void
setValues(int value, int visibleAmount, int minimum, int maximum)383 setValues(int value, int visibleAmount, int minimum, int maximum)
384 {
385 if (maximum < minimum)
386 maximum = minimum;
387
388 if (value < minimum)
389 value = minimum;
390
391 if (value > maximum)
392 value = maximum;
393
394 if (visibleAmount > maximum - minimum)
395 visibleAmount = maximum - minimum;
396
397 this.value = value;
398 this.visibleAmount = visibleAmount;
399 this.minimum = minimum;
400 this.maximum = maximum;
401
402 ScrollbarPeer sp = (ScrollbarPeer)getPeer();
403 if (sp != null)
404 sp.setValues(value, visibleAmount, minimum, maximum);
405
406 int range = maximum - minimum;
407 if (lineIncrement > range)
408 {
409 if (range == 0)
410 lineIncrement = 1;
411 else
412 lineIncrement = range;
413
414 if (sp != null)
415 sp.setLineIncrement(lineIncrement);
416 }
417
418 if (pageIncrement > range)
419 {
420 if (range == 0)
421 pageIncrement = 1;
422 else
423 pageIncrement = range;
424
425 if (sp != null)
426 sp.setPageIncrement(pageIncrement);
427 }
428 }
429
430 /*************************************************************************/
431
432 /**
433 * Returns the value added or subtracted when the user activates the scrollbar
434 * scroll by a "unit" amount.
435 *
436 * @return The unit increment value.
437 */
438 public int
getUnitIncrement()439 getUnitIncrement()
440 {
441 return(lineIncrement);
442 }
443
444 /*************************************************************************/
445
446 /**
447 * Returns the value added or subtracted when the user selects the scrollbar
448 * scroll by a "unit" amount control.
449 *
450 * @return The unit increment value.
451 *
452 * @deprecated This method is deprecated in favor of
453 * <code>getUnitIncrement()</code>.
454 */
455 public int
getLineIncrement()456 getLineIncrement()
457 {
458 return(lineIncrement);
459 }
460
461 /*************************************************************************/
462
463 /**
464 * Sets the value added or subtracted to the scrollbar value when the
465 * user selects the scroll by a "unit" amount control.
466 *
467 * @param unitIncrement The new unit increment amount.
468 */
469 public synchronized void
setUnitIncrement(int unitIncrement)470 setUnitIncrement(int unitIncrement)
471 {
472 if (unitIncrement < 0)
473 throw new IllegalArgumentException("Unit increment less than zero.");
474
475 int range = maximum - minimum;
476 if (unitIncrement > range)
477 {
478 if (range == 0)
479 unitIncrement = 1;
480 else
481 unitIncrement = range;
482 }
483
484 if (unitIncrement == lineIncrement)
485 return;
486
487 lineIncrement = unitIncrement;
488
489 ScrollbarPeer sp = (ScrollbarPeer)getPeer();
490 if (sp != null)
491 sp.setLineIncrement(lineIncrement);
492 }
493
494 /*************************************************************************/
495
496 /**
497 * Sets the value added or subtracted to the scrollbar value when the
498 * user selects the scroll by a "unit" amount control.
499 *
500 * @param lineIncrement The new unit increment amount.
501 *
502 * @deprecated This method is deprecated in favor of
503 * <code>setUnitIncrement()</code>.
504 */
505 public void
setLineIncrement(int lineIncrement)506 setLineIncrement(int lineIncrement)
507 {
508 setUnitIncrement(lineIncrement);
509 }
510
511 /*************************************************************************/
512
513 /**
514 * Returns the value added or subtracted when the user activates the scrollbar
515 * scroll by a "block" amount.
516 *
517 * @return The block increment value.
518 */
519 public int
getBlockIncrement()520 getBlockIncrement()
521 {
522 return(pageIncrement);
523 }
524
525 /*************************************************************************/
526
527 /**
528 * Returns the value added or subtracted when the user selects the scrollbar
529 * scroll by a "block" amount control.
530 *
531 * @return The block increment value.
532 *
533 * @deprecated This method is deprecated in favor of
534 * <code>getBlockIncrement()</code>.
535 */
536 public int
getPageIncrement()537 getPageIncrement()
538 {
539 return(pageIncrement);
540 }
541
542 /*************************************************************************/
543
544 /**
545 * Sets the value added or subtracted to the scrollbar value when the
546 * user selects the scroll by a "block" amount control.
547 *
548 * @param blockIncrement The new block increment amount.
549 */
550 public synchronized void
setBlockIncrement(int blockIncrement)551 setBlockIncrement(int blockIncrement)
552 {
553 if (blockIncrement < 0)
554 throw new IllegalArgumentException("Block increment less than zero.");
555
556 int range = maximum - minimum;
557 if (blockIncrement > range)
558 {
559 if (range == 0)
560 blockIncrement = 1;
561 else
562 blockIncrement = range;
563 }
564
565 if (blockIncrement == pageIncrement)
566 return;
567
568 pageIncrement = blockIncrement;
569
570 ScrollbarPeer sp = (ScrollbarPeer)getPeer();
571 if (sp != null)
572 sp.setPageIncrement(pageIncrement);
573 }
574
575 /*************************************************************************/
576
577 /**
578 * Sets the value added or subtracted to the scrollbar value when the
579 * user selects the scroll by a "block" amount control.
580 *
581 * @param pageIncrement The new block increment amount.
582 *
583 * @deprecated This method is deprecated in favor of
584 * <code>setBlockIncrement()</code>.
585 */
586 public void
setPageIncrement(int pageIncrement)587 setPageIncrement(int pageIncrement)
588 {
589 setBlockIncrement(pageIncrement);
590 }
591
592 /*************************************************************************/
593
594 /**
595 * Notifies this object to create its native peer.
596 */
597 public synchronized void
addNotify()598 addNotify()
599 {
600 if (peer == null)
601 peer = getToolkit ().createScrollbar (this);
602 super.addNotify ();
603 }
604
605 /*************************************************************************/
606
607 /**
608 * Adds a new adjustment listener to the list of registered listeners
609 * for this object.
610 *
611 * @param listener The listener to add.
612 */
613 public synchronized void
addAdjustmentListener(AdjustmentListener listener)614 addAdjustmentListener(AdjustmentListener listener)
615 {
616 adjustment_listeners = AWTEventMulticaster.add(adjustment_listeners, listener);
617 enableEvents(AWTEvent.ADJUSTMENT_EVENT_MASK);
618 }
619
620 /*************************************************************************/
621
622 /**
623 * Removes the specified listener from the list of registered listeners
624 * for this object.
625 *
626 * @param listener The listener to remove.
627 */
628 public synchronized void
removeAdjustmentListener(AdjustmentListener listener)629 removeAdjustmentListener(AdjustmentListener listener)
630 {
631 adjustment_listeners = AWTEventMulticaster.remove(adjustment_listeners,
632 listener);
633 }
634
635 /*************************************************************************/
636
637 /**
638 * Processes events for this scrollbar. It does this by calling
639 * <code>processAdjustmentEvent()</code> if the event is an instance of
640 * <code>AdjustmentEvent</code>, otherwise it calls the superclass to
641 * process the event.
642 *
643 * @param event The event to process.
644 */
645 protected void
processEvent(AWTEvent event)646 processEvent(AWTEvent event)
647 {
648 if (event instanceof AdjustmentEvent)
649 processAdjustmentEvent((AdjustmentEvent)event);
650 else
651 super.processEvent(event);
652 }
653
654 /*************************************************************************/
655
656 /**
657 * Processes adjustment events for this object by dispatching them to
658 * any registered listeners. Note that this method will only be called
659 * if adjustment events are enabled. This will happen automatically if
660 * any listeners are registered. Otherwise, it can be enabled by a
661 * call to <code>enableEvents()</code>.
662 *
663 * @param event The event to process.
664 */
665 protected void
processAdjustmentEvent(AdjustmentEvent event)666 processAdjustmentEvent(AdjustmentEvent event)
667 {
668 value = event.getValue();
669 if (adjustment_listeners != null)
670 adjustment_listeners.adjustmentValueChanged(event);
671 }
672
673 void
dispatchEventImpl(AWTEvent e)674 dispatchEventImpl(AWTEvent e)
675 {
676 if (e.id <= AdjustmentEvent.ADJUSTMENT_LAST
677 && e.id >= AdjustmentEvent.ADJUSTMENT_FIRST
678 && (adjustment_listeners != null
679 || (eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0))
680 processEvent(e);
681 else
682 super.dispatchEventImpl(e);
683 }
684
685 /*************************************************************************/
686
687 /**
688 * Returns a debugging string for this object.
689 *
690 * @return A debugging string for this object.
691 */
692 protected String
paramString()693 paramString()
694 {
695 return("value=" + getValue() + ",visibleAmount=" +
696 getVisibleAmount() + ",minimum=" + getMinimum()
697 + ",maximum=" + getMaximum()
698 + ",pageIncrement=" + pageIncrement
699 + ",lineIncrement=" + lineIncrement
700 + ",orientation=" + (orientation == HORIZONTAL
701 ? "HORIZONTAL" : "VERTICAL")
702 + super.paramString());
703 }
704
705 /**
706 * Returns an array of all the objects currently registered as FooListeners
707 * upon this <code>Scrollbar</code>. FooListeners are registered using the
708 * addFooListener method.
709 *
710 * @exception ClassCastException If listenerType doesn't specify a class or
711 * interface that implements java.util.EventListener.
712 */
getListeners(Class listenerType)713 public EventListener[] getListeners (Class listenerType)
714 {
715 if (listenerType == AdjustmentListener.class)
716 return AWTEventMulticaster.getListeners (adjustment_listeners,
717 listenerType);
718
719 return super.getListeners (listenerType);
720 }
721
722 /**
723 * Returns an array of all registered adjustment listeners.
724 */
getAdjustmentListeners()725 public AdjustmentListener[] getAdjustmentListeners ()
726 {
727 return (AdjustmentListener[]) getListeners (AdjustmentListener.class);
728 }
729
730 /**
731 * Returns true if the value is in the process of changing.
732 *
733 * @since 1.4
734 */
getValueIsAdjusting()735 public boolean getValueIsAdjusting ()
736 {
737 return valueIsAdjusting;
738 }
739
740 /**
741 * Sets the value of valueIsAdjusting.
742 *
743 * @since 1.4
744 */
setValueIsAdjusting(boolean valueIsAdjusting)745 public void setValueIsAdjusting (boolean valueIsAdjusting)
746 {
747 this.valueIsAdjusting = valueIsAdjusting;
748 }
749 } // class Scrollbar
750
751