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