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 }
|