001: /*
002: * @(#)ScrollPane.java 1.78 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027: package java.awt;
028:
029: import sun.awt.peer.ScrollPanePeer;
030: import sun.awt.PeerBasedToolkit;
031: import java.awt.event.*;
032: import java.io.Serializable;
033: import java.io.ObjectInputStream;
034: import java.io.ObjectOutputStream;
035: import java.io.IOException;
036: import sun.awt.ScrollPaneWheelScroller;
037:
038: /**
039: * A container class which implements automatic horizontal and/or
040: * vertical scrolling for a single child component. The display
041: * policy for the scrollbars can be set to:
042: * <OL>
043: * <LI>as needed: scrollbars created and shown only when needed by scrollpane
044: * <LI>always: scrollbars created and always shown by the scrollpane
045: * <LI>never: scrollbars never created or shown by the scrollpane
046: * </OL>
047: * <P>
048: * The state of the horizontal and vertical scrollbars is represented
049: * by two objects (one for each dimension) which implement the
050: * Adjustable interface. The API provides methods to access those
051: * objects such that the attributes on the Adjustable object (such as unitIncrement,
052: * value, etc.) can be manipulated.
053: * <P>
054: * Certain adjustable properties (minimum, maximum, blockIncrement,
055: * and visibleAmount) are set internally by the scrollpane in accordance
056: * with the geometry of the scrollpane and its child and these should
057: * not be set by programs using the scrollpane.
058: * <P>
059: * If the scrollbar display policy is defined as "never", then the
060: * scrollpane can still be programmatically scrolled using the
061: * setScrollPosition() method and the scrollpane will move and clip
062: * the child's contents appropriately. This policy is useful if the
063: * program needs to create and manage its own adjustable controls.
064: * <P>
065: * The placement of the scrollbars is controlled by platform-specific
066: * properties set by the user outside of the program.
067: * <P>
068: * The initial size of this container is set to 100x100, but can
069: * be reset using setSize().
070: * <P>
071: * Insets are used to define any space used by scrollbars and any
072: * borders created by the scroll pane. getInsets() can be used
073: * to get the current value for the insets. If the value of
074: * scrollbarsAlwaysVisible is false, then the value of the insets
075: * will change dynamically depending on whether the scrollbars are
076: * currently visible or not.
077: *
078: * @version 1.71 08/19/02
079: * @author Tom Ball
080: * @author Amy Fowler
081: * @author Tim Prinzing
082: */
083: public class ScrollPane extends Container {
084: /**
085: * Specifies that horizontal/vertical scrollbar should be shown
086: * only when the size of the child exceeds the size of the scrollpane
087: * in the horizontal/vertical dimension.
088: */
089: public static final int SCROLLBARS_AS_NEEDED = 0;
090: /**
091: * Specifies that horizontal/vertical scrollbars should always be
092: * shown regardless of the respective sizes of the scrollpane and child.
093: */
094: public static final int SCROLLBARS_ALWAYS = 1;
095: /**
096: * Specifies that horizontal/vertical scrollbars should never be shown
097: * regardless of the respective sizes of the scrollpane and child.
098: */
099: public static final int SCROLLBARS_NEVER = 2;
100: /**
101: * There are 3 ways in which a scroll bar can be displayed.
102: * This integer will represent one of these 3 displays -
103: * (SCROLLBARS_ALWAYS, SCROLLBARS_AS_NEEDED, SCROLLBARS_NEVER)
104: *
105: * @serial
106: * @see getScrollbarDisplayPolicy()
107: */
108: private int scrollbarDisplayPolicy;
109: // ### Serialization problem -- Scrollpane adjustable is package private.
110:
111: /**
112: * An adjustable Vertical Scrollbar.
113: * It is important to not that you must NOT call 3 Adjustable methods
114: * ie : setMinimum(), setMaximum(), setVisibleAmount().
115: *
116: * @serial
117: * @see getVAdjustable()
118: * @see java.awt.Adjustable
119: */
120: private transient ScrollPaneAdjustable vAdjustable;
121: /**
122: * An adjustable Horizontal Scrollbar.
123: * It is important to not that you must NOT call 3 Adjustable method
124: * ie : setMinimum(), setMaximum(), setVisibleAmount().
125: *
126: * @serial
127: * @see getHAdjustable()
128: * @see java.awt.Adjustable
129: */
130: private transient ScrollPaneAdjustable hAdjustable;
131: private static final String base = "scrollpane";
132: private static int nameCounter = 0;
133: private static final boolean defaultWheelScroll = true;
134:
135: /**
136: * Indicates whether or not scrolling should take place when a
137: * MouseWheelEvent is received.
138: *
139: * @serial
140: * @since 1.4
141: */
142: private boolean wheelScrollingEnabled = defaultWheelScroll;
143: /*
144: * JDK 1.1 serialVersionUID
145: */
146: private static final long serialVersionUID = 7956609840827222915L;
147:
148: /**
149: * Create a new scrollpane container with a scrollbar display policy of
150: * "as needed".
151: */
152: public ScrollPane() {
153: this (SCROLLBARS_AS_NEEDED);
154: }
155:
156: /**
157: * Create a new scrollpane container.
158: * @param scrollbarDisplayPolicy policy for when scrollbars should be shown
159: */
160: public ScrollPane(int scrollbarDisplayPolicy) {
161: this .layoutMgr = null;
162: this .width = 100;
163: this .height = 100;
164: switch (scrollbarDisplayPolicy) {
165: case SCROLLBARS_NEVER:
166: case SCROLLBARS_AS_NEEDED:
167: case SCROLLBARS_ALWAYS:
168: this .scrollbarDisplayPolicy = scrollbarDisplayPolicy;
169: break;
170:
171: default:
172: throw new IllegalArgumentException(
173: "illegal scrollbar display policy");
174: }
175: vAdjustable = new ScrollPaneAdjustable(this ,
176: Adjustable.VERTICAL);
177: hAdjustable = new ScrollPaneAdjustable(this ,
178: Adjustable.HORIZONTAL);
179: }
180:
181: /**
182: * Construct a name for this component. Called by getName() when the
183: * name is null.
184: */
185: String constructComponentName() {
186: return base + nameCounter++;
187: }
188:
189: /**
190: * Adds the specified component to this scroll pane container.
191: * If the scroll pane has an existing child component, that
192: * component is removed and the new one is added.
193: * @param comp the component to be added
194: * @param constraints not applicable
195: * @param index position of child component (must be <= 0)
196: */
197: protected final void addImpl(Component comp, Object constraints,
198: int index) {
199: synchronized (getTreeLock()) {
200: if (getComponentCount() > 0) {
201: remove(0);
202: }
203: if (index > 0) {
204: throw new IllegalArgumentException(
205: "position greater than 0");
206: }
207: super .addImpl(comp, constraints, index);
208: }
209: }
210:
211: /**
212: * Returns the display policy for the scrollbars.
213: * @return the display policy for the scrollbars
214: */
215: public int getScrollbarDisplayPolicy() {
216: return scrollbarDisplayPolicy;
217: }
218:
219: /**
220: * Returns the current size of the scroll pane's view port.
221: * @return the size of the view port in pixels
222: */
223: public Dimension getViewportSize() {
224: Insets i = getInsets();
225: return new Dimension(width - i.right - i.left, height - i.top
226: - i.bottom);
227: }
228:
229: /**
230: * Returns the height that would be occupied by a horizontal
231: * scrollbar, which is independent of whether it is currently
232: * displayed by the scroll pane or not.
233: * @return the height of a horizontal scrollbar in pixels
234: */
235: public int getHScrollbarHeight() {
236: int h = 0;
237: if (scrollbarDisplayPolicy != SCROLLBARS_NEVER) {
238: ScrollPanePeer peer = (ScrollPanePeer) this .peer;
239: if (peer != null) {
240: h = peer.getHScrollbarHeight();
241: }
242: }
243: return h;
244: }
245:
246: /**
247: * Returns the width that would be occupied by a vertical
248: * scrollbar, which is independent of whether it is currently
249: * displayed by the scroll pane or not.
250: * @return the width of a vertical scrollbar in pixels
251: */
252: public int getVScrollbarWidth() {
253: int w = 0;
254: if (scrollbarDisplayPolicy != SCROLLBARS_NEVER) {
255: ScrollPanePeer peer = (ScrollPanePeer) this .peer;
256: if (peer != null) {
257: w = peer.getVScrollbarWidth();
258: }
259: }
260: return w;
261: }
262:
263: /**
264: * Returns the Adjustable object which represents the state of
265: * the vertical scrollbar.
266: */
267: public Adjustable getVAdjustable() {
268: return vAdjustable;
269: }
270:
271: /**
272: * Returns the Adjustable object which represents the state of
273: * the horizontal scrollbar.
274: */
275: public Adjustable getHAdjustable() {
276: return hAdjustable;
277: }
278:
279: /**
280: * Scrolls to the specified position within the child component.
281: * A call to this method is only valid if the scroll pane contains
282: * a child. Specifying a position outside of the legal scrolling bounds
283: * of the child will scroll to the closest legal position.
284: * Legal bounds are defined to be the rectangle:
285: * x = 0, y = 0, width = (child width - view port width),
286: * height = (child height - view port height).
287: * This is a convenience method which interfaces with the Adjustable
288: * objects which represent the state of the scrollbars.
289: * @param x the x position to scroll to
290: * @param y the y position to scroll to
291: */
292: public void setScrollPosition(int x, int y) {
293: synchronized (getTreeLock()) {
294: if (ncomponents <= 0) {
295: throw new NullPointerException("child is null");
296: }
297: hAdjustable.setValue(x);
298: vAdjustable.setValue(y);
299: }
300: }
301:
302: /**
303: * Scrolls to the specified position within the child component.
304: * A call to this method is only valid if the scroll pane contains
305: * a child and the specified position is within legal scrolling bounds
306: * of the child. Specifying a position outside of the legal scrolling
307: * bounds of the child will scroll to the closest legal position.
308: * Legal bounds are defined to be the rectangle:
309: * x = 0, y = 0, width = (child width - view port width),
310: * height = (child height - view port height).
311: * This is a convenience method which interfaces with the Adjustable
312: * objects which represent the state of the scrollbars.
313: * @param p the Point representing the position to scroll to
314: */
315: public void setScrollPosition(Point p) {
316: setScrollPosition(p.x, p.y);
317: }
318:
319: /**
320: * Returns the current x,y position within the child which is displayed
321: * at the 0,0 location of the scrolled panel's view port.
322: * This is a convenience method which interfaces with the adjustable
323: * objects which represent the state of the scrollbars.
324: * @return the coordinate position for the current scroll position
325: */
326: public Point getScrollPosition() {
327: if (ncomponents <= 0) {
328: throw new NullPointerException("child is null");
329: }
330: return new Point(hAdjustable.getValue(), vAdjustable.getValue());
331: }
332:
333: /**
334: * Sets the layout manager for this container. This method is
335: * overridden to prevent the layout mgr from being set.
336: * @param mgr the specified layout manager
337: */
338: public final void setLayout(LayoutManager mgr) {
339: throw new AWTError("ScrollPane controls layout");
340: }
341:
342: /**
343: * @deprecated As of JDK version 1.1,
344: * replaced by <code>doLayout()</code>.
345: */
346: public void layout() {
347: if (ncomponents > 0) {
348: Component c = getComponent(0);
349: Point p = getScrollPosition();
350: Dimension cs = calculateChildSize(c);
351: Dimension vs = getViewportSize();
352: Insets i = getInsets();
353: c.setBounds(i.left - p.x, i.top - p.y, cs.width, cs.height);
354: ScrollPanePeer peer = (ScrollPanePeer) this .peer;
355: if (peer != null) {
356: peer.childResized(cs.width, cs.height);
357: }
358: // update adjustables... the viewport size may have changed
359: // with the scrollbars coming or going so the viewport size
360: // is updated before the adjustables.
361: vs = getViewportSize();
362: hAdjustable.setSpan(0, cs.width, vs.width);
363: vAdjustable.setSpan(0, cs.height, vs.height);
364: }
365: }
366:
367: /**
368: * Determine the size to allocate the child component.
369: * If the viewport area is bigger than the childs
370: * preferred size then the child is allocated enough
371: * to fill the viewport, otherwise the child is given
372: * it's preferred size.
373: */
374: Dimension calculateChildSize(Component child) {
375: // calculate the view size, accounting for border but not scrollbars
376: // - don't use right/bottom insets since they vary depending
377: // on whether or not scrollbars were displayed on last resize
378:
379: Insets insets = getInsets();
380: int viewWidth = width - insets.left * 2;
381: int viewHeight = height - insets.top * 2;
382: // determine whether or not horz or vert scrollbars will be displayed
383:
384: boolean vbarOn;
385: boolean hbarOn;
386: Dimension childSize = new Dimension(child.getPreferredSize());
387: if (scrollbarDisplayPolicy == SCROLLBARS_AS_NEEDED) {
388: vbarOn = childSize.height > viewHeight;
389: hbarOn = childSize.width > viewWidth;
390: } else if (scrollbarDisplayPolicy == SCROLLBARS_ALWAYS) {
391: vbarOn = hbarOn = true;
392: } else { // SCROLLBARS_NEVER
393: vbarOn = hbarOn = false;
394: }
395: // adjust predicted view size to account for scrollbars
396:
397: if (vbarOn) {
398: viewWidth -= getVScrollbarWidth();
399: }
400: if (hbarOn) {
401: viewHeight -= getHScrollbarHeight();
402: }
403: // if child is smaller than view, size it up
404:
405: if (childSize.width < viewWidth) {
406: childSize.width = viewWidth;
407: }
408: if (childSize.height < viewHeight) {
409: childSize.height = viewHeight;
410: }
411: return childSize;
412: }
413:
414: /**
415: * Lays out this container by resizing its child to its preferred size.
416: * If the new preferred size of the child causes the current scroll
417: * position to be invalid, the scroll position is set to the closest
418: * valid position.
419: *
420: * @see Component#validate
421: */
422: public void doLayout() {
423: layout();
424: }
425:
426: /**
427: * Prints the component in this scroll pane.
428: * @param g the specified Graphics window
429: * @see Component#print
430: * @see Component#printAll
431: */
432: public void printComponents(Graphics g) {
433: if (ncomponents > 0) {
434: Component c = component[0];
435: Point p = c.getLocation();
436: Dimension vs = getViewportSize();
437: Insets i = getInsets();
438: Graphics cg = g.create();
439: try {
440: cg.clipRect(i.left, i.top, vs.width, vs.height);
441: cg.translate(p.x, p.y);
442: c.printAll(cg);
443: } finally {
444: cg.dispose();
445: }
446: }
447: }
448:
449: /**
450: * Creates the scroll pane's peer.
451: */
452: public void addNotify() {
453: synchronized (getTreeLock()) {
454: int vAdjustableValue = 0;
455: int hAdjustableValue = 0;
456: // Bug 4124460. Save the current adjustable values,
457: // so they can be restored after addnotify. Set the
458: // adjustibles to 0, to prevent crashes for possible
459: // negative values.
460: if (getComponentCount() > 0) {
461: vAdjustableValue = vAdjustable.getValue();
462: hAdjustableValue = hAdjustable.getValue();
463: vAdjustable.setValue(0);
464: hAdjustable.setValue(0);
465: }
466: if (peer == null)
467: peer = ((PeerBasedToolkit) getToolkit())
468: .createScrollPane(this );
469: super .addNotify();
470: // Bug 4124460. Restore the adjustable values.
471: if (getComponentCount() > 0) {
472: vAdjustable.setValue(vAdjustableValue);
473: hAdjustable.setValue(hAdjustableValue);
474: }
475: if (getComponentCount() > 0) {
476: Component comp = getComponent(0);
477: if (comp.peer instanceof sun.awt.peer.LightweightPeer) {
478: // The scrollpane won't work with a windowless child... it assumes
479: // it is moving a child window around so the windowless child is
480: // wrapped with a window.
481: remove(0);
482: Panel child = new Panel();
483: child.setLayout(new BorderLayout());
484: child.add(comp);
485: add(child);
486: }
487: }
488: }
489: }
490:
491: public String paramString() {
492: String sdpStr;
493: switch (scrollbarDisplayPolicy) {
494: case SCROLLBARS_AS_NEEDED:
495: sdpStr = "as-needed";
496: break;
497:
498: case SCROLLBARS_ALWAYS:
499: sdpStr = "always";
500: break;
501:
502: case SCROLLBARS_NEVER:
503: sdpStr = "never";
504: break;
505:
506: default:
507: sdpStr = "invalid display policy";
508: }
509: Point p = ncomponents > 0 ? getScrollPosition() : new Point(0,
510: 0);
511: Insets i = getInsets();
512: return super .paramString() + ",ScrollPosition=(" + p.x + ","
513: + p.y + ")" + ",Insets=(" + i.top + "," + i.left + ","
514: + i.bottom + "," + i.right + ")"
515: + ",ScrollbarDisplayPolicy=" + sdpStr
516: + ",wheelScrollingEnabled=" + isWheelScrollingEnabled();
517: }
518:
519: void autoProcessMouseWheel(MouseWheelEvent e) {
520: processMouseWheelEvent(e);
521: }
522:
523: /**
524: * Process mouse wheel events that are delivered to this
525: * <code>ScrollPane</code> by scrolling an appropriate amount.
526: * <p>Note that if the event parameter is <code>null</code>
527: * the behavior is unspecified and may result in an
528: * exception.
529: *
530: * @param e the mouse wheel event
531: * @since 1.4
532: */
533: protected void processMouseWheelEvent(MouseWheelEvent e) {
534: if (isWheelScrollingEnabled()) {
535: ScrollPaneWheelScroller.handleWheelScrolling(this , e);
536: e.consume();
537: }
538: super .processMouseWheelEvent(e);
539: }
540:
541: /**
542: * Enables/disables scrolling in response to movement of the mouse wheel.
543: * Wheel scrolling is enabled by default.
544: *
545: * @param handleWheel <code>true</code> if scrolling should be done
546: * automatically for a MouseWheelEvent,
547: * <code>false</code> otherwise.
548: * @see #isWheelScrollingEnabled
549: * @see java.awt.event.MouseWheelEvent
550: * @see java.awt.event.MouseWheelListener
551: * @since 1.4
552: */
553: public void setWheelScrollingEnabled(boolean handleWheel) {
554: wheelScrollingEnabled = handleWheel;
555: }
556:
557: /**
558: * Indicates whether or not scrolling will take place in response to
559: * the mouse wheel. Wheel scrolling is enabled by default.
560: *
561: * @see #setWheelScrollingEnabled(boolean)
562: * @since 1.4
563: */
564: public boolean isWheelScrollingEnabled() {
565: return wheelScrollingEnabled;
566: }
567:
568: /**
569: * Writes default serializable fields to stream.
570: */
571: private void writeObject(ObjectOutputStream s) throws IOException {
572: // 4352819: We only need this degenerate writeObject to make
573: // it safe for future versions of this class to write optional
574: // data to the stream.
575: s.defaultWriteObject();
576: }
577:
578: /**
579: * Reads default serializable fields to stream.
580: * @exception HeadlessException if
581: * <code>GraphicsEnvironment.isHeadless()</code> returns
582: * <code>true</code>
583: * @see java.awt.GraphicsEnvironment#isHeadless
584: */
585: private void readObject(ObjectInputStream s)
586: throws ClassNotFoundException, IOException,
587: HeadlessException {
588: // 4352819: Gotcha! Cannot use s.defaultReadObject here and
589: // then continue with reading optional data. Use GetField instead.
590: ObjectInputStream.GetField f = s.readFields();
591:
592: // Old fields
593: scrollbarDisplayPolicy = f.get("scrollbarDisplayPolicy",
594: SCROLLBARS_AS_NEEDED);
595:
596: // vAdjustable and hAdjustable have been taken out of
597: // the PP 1.1 serial spec
598: if (vAdjustable == null) {
599: vAdjustable = new ScrollPaneAdjustable(this ,
600: Adjustable.VERTICAL);
601: }
602: if (hAdjustable == null) {
603: hAdjustable = new ScrollPaneAdjustable(this ,
604: Adjustable.HORIZONTAL);
605: }
606:
607: // Since 1.4
608: wheelScrollingEnabled = f.get("wheelScrollingEnabled",
609: defaultWheelScroll);
610:
611: // // Note to future maintainers
612: // if (f.defaulted("wheelScrollingEnabled")) {
613: // // We are reading pre-1.4 stream that doesn't have
614: // // optional data, not even the TC_ENDBLOCKDATA marker.
615: // // Reading anything after this point is unsafe as we will
616: // // read unrelated objects further down the stream (4352819).
617: // }
618: // else {
619: // // Reading data from 1.4 or later, it's ok to try to read
620: // // optional data as OptionalDataException with eof == true
621: // // will be correctly reported
622: // }
623: }
624:
625: /**
626: * 6255265
627: */
628: int setValue(ScrollPaneAdjustable spa, int value) {
629: int newValue = 0;
630:
631: ScrollPanePeer peer = (ScrollPanePeer) this .peer;
632: if (peer != null) {
633: newValue = peer.setValue(spa, value);
634: if (newValue == -1) {
635: newValue = value;
636: }
637: }
638: Component c = getComponent(0);
639: switch (spa.getOrientation()) {
640: case Adjustable.VERTICAL:
641: c.move(c.getLocation().x, -(value));
642: break;
643:
644: case Adjustable.HORIZONTAL:
645: c.move(-(value), c.getLocation().y);
646: break;
647:
648: default:
649: throw new IllegalArgumentException(
650: "Illegal adjustable orientation");
651: }
652: return newValue;
653: }
654: }
655:
656: class ScrollPaneAdjustable implements Adjustable, java.io.Serializable {
657: private ScrollPane sp;
658: private int orientation;
659: private int minimum;
660: private int maximum;
661: private int visibleAmount;
662: private int unitIncrement = 1;
663: private int blockIncrement = 1;
664: private int value;
665: private AdjustmentListener adjustmentListener;
666: private static final String SCROLLPANE_ONLY = "Can be set by scrollpane only";
667: /*
668: * JDK 1.1 serialVersionUID
669: */
670: private static final long serialVersionUID = -3359745691033257079L;
671:
672: public ScrollPaneAdjustable(ScrollPane sp, int orientation) {
673: this .sp = sp;
674: this .orientation = orientation;
675: }
676:
677: /**
678: * This is called by the scrollpane itself to update the
679: * min,max,visible values. The scrollpane is the only one
680: * that should be changing these since it is the source of
681: * these values.
682: */
683: void setSpan(int min, int max, int visible) {
684: // adjust the values to be reasonable
685: minimum = min;
686: maximum = Math.max(max, minimum + 1);
687: visibleAmount = Math.min(visible, maximum - minimum);
688: visibleAmount = Math.max(visibleAmount, 1);
689: blockIncrement = Math.max((int) (visible * .90), 1);
690: setValue(value);
691: }
692:
693: public int getOrientation() {
694: return orientation;
695: }
696:
697: public void setMinimum(int min) {
698: throw new AWTError(SCROLLPANE_ONLY);
699: }
700:
701: public int getMinimum() {
702: return 0;
703: }
704:
705: public void setMaximum(int max) {
706: throw new AWTError(SCROLLPANE_ONLY);
707: }
708:
709: public int getMaximum() {
710: return maximum;
711: }
712:
713: public synchronized void setUnitIncrement(int u) {
714: if (u != unitIncrement) {
715: unitIncrement = u;
716: if (sp.peer != null) {
717: ScrollPanePeer peer = (ScrollPanePeer) sp.peer;
718: peer.setUnitIncrement(this , u);
719: }
720: }
721: }
722:
723: public int getUnitIncrement() {
724: return unitIncrement;
725: }
726:
727: public synchronized void setBlockIncrement(int b) {
728: blockIncrement = b;
729: }
730:
731: public int getBlockIncrement() {
732: return blockIncrement;
733: }
734:
735: public void setVisibleAmount(int v) {
736: throw new AWTError(SCROLLPANE_ONLY);
737: }
738:
739: public int getVisibleAmount() {
740: return visibleAmount;
741: }
742:
743: public void setValue(int v) {
744: // bounds check
745: v = Math.max(v, minimum);
746: v = Math.min(v, maximum - visibleAmount);
747: if (v != value) {
748: value = v;
749: // Synchronously notify the listeners so that they are
750: // guaranteed to be up-to-date with the Adjustable before
751: // it is mutated again.
752:
753: value = sp.setValue(this , value); //655265
754: AdjustmentEvent e = new AdjustmentEvent(this ,
755: AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
756: AdjustmentEvent.TRACK, value);
757: if (adjustmentListener != null) {
758: adjustmentListener.adjustmentValueChanged(e);
759: }
760: }
761: }
762:
763: public int getValue() {
764: return value;
765: }
766:
767: /**
768: * Adds the specified adjustment listener to receive adjustment events
769: * from this ScrollPane.
770: * If l is null, no exception is thrown and no action is performed.
771: *
772: * @param l the adjustment listener.
773: * @see java.awt.event.AdjustmentListener
774: * @see java.awt.ScrollPane#removeAdjustmentListener
775: */
776: public synchronized void addAdjustmentListener(AdjustmentListener l) {
777: adjustmentListener = AWTEventMulticaster.add(
778: adjustmentListener, l);
779: }
780:
781: /**
782: * Removes the specified adjustment listener so that it no longer
783: * receives adjustment events from this button.
784: * If l is null, no exception is thrown and no action is performed.
785: *
786: * @param l the adjustment listener.
787: * @see java.awt.event.AdjustmentListener
788: * @see java.awt.Button#addAdjustmentListener
789: * @since JDK1.1
790: */
791:
792: public synchronized void removeAdjustmentListener(
793: AdjustmentListener l) {
794: adjustmentListener = AWTEventMulticaster.remove(
795: adjustmentListener, l);
796: }
797:
798: public String toString() {
799: return getClass().getName() + "[" + paramString() + "]";
800: }
801:
802: public String paramString() {
803: return ((orientation == Adjustable.VERTICAL ? "vertical,"
804: : "horizontal,")
805: + "[0.."
806: + maximum
807: + "],"
808: + "val="
809: + value
810: + ",vis="
811: + visibleAmount + ",unit=" + unitIncrement + ",block=" + blockIncrement);
812: }
813: }
|