blob: f4303c0aea4bc666e6ea7132055cb4fe420a510f [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package java.awt;
26
27import java.awt.peer.LightweightPeer;
28import java.awt.peer.ScrollPanePeer;
29import java.awt.event.*;
30import javax.accessibility.*;
31import sun.awt.ScrollPaneWheelScroller;
32import sun.awt.SunToolkit;
33
34import java.beans.ConstructorProperties;
35import java.io.ObjectInputStream;
36import java.io.ObjectOutputStream;
37import java.io.IOException;
38
39/**
40 * A container class which implements automatic horizontal and/or
41 * vertical scrolling for a single child component. The display
42 * policy for the scrollbars can be set to:
43 * <OL>
44 * <LI>as needed: scrollbars created and shown only when needed by scrollpane
45 * <LI>always: scrollbars created and always shown by the scrollpane
46 * <LI>never: scrollbars never created or shown by the scrollpane
47 * </OL>
48 * <P>
49 * The state of the horizontal and vertical scrollbars is represented
50 * by two <code>ScrollPaneAdjustable</code> objects (one for each
51 * dimension) which implement the <code>Adjustable</code> interface.
52 * The API provides methods to access those objects such that the
53 * attributes on the Adjustable object (such as unitIncrement, value,
54 * etc.) can be manipulated.
55 * <P>
56 * Certain adjustable properties (minimum, maximum, blockIncrement,
57 * and visibleAmount) are set internally by the scrollpane in accordance
58 * with the geometry of the scrollpane and its child and these should
59 * not be set by programs using the scrollpane.
60 * <P>
61 * If the scrollbar display policy is defined as "never", then the
62 * scrollpane can still be programmatically scrolled using the
63 * setScrollPosition() method and the scrollpane will move and clip
64 * the child's contents appropriately. This policy is useful if the
65 * program needs to create and manage its own adjustable controls.
66 * <P>
67 * The placement of the scrollbars is controlled by platform-specific
68 * properties set by the user outside of the program.
69 * <P>
70 * The initial size of this container is set to 100x100, but can
71 * be reset using setSize().
72 * <P>
73 * Scrolling with the wheel on a wheel-equipped mouse is enabled by default.
74 * This can be disabled using <code>setWheelScrollingEnabled</code>.
75 * Wheel scrolling can be customized by setting the block and
76 * unit increment of the horizontal and vertical Adjustables.
77 * For information on how mouse wheel events are dispatched, see
78 * the class description for {@link MouseWheelEvent}.
79 * <P>
80 * Insets are used to define any space used by scrollbars and any
81 * borders created by the scroll pane. getInsets() can be used
82 * to get the current value for the insets. If the value of
83 * scrollbarsAlwaysVisible is false, then the value of the insets
84 * will change dynamically depending on whether the scrollbars are
85 * currently visible or not.
86 *
87 * @author Tom Ball
88 * @author Amy Fowler
89 * @author Tim Prinzing
90 */
91public class ScrollPane extends Container implements Accessible {
92
93
94 /**
95 * Initialize JNI field and method IDs
96 */
97 private static native void initIDs();
98
99 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) throws HeadlessException {
201 GraphicsEnvironment.checkHeadless();
202 this.layoutMgr = null;
203 this.width = 100;
204 this.height = 100;
205 switch (scrollbarDisplayPolicy) {
206 case SCROLLBARS_NEVER:
207 case SCROLLBARS_AS_NEEDED:
208 case SCROLLBARS_ALWAYS:
209 this.scrollbarDisplayPolicy = scrollbarDisplayPolicy;
210 break;
211 default:
212 throw new IllegalArgumentException("illegal scrollbar display policy");
213 }
214
215 vAdjustable = new ScrollPaneAdjustable(this, new PeerFixer(this),
216 Adjustable.VERTICAL);
217 hAdjustable = new ScrollPaneAdjustable(this, new PeerFixer(this),
218 Adjustable.HORIZONTAL);
219 setWheelScrollingEnabled(defaultWheelScroll);
220 }
221
222 /**
223 * Construct a name for this component. Called by getName() when the
224 * name is null.
225 */
226 String constructComponentName() {
227 synchronized (ScrollPane.class) {
228 return base + nameCounter++;
229 }
230 }
231
232 // The scrollpane won't work with a windowless child... it assumes
233 // it is moving a child window around so the windowless child is
234 // wrapped with a window.
235 private void addToPanel(Component comp, Object constraints, int index) {
236 Panel child = new Panel();
237 child.setLayout(new BorderLayout());
238 child.add(comp);
239 super.addImpl(child, constraints, index);
240 validate();
241 }
242
243 /**
244 * Adds the specified component to this scroll pane container.
245 * If the scroll pane has an existing child component, that
246 * component is removed and the new one is added.
247 * @param comp the component to be added
248 * @param constraints not applicable
249 * @param index position of child component (must be <= 0)
250 */
251 protected final void addImpl(Component comp, Object constraints, int index) {
252 synchronized (getTreeLock()) {
253 if (getComponentCount() > 0) {
254 remove(0);
255 }
256 if (index > 0) {
257 throw new IllegalArgumentException("position greater than 0");
258 }
259
260 if (!SunToolkit.isLightweightOrUnknown(comp)) {
261 super.addImpl(comp, constraints, index);
262 } else {
263 addToPanel(comp, constraints, index);
264 }
265 }
266 }
267
268 /**
269 * Returns the display policy for the scrollbars.
270 * @return the display policy for the scrollbars
271 */
272 public int getScrollbarDisplayPolicy() {
273 return scrollbarDisplayPolicy;
274 }
275
276 /**
277 * Returns the current size of the scroll pane's view port.
278 * @return the size of the view port in pixels
279 */
280 public Dimension getViewportSize() {
281 Insets i = getInsets();
282 return new Dimension(width - i.right - i.left,
283 height - i.top - i.bottom);
284 }
285
286 /**
287 * Returns the height that would be occupied by a horizontal
288 * scrollbar, which is independent of whether it is currently
289 * displayed by the scroll pane or not.
290 * @return the height of a horizontal scrollbar in pixels
291 */
292 public int getHScrollbarHeight() {
293 int h = 0;
294 if (scrollbarDisplayPolicy != SCROLLBARS_NEVER) {
295 ScrollPanePeer peer = (ScrollPanePeer)this.peer;
296 if (peer != null) {
297 h = peer.getHScrollbarHeight();
298 }
299 }
300 return h;
301 }
302
303 /**
304 * Returns the width that would be occupied by a vertical
305 * scrollbar, which is independent of whether it is currently
306 * displayed by the scroll pane or not.
307 * @return the width of a vertical scrollbar in pixels
308 */
309 public int getVScrollbarWidth() {
310 int w = 0;
311 if (scrollbarDisplayPolicy != SCROLLBARS_NEVER) {
312 ScrollPanePeer peer = (ScrollPanePeer)this.peer;
313 if (peer != null) {
314 w = peer.getVScrollbarWidth();
315 }
316 }
317 return w;
318 }
319
320 /**
321 * Returns the <code>ScrollPaneAdjustable</code> object which
322 * represents the state of the vertical scrollbar.
323 * The declared return type of this method is
324 * <code>Adjustable</code> to maintain backward compatibility.
325 * @see java.awt.ScrollPaneAdjustable
326 */
327 public Adjustable getVAdjustable() {
328 return vAdjustable;
329 }
330
331 /**
332 * Returns the <code>ScrollPaneAdjustable</code> object which
333 * represents the state of the horizontal scrollbar.
334 * The declared return type of this method is
335 * <code>Adjustable</code> to maintain backward compatibility.
336 * @see java.awt.ScrollPaneAdjustable
337 */
338 public Adjustable getHAdjustable() {
339 return hAdjustable;
340 }
341
342 /**
343 * Scrolls to the specified position within the child component.
344 * A call to this method is only valid if the scroll pane contains
345 * a child. Specifying a position outside of the legal scrolling bounds
346 * of the child will scroll to the closest legal position.
347 * Legal bounds are defined to be the rectangle:
348 * x = 0, y = 0, width = (child width - view port width),
349 * height = (child height - view port height).
350 * This is a convenience method which interfaces with the Adjustable
351 * objects which represent the state of the scrollbars.
352 * @param x the x position to scroll to
353 * @param y the y position to scroll to
354 * @throws NullPointerException if the scrollpane does not contain
355 * a child
356 */
357 public void setScrollPosition(int x, int y) {
358 synchronized (getTreeLock()) {
359 if (ncomponents <= 0) {
360 throw new NullPointerException("child is null");
361 }
362 hAdjustable.setValue(x);
363 vAdjustable.setValue(y);
364 }
365 }
366
367 /**
368 * Scrolls to the specified position within the child component.
369 * A call to this method is only valid if the scroll pane contains
370 * a child and the specified position is within legal scrolling bounds
371 * of the child. Specifying a position outside of the legal scrolling
372 * bounds of the child will scroll to the closest legal position.
373 * Legal bounds are defined to be the rectangle:
374 * x = 0, y = 0, width = (child width - view port width),
375 * height = (child height - view port height).
376 * This is a convenience method which interfaces with the Adjustable
377 * objects which represent the state of the scrollbars.
378 * @param p the Point representing the position to scroll to
379 */
380 public void setScrollPosition(Point p) {
381 setScrollPosition(p.x, p.y);
382 }
383
384 /**
385 * Returns the current x,y position within the child which is displayed
386 * at the 0,0 location of the scrolled panel's view port.
387 * This is a convenience method which interfaces with the adjustable
388 * objects which represent the state of the scrollbars.
389 * @return the coordinate position for the current scroll position
390 * @throws NullPointerException if the scrollpane does not contain
391 * a child
392 */
393 public Point getScrollPosition() {
394 if (ncomponents <= 0) {
395 throw new NullPointerException("child is null");
396 }
397 return new Point(hAdjustable.getValue(), vAdjustable.getValue());
398 }
399
400 /**
401 * Sets the layout manager for this container. This method is
402 * overridden to prevent the layout mgr from being set.
403 * @param mgr the specified layout manager
404 */
405 public final void setLayout(LayoutManager mgr) {
406 throw new AWTError("ScrollPane controls layout");
407 }
408
409 /**
410 * Lays out this container by resizing its child to its preferred size.
411 * If the new preferred size of the child causes the current scroll
412 * position to be invalid, the scroll position is set to the closest
413 * valid position.
414 *
415 * @see Component#validate
416 */
417 public void doLayout() {
418 layout();
419 }
420
421 /**
422 * Determine the size to allocate the child component.
423 * If the viewport area is bigger than the childs
424 * preferred size then the child is allocated enough
425 * to fill the viewport, otherwise the child is given
426 * it's preferred size.
427 */
428 Dimension calculateChildSize() {
429 //
430 // calculate the view size, accounting for border but not scrollbars
431 // - don't use right/bottom insets since they vary depending
432 // on whether or not scrollbars were displayed on last resize
433 //
434 Dimension size = getSize();
435 Insets insets = getInsets();
436 int viewWidth = size.width - insets.left*2;
437 int viewHeight = size.height - insets.top*2;
438
439 //
440 // determine whether or not horz or vert scrollbars will be displayed
441 //
442 boolean vbarOn;
443 boolean hbarOn;
444 Component child = getComponent(0);
445 Dimension childSize = new Dimension(child.getPreferredSize());
446
447 if (scrollbarDisplayPolicy == SCROLLBARS_AS_NEEDED) {
448 vbarOn = childSize.height > viewHeight;
449 hbarOn = childSize.width > viewWidth;
450 } else if (scrollbarDisplayPolicy == SCROLLBARS_ALWAYS) {
451 vbarOn = hbarOn = true;
452 } else { // SCROLLBARS_NEVER
453 vbarOn = hbarOn = false;
454 }
455
456 //
457 // adjust predicted view size to account for scrollbars
458 //
459 int vbarWidth = getVScrollbarWidth();
460 int hbarHeight = getHScrollbarHeight();
461 if (vbarOn) {
462 viewWidth -= vbarWidth;
463 }
464 if(hbarOn) {
465 viewHeight -= hbarHeight;
466 }
467
468 //
469 // if child is smaller than view, size it up
470 //
471 if (childSize.width < viewWidth) {
472 childSize.width = viewWidth;
473 }
474 if (childSize.height < viewHeight) {
475 childSize.height = viewHeight;
476 }
477
478 return childSize;
479 }
480
481 /**
482 * @deprecated As of JDK version 1.1,
483 * replaced by <code>doLayout()</code>.
484 */
485 @Deprecated
486 public void layout() {
487 if (ncomponents > 0) {
488 Component c = getComponent(0);
489 Point p = getScrollPosition();
490 Dimension cs = calculateChildSize();
491 Dimension vs = getViewportSize();
492 Insets i = getInsets();
493
494 c.reshape(i.left - p.x, i.top - p.y, cs.width, cs.height);
495 ScrollPanePeer peer = (ScrollPanePeer)this.peer;
496 if (peer != null) {
497 peer.childResized(cs.width, cs.height);
498 }
499
500 // update adjustables... the viewport size may have changed
501 // with the scrollbars coming or going so the viewport size
502 // is updated before the adjustables.
503 vs = getViewportSize();
504 hAdjustable.setSpan(0, cs.width, vs.width);
505 vAdjustable.setSpan(0, cs.height, vs.height);
506 }
507 }
508
509 /**
510 * Prints the component in this scroll pane.
511 * @param g the specified Graphics window
512 * @see Component#print
513 * @see Component#printAll
514 */
515 public void printComponents(Graphics g) {
516 if (ncomponents > 0) {
517 Component c = component[0];
518 Point p = c.getLocation();
519 Dimension vs = getViewportSize();
520 Insets i = getInsets();
521
522 Graphics cg = g.create();
523 try {
524 cg.clipRect(i.left, i.top, vs.width, vs.height);
525 cg.translate(p.x, p.y);
526 c.printAll(cg);
527 } finally {
528 cg.dispose();
529 }
530 }
531 }
532
533 /**
534 * Creates the scroll pane's peer.
535 */
536 public void addNotify() {
537 synchronized (getTreeLock()) {
538
539 int vAdjustableValue = 0;
540 int hAdjustableValue = 0;
541
542 // Bug 4124460. Save the current adjustable values,
543 // so they can be restored after addnotify. Set the
544 // adjustables to 0, to prevent crashes for possible
545 // negative values.
546 if (getComponentCount() > 0) {
547 vAdjustableValue = vAdjustable.getValue();
548 hAdjustableValue = hAdjustable.getValue();
549 vAdjustable.setValue(0);
550 hAdjustable.setValue(0);
551 }
552
553 if (peer == null)
554 peer = getToolkit().createScrollPane(this);
555 super.addNotify();
556
557 // Bug 4124460. Restore the adjustable values.
558 if (getComponentCount() > 0) {
559 vAdjustable.setValue(vAdjustableValue);
560 hAdjustable.setValue(hAdjustableValue);
561 }
562 }
563 }
564
565 /**
566 * Returns a string representing the state of this
567 * <code>ScrollPane</code>. This
568 * method is intended to be used only for debugging purposes, and the
569 * content and format of the returned string may vary between
570 * implementations. The returned string may be empty but may not be
571 * <code>null</code>.
572 *
573 * @return the parameter string of this scroll pane
574 */
575 public String paramString() {
576 String sdpStr;
577 switch (scrollbarDisplayPolicy) {
578 case SCROLLBARS_AS_NEEDED:
579 sdpStr = "as-needed";
580 break;
581 case SCROLLBARS_ALWAYS:
582 sdpStr = "always";
583 break;
584 case SCROLLBARS_NEVER:
585 sdpStr = "never";
586 break;
587 default:
588 sdpStr = "invalid display policy";
589 }
590 Point p = ncomponents > 0? getScrollPosition() : new Point(0,0);
591 Insets i = getInsets();
592 return super.paramString()+",ScrollPosition=("+p.x+","+p.y+")"+
593 ",Insets=("+i.top+","+i.left+","+i.bottom+","+i.right+")"+
594 ",ScrollbarDisplayPolicy="+sdpStr+
595 ",wheelScrollingEnabled="+isWheelScrollingEnabled();
596 }
597
598 void autoProcessMouseWheel(MouseWheelEvent e) {
599 processMouseWheelEvent(e);
600 }
601
602 /**
603 * Process mouse wheel events that are delivered to this
604 * <code>ScrollPane</code> by scrolling an appropriate amount.
605 * <p>Note that if the event parameter is <code>null</code>
606 * the behavior is unspecified and may result in an
607 * exception.
608 *
609 * @param e the mouse wheel event
610 * @since 1.4
611 */
612 protected void processMouseWheelEvent(MouseWheelEvent e) {
613 if (isWheelScrollingEnabled()) {
614 ScrollPaneWheelScroller.handleWheelScrolling(this, e);
615 e.consume();
616 }
617 super.processMouseWheelEvent(e);
618 }
619
620 /**
621 * If wheel scrolling is enabled, we return true for MouseWheelEvents
622 * @since 1.4
623 */
624 protected boolean eventTypeEnabled(int type) {
625 if (type == MouseEvent.MOUSE_WHEEL && isWheelScrollingEnabled()) {
626 return true;
627 }
628 else {
629 return super.eventTypeEnabled(type);
630 }
631 }
632
633 /**
634 * Enables/disables scrolling in response to movement of the mouse wheel.
635 * Wheel scrolling is enabled by default.
636 *
637 * @param handleWheel <code>true</code> if scrolling should be done
638 * automatically for a MouseWheelEvent,
639 * <code>false</code> otherwise.
640 * @see #isWheelScrollingEnabled
641 * @see java.awt.event.MouseWheelEvent
642 * @see java.awt.event.MouseWheelListener
643 * @since 1.4
644 */
645 public void setWheelScrollingEnabled(boolean handleWheel) {
646 wheelScrollingEnabled = handleWheel;
647 }
648
649 /**
650 * Indicates whether or not scrolling will take place in response to
651 * the mouse wheel. Wheel scrolling is enabled by default.
652 *
653 * @see #setWheelScrollingEnabled(boolean)
654 * @since 1.4
655 */
656 public boolean isWheelScrollingEnabled() {
657 return wheelScrollingEnabled;
658 }
659
660
661 /**
662 * Writes default serializable fields to stream.
663 */
664 private void writeObject(ObjectOutputStream s) throws IOException {
665 // 4352819: We only need this degenerate writeObject to make
666 // it safe for future versions of this class to write optional
667 // data to the stream.
668 s.defaultWriteObject();
669 }
670
671 /**
672 * Reads default serializable fields to stream.
673 * @exception HeadlessException if
674 * <code>GraphicsEnvironment.isHeadless()</code> returns
675 * <code>true</code>
676 * @see java.awt.GraphicsEnvironment#isHeadless
677 */
678 private void readObject(ObjectInputStream s)
679 throws ClassNotFoundException, IOException, HeadlessException
680 {
681 GraphicsEnvironment.checkHeadless();
682 // 4352819: Gotcha! Cannot use s.defaultReadObject here and
683 // then continue with reading optional data. Use GetField instead.
684 ObjectInputStream.GetField f = s.readFields();
685
686 // Old fields
687 scrollbarDisplayPolicy = f.get("scrollbarDisplayPolicy",
688 SCROLLBARS_AS_NEEDED);
689 hAdjustable = (ScrollPaneAdjustable)f.get("hAdjustable", null);
690 vAdjustable = (ScrollPaneAdjustable)f.get("vAdjustable", null);
691
692 // Since 1.4
693 wheelScrollingEnabled = f.get("wheelScrollingEnabled",
694 defaultWheelScroll);
695
696// // Note to future maintainers
697// if (f.defaulted("wheelScrollingEnabled")) {
698// // We are reading pre-1.4 stream that doesn't have
699// // optional data, not even the TC_ENDBLOCKDATA marker.
700// // Reading anything after this point is unsafe as we will
701// // read unrelated objects further down the stream (4352819).
702// }
703// else {
704// // Reading data from 1.4 or later, it's ok to try to read
705// // optional data as OptionalDataException with eof == true
706// // will be correctly reported
707// }
708 }
709
710 class PeerFixer implements AdjustmentListener, java.io.Serializable
711 {
712 private static final long serialVersionUID = 1043664721353696630L;
713
714 PeerFixer(ScrollPane scroller) {
715 this.scroller = scroller;
716 }
717
718 /**
719 * Invoked when the value of the adjustable has changed.
720 */
721 public void adjustmentValueChanged(AdjustmentEvent e) {
722 Adjustable adj = e.getAdjustable();
723 int value = e.getValue();
724 ScrollPanePeer peer = (ScrollPanePeer) scroller.peer;
725 if (peer != null) {
726 peer.setValue(adj, value);
727 }
728
729 Component c = scroller.getComponent(0);
730 switch(adj.getOrientation()) {
731 case Adjustable.VERTICAL:
732 c.move(c.getLocation().x, -(value));
733 break;
734 case Adjustable.HORIZONTAL:
735 c.move(-(value), c.getLocation().y);
736 break;
737 default:
738 throw new IllegalArgumentException("Illegal adjustable orientation");
739 }
740 }
741
742 private ScrollPane scroller;
743 }
744
745
746/////////////////
747// Accessibility support
748////////////////
749
750 /**
751 * Gets the AccessibleContext associated with this ScrollPane.
752 * For scroll panes, the AccessibleContext takes the form of an
753 * AccessibleAWTScrollPane.
754 * A new AccessibleAWTScrollPane instance is created if necessary.
755 *
756 * @return an AccessibleAWTScrollPane that serves as the
757 * AccessibleContext of this ScrollPane
758 * @since 1.3
759 */
760 public AccessibleContext getAccessibleContext() {
761 if (accessibleContext == null) {
762 accessibleContext = new AccessibleAWTScrollPane();
763 }
764 return accessibleContext;
765 }
766
767 /**
768 * This class implements accessibility support for the
769 * <code>ScrollPane</code> class. It provides an implementation of the
770 * Java Accessibility API appropriate to scroll pane user-interface
771 * elements.
772 * @since 1.3
773 */
774 protected class AccessibleAWTScrollPane extends AccessibleAWTContainer
775 {
776 /*
777 * JDK 1.3 serialVersionUID
778 */
779 private static final long serialVersionUID = 6100703663886637L;
780
781 /**
782 * Get the role of this object.
783 *
784 * @return an instance of AccessibleRole describing the role of the
785 * object
786 * @see AccessibleRole
787 */
788 public AccessibleRole getAccessibleRole() {
789 return AccessibleRole.SCROLL_PANE;
790 }
791
792 } // class AccessibleAWTScrollPane
793
794}
795
796/*
797 * In JDK 1.1.1, the pkg private class java.awt.PeerFixer was moved to
798 * become an inner class of ScrollPane, which broke serialization
799 * for ScrollPane objects using JDK 1.1.
800 * Instead of moving it back out here, which would break all JDK 1.1.x
801 * releases, we keep PeerFixer in both places. Because of the scoping rules,
802 * the PeerFixer that is used in ScrollPane will be the one that is the
803 * inner class. This pkg private PeerFixer class below will only be used
804 * if the Java 2 platform is used to deserialize ScrollPane objects that were serialized
805 * using JDK1.1
806 */
807class PeerFixer implements AdjustmentListener, java.io.Serializable {
808 /*
809 * serialVersionUID
810 */
811 private static final long serialVersionUID = 7051237413532574756L;
812
813 PeerFixer(ScrollPane scroller) {
814 this.scroller = scroller;
815 }
816
817 /**
818 * Invoked when the value of the adjustable has changed.
819 */
820 public void adjustmentValueChanged(AdjustmentEvent e) {
821 Adjustable adj = e.getAdjustable();
822 int value = e.getValue();
823 ScrollPanePeer peer = (ScrollPanePeer) scroller.peer;
824 if (peer != null) {
825 peer.setValue(adj, value);
826 }
827
828 Component c = scroller.getComponent(0);
829 switch(adj.getOrientation()) {
830 case Adjustable.VERTICAL:
831 c.move(c.getLocation().x, -(value));
832 break;
833 case Adjustable.HORIZONTAL:
834 c.move(-(value), c.getLocation().y);
835 break;
836 default:
837 throw new IllegalArgumentException("Illegal adjustable orientation");
838 }
839 }
840
841 private ScrollPane scroller;
842}