History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/awt/ScrollPane.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/awt/ScrollPane.java+849−0
@@ -0,0 +1,849 @@
1+/*
2+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. 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. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+package java.awt;
26+
27+import java.awt.peer.LightweightPeer;
28+import java.awt.peer.ScrollPanePeer;
29+import java.awt.event.*;
30+import javax.accessibility.*;
31+import sun.awt.ScrollPaneWheelScroller;
32+import sun.awt.SunToolkit;
33+
34+import java.beans.ConstructorProperties;
35+import java.beans.Transient;
36+import java.io.ObjectInputStream;
37+import java.io.ObjectOutputStream;
38+import java.io.IOException;
39+
40+/**
41+ * A container class which implements automatic horizontal and/or
42+ * vertical scrolling for a single child component. The display
43+ * policy for the scrollbars can be set to:
44+ * <OL>
45+ * <LI>as needed: scrollbars created and shown only when needed by scrollpane
46+ * <LI>always: scrollbars created and always shown by the scrollpane
47+ * <LI>never: scrollbars never created or shown by the scrollpane
48+ * </OL>
49+ * <P>
50+ * The state of the horizontal and vertical scrollbars is represented
51+ * by two <code>ScrollPaneAdjustable</code> objects (one for each
52+ * dimension) which implement the <code>Adjustable</code> interface.
53+ * The API provides methods to access those objects such that the
54+ * attributes on the Adjustable object (such as unitIncrement, value,
55+ * etc.) can be manipulated.
56+ * <P>
57+ * Certain adjustable properties (minimum, maximum, blockIncrement,
58+ * and visibleAmount) are set internally by the scrollpane in accordance
59+ * with the geometry of the scrollpane and its child and these should
60+ * not be set by programs using the scrollpane.
61+ * <P>
62+ * If the scrollbar display policy is defined as "never", then the
63+ * scrollpane can still be programmatically scrolled using the
64+ * setScrollPosition() method and the scrollpane will move and clip
65+ * the child's contents appropriately. This policy is useful if the
66+ * program needs to create and manage its own adjustable controls.
67+ * <P>
68+ * The placement of the scrollbars is controlled by platform-specific
69+ * properties set by the user outside of the program.
70+ * <P>
71+ * The initial size of this container is set to 100x100, but can
72+ * be reset using setSize().
73+ * <P>
74+ * Scrolling with the wheel on a wheel-equipped mouse is enabled by default.
75+ * This can be disabled using <code>setWheelScrollingEnabled</code>.
76+ * Wheel scrolling can be customized by setting the block and
77+ * unit increment of the horizontal and vertical Adjustables.
78+ * For information on how mouse wheel events are dispatched, see
79+ * the class description for {@link MouseWheelEvent}.
80+ * <P>
81+ * Insets are used to define any space used by scrollbars and any
82+ * borders created by the scroll pane. getInsets() can be used
83+ * to get the current value for the insets. If the value of
84+ * scrollbarsAlwaysVisible is false, then the value of the insets
85+ * will change dynamically depending on whether the scrollbars are
86+ * currently visible or not.
87+ *
88+ * @author Tom Ball
89+ * @author Amy Fowler
90+ * @author Tim Prinzing
91+ */
92+public class ScrollPane extends Container implements Accessible {
93+
94+
95+ /**
96+ * Initialize JNI field and method IDs
97+ */
98+ private static native void initIDs();
99+
100+ static {
101+ /* ensure that the necessary native libraries are loaded */
102+ Toolkit.loadLibraries();
103+ if (!GraphicsEnvironment.isHeadless()) {
104+ initIDs();
105+ }
106+ }
107+
108+ /**
109+ * Specifies that horizontal/vertical scrollbar should be shown
110+ * only when the size of the child exceeds the size of the scrollpane
111+ * in the horizontal/vertical dimension.
112+ */
113+ public static final int SCROLLBARS_AS_NEEDED = 0;
114+
115+ /**
116+ * Specifies that horizontal/vertical scrollbars should always be
117+ * shown regardless of the respective sizes of the scrollpane and child.
118+ */
119+ public static final int SCROLLBARS_ALWAYS = 1;
120+
121+ /**
122+ * Specifies that horizontal/vertical scrollbars should never be shown
123+ * regardless of the respective sizes of the scrollpane and child.
124+ */
125+ public static final int SCROLLBARS_NEVER = 2;
126+
127+ /**
128+ * There are 3 ways in which a scroll bar can be displayed.
129+ * This integer will represent one of these 3 displays -
130+ * (SCROLLBARS_ALWAYS, SCROLLBARS_AS_NEEDED, SCROLLBARS_NEVER)
131+ *
132+ * @serial
133+ * @see #getScrollbarDisplayPolicy
134+ */
135+ private int scrollbarDisplayPolicy;
136+
137+ /**
138+ * An adjustable vertical scrollbar.
139+ * It is important to note that you must <em>NOT</em> call 3
140+ * <code>Adjustable</code> methods, namely:
141+ * <code>setMinimum()</code>, <code>setMaximum()</code>,
142+ * <code>setVisibleAmount()</code>.
143+ *
144+ * @serial
145+ * @see #getVAdjustable
146+ */
147+ private ScrollPaneAdjustable vAdjustable;
148+
149+ /**
150+ * An adjustable horizontal scrollbar.
151+ * It is important to note that you must <em>NOT</em> call 3
152+ * <code>Adjustable</code> methods, namely:
153+ * <code>setMinimum()</code>, <code>setMaximum()</code>,
154+ * <code>setVisibleAmount()</code>.
155+ *
156+ * @serial
157+ * @see #getHAdjustable
158+ */
159+ private ScrollPaneAdjustable hAdjustable;
160+
161+ private static final String base = "scrollpane";
162+ private static int nameCounter = 0;
163+
164+ private static final boolean defaultWheelScroll = true;
165+
166+ /**
167+ * Indicates whether or not scrolling should take place when a
168+ * MouseWheelEvent is received.
169+ *
170+ * @serial
171+ * @since 1.4
172+ */
173+ private boolean wheelScrollingEnabled = defaultWheelScroll;
174+
175+ /*
176+ * JDK 1.1 serialVersionUID
177+ */
178+ private static final long serialVersionUID = 7956609840827222915L;
179+
180+ /**
181+ * Create a new scrollpane container with a scrollbar display
182+ * policy of "as needed".
183+ * @throws HeadlessException if GraphicsEnvironment.isHeadless()
184+ * returns true
185+ * @see java.awt.GraphicsEnvironment#isHeadless
186+ */
187+ public ScrollPane() throws HeadlessException {
188+ this(SCROLLBARS_AS_NEEDED);
189+ }
190+
191+ /**
192+ * Create a new scrollpane container.
193+ * @param scrollbarDisplayPolicy policy for when scrollbars should be shown
194+ * @throws IllegalArgumentException if the specified scrollbar
195+ * display policy is invalid
196+ * @throws HeadlessException if GraphicsEnvironment.isHeadless()
197+ * returns true
198+ * @see java.awt.GraphicsEnvironment#isHeadless
199+ */
200+ @ConstructorProperties({"scrollbarDisplayPolicy"})
201+ public ScrollPane(int scrollbarDisplayPolicy) 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("illegal scrollbar display policy");
214+ }
215+
216+ vAdjustable = new ScrollPaneAdjustable(this, new PeerFixer(this),
217+ Adjustable.VERTICAL);
218+ hAdjustable = new ScrollPaneAdjustable(this, new PeerFixer(this),
219+ Adjustable.HORIZONTAL);
220+ setWheelScrollingEnabled(defaultWheelScroll);
221+ }
222+
223+ /**
224+ * Construct a name for this component. Called by getName() when the
225+ * name is null.
226+ */
227+ String constructComponentName() {
228+ synchronized (ScrollPane.class) {
229+ return base + nameCounter++;
230+ }
231+ }
232+
233+ // The scrollpane won't work with a windowless child... it assumes
234+ // it is moving a child window around so the windowless child is
235+ // wrapped with a window.
236+ private void addToPanel(Component comp, Object constraints, int index) {
237+ Panel child = new Panel();
238+ child.setLayout(new BorderLayout());
239+ child.add(comp);
240+ super.addImpl(child, constraints, index);
241+ validate();
242+ }
243+
244+ /**
245+ * Adds the specified component to this scroll pane container.
246+ * If the scroll pane has an existing child component, that
247+ * component is removed and the new one is added.
248+ * @param comp the component to be added
249+ * @param constraints not applicable
250+ * @param index position of child component (must be <= 0)
251+ */
252+ protected final void addImpl(Component comp, Object constraints, int index) {
253+ synchronized (getTreeLock()) {
254+ if (getComponentCount() > 0) {
255+ remove(0);
256+ }
257+ if (index > 0) {
258+ throw new IllegalArgumentException("position greater than 0");
259+ }
260+
261+ if (!SunToolkit.isLightweightOrUnknown(comp)) {
262+ super.addImpl(comp, constraints, index);
263+ } else {
264+ addToPanel(comp, constraints, index);
265+ }
266+ }
267+ }
268+
269+ /**
270+ * Returns the display policy for the scrollbars.
271+ * @return the display policy for the scrollbars
272+ */
273+ public int getScrollbarDisplayPolicy() {
274+ return scrollbarDisplayPolicy;
275+ }
276+
277+ /**
278+ * Returns the current size of the scroll pane's view port.
279+ * @return the size of the view port in pixels
280+ */
281+ public Dimension getViewportSize() {
282+ Insets i = getInsets();
283+ return new Dimension(width - i.right - i.left,
284+ height - i.top - i.bottom);
285+ }
286+
287+ /**
288+ * Returns the height that would be occupied by a horizontal
289+ * scrollbar, which is independent of whether it is currently
290+ * displayed by the scroll pane or not.
291+ * @return the height of a horizontal scrollbar in pixels
292+ */
293+ public int getHScrollbarHeight() {
294+ int h = 0;
295+ if (scrollbarDisplayPolicy != SCROLLBARS_NEVER) {
296+ ScrollPanePeer peer = (ScrollPanePeer)this.peer;
297+ if (peer != null) {
298+ h = peer.getHScrollbarHeight();
299+ }
300+ }
301+ return h;
302+ }
303+
304+ /**
305+ * Returns the width that would be occupied by a vertical
306+ * scrollbar, which is independent of whether it is currently
307+ * displayed by the scroll pane or not.
308+ * @return the width of a vertical scrollbar in pixels
309+ */
310+ public int getVScrollbarWidth() {
311+ int w = 0;
312+ if (scrollbarDisplayPolicy != SCROLLBARS_NEVER) {
313+ ScrollPanePeer peer = (ScrollPanePeer)this.peer;
314+ if (peer != null) {
315+ w = peer.getVScrollbarWidth();
316+ }
317+ }
318+ return w;
319+ }
320+
321+ /**
322+ * Returns the <code>ScrollPaneAdjustable</code> object which
323+ * represents the state of the vertical scrollbar.
324+ * The declared return type of this method is
325+ * <code>Adjustable</code> to maintain backward compatibility.
326+ * @see java.awt.ScrollPaneAdjustable
327+ */
328+ public Adjustable getVAdjustable() {
329+ return vAdjustable;
330+ }
331+
332+ /**
333+ * Returns the <code>ScrollPaneAdjustable</code> object which
334+ * represents the state of the horizontal scrollbar.
335+ * The declared return type of this method is
336+ * <code>Adjustable</code> to maintain backward compatibility.
337+ * @see java.awt.ScrollPaneAdjustable
338+ */
339+ public Adjustable getHAdjustable() {
340+ return hAdjustable;
341+ }
342+
343+ /**
344+ * Scrolls to the specified position within the child component.
345+ * A call to this method is only valid if the scroll pane contains
346+ * a child. Specifying a position outside of the legal scrolling bounds
347+ * of the child will scroll to the closest legal position.
348+ * Legal bounds are defined to be the rectangle:
349+ * x = 0, y = 0, width = (child width - view port width),
350+ * height = (child height - view port height).
351+ * This is a convenience method which interfaces with the Adjustable
352+ * objects which represent the state of the scrollbars.
353+ * @param x the x position to scroll to
354+ * @param y the y position to scroll to
355+ * @throws NullPointerException if the scrollpane does not contain
356+ * a child
357+ */
358+ public void setScrollPosition(int x, int y) {
359+ synchronized (getTreeLock()) {
360+ if (getComponentCount()==0) {
361+ throw new NullPointerException("child is null");
362+ }
363+ hAdjustable.setValue(x);
364+ vAdjustable.setValue(y);
365+ }
366+ }
367+
368+ /**
369+ * Scrolls to the specified position within the child component.
370+ * A call to this method is only valid if the scroll pane contains
371+ * a child and the specified position is within legal scrolling bounds
372+ * of the child. Specifying a position outside of the legal scrolling
373+ * bounds of the child will scroll to the closest legal position.
374+ * Legal bounds are defined to be the rectangle:
375+ * x = 0, y = 0, width = (child width - view port width),
376+ * height = (child height - view port height).
377+ * This is a convenience method which interfaces with the Adjustable
378+ * objects which represent the state of the scrollbars.
379+ * @param p the Point representing the position to scroll to
380+ * @throws NullPointerException if {@code p} is {@code null}
381+ */
382+ public void setScrollPosition(Point p) {
383+ setScrollPosition(p.x, p.y);
384+ }
385+
386+ /**
387+ * Returns the current x,y position within the child which is displayed
388+ * at the 0,0 location of the scrolled panel's view port.
389+ * This is a convenience method which interfaces with the adjustable
390+ * objects which represent the state of the scrollbars.
391+ * @return the coordinate position for the current scroll position
392+ * @throws NullPointerException if the scrollpane does not contain
393+ * a child
394+ */
395+ @Transient
396+ public Point getScrollPosition() {
397+ synchronized (getTreeLock()) {
398+ if (getComponentCount()==0) {
399+ throw new NullPointerException("child is null");
400+ }
401+ return new Point(hAdjustable.getValue(), vAdjustable.getValue());
402+ }
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 (getComponentCount()==0) {
493+ return;
494+ }
495+ Component c = getComponent(0);
496+ Point p = getScrollPosition();
497+ Dimension cs = calculateChildSize();
498+ Dimension vs = getViewportSize();
499+ Insets i = getInsets();
500+
501+ c.reshape(i.left - p.x, i.top - p.y, cs.width, cs.height);
502+ ScrollPanePeer peer = (ScrollPanePeer)this.peer;
503+ if (peer != null) {
504+ peer.childResized(cs.width, cs.height);
505+ }
506+
507+ // update adjustables... the viewport size may have changed
508+ // with the scrollbars coming or going so the viewport size
509+ // is updated before the adjustables.
510+ vs = getViewportSize();
511+ hAdjustable.setSpan(0, cs.width, vs.width);
512+ vAdjustable.setSpan(0, cs.height, vs.height);
513+ }
514+
515+ /**
516+ * Prints the component in this scroll pane.
517+ * @param g the specified Graphics window
518+ * @see Component#print
519+ * @see Component#printAll
520+ */
521+ public void printComponents(Graphics g) {
522+ if (getComponentCount()==0) {
523+ return;
524+ }
525+ Component c = getComponent(0);
526+ Point p = c.getLocation();
527+ Dimension vs = getViewportSize();
528+ Insets i = getInsets();
529+
530+ Graphics cg = g.create();
531+ try {
532+ cg.clipRect(i.left, i.top, vs.width, vs.height);
533+ cg.translate(p.x, p.y);
534+ c.printAll(cg);
535+ } finally {
536+ cg.dispose();
537+ }
538+ }
539+
540+ /**
541+ * Creates the scroll pane's peer.
542+ */
543+ public void addNotify() {
544+ synchronized (getTreeLock()) {
545+
546+ int vAdjustableValue = 0;
547+ int hAdjustableValue = 0;
548+
549+ // Bug 4124460. Save the current adjustable values,
550+ // so they can be restored after addnotify. Set the
551+ // adjustables to 0, to prevent crashes for possible
552+ // negative values.
553+ if (getComponentCount() > 0) {
554+ vAdjustableValue = vAdjustable.getValue();
555+ hAdjustableValue = hAdjustable.getValue();
556+ vAdjustable.setValue(0);
557+ hAdjustable.setValue(0);
558+ }
559+
560+ if (peer == null)
561+ peer = getToolkit().createScrollPane(this);
562+ super.addNotify();
563+
564+ // Bug 4124460. Restore the adjustable values.
565+ if (getComponentCount() > 0) {
566+ vAdjustable.setValue(vAdjustableValue);
567+ hAdjustable.setValue(hAdjustableValue);
568+ }
569+ }
570+ }
571+
572+ /**
573+ * Returns a string representing the state of this
574+ * <code>ScrollPane</code>. This
575+ * method is intended to be used only for debugging purposes, and the
576+ * content and format of the returned string may vary between
577+ * implementations. The returned string may be empty but may not be
578+ * <code>null</code>.
579+ *
580+ * @return the parameter string of this scroll pane
581+ */
582+ public String paramString() {
583+ String sdpStr;
584+ switch (scrollbarDisplayPolicy) {
585+ case SCROLLBARS_AS_NEEDED:
586+ sdpStr = "as-needed";
587+ break;
588+ case SCROLLBARS_ALWAYS:
589+ sdpStr = "always";
590+ break;
591+ case SCROLLBARS_NEVER:
592+ sdpStr = "never";
593+ break;
594+ default:
595+ sdpStr = "invalid display policy";
596+ }
597+ Point p = (getComponentCount()>0)? getScrollPosition() : new Point(0,0);
598+ Insets i = getInsets();
599+ return super.paramString()+",ScrollPosition=("+p.x+","+p.y+")"+
600+ ",Insets=("+i.top+","+i.left+","+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+ }
635+ else {
636+ return super.eventTypeEnabled(type);
637+ }
638+ }
639+
640+ /**
641+ * Enables/disables scrolling in response to movement of the mouse wheel.
642+ * Wheel scrolling is enabled by default.
643+ *
644+ * @param handleWheel <code>true</code> if scrolling should be done
645+ * automatically for a MouseWheelEvent,
646+ * <code>false</code> otherwise.
647+ * @see #isWheelScrollingEnabled
648+ * @see java.awt.event.MouseWheelEvent
649+ * @see java.awt.event.MouseWheelListener
650+ * @since 1.4
651+ */
652+ public void setWheelScrollingEnabled(boolean handleWheel) {
653+ wheelScrollingEnabled = handleWheel;
654+ }
655+
656+ /**
657+ * Indicates whether or not scrolling will take place in response to
658+ * the mouse wheel. Wheel scrolling is enabled by default.
659+ *
660+ * @see #setWheelScrollingEnabled(boolean)
661+ * @since 1.4
662+ */
663+ public boolean isWheelScrollingEnabled() {
664+ return wheelScrollingEnabled;
665+ }
666+
667+
668+ /**
669+ * Writes default serializable fields to stream.
670+ */
671+ private void writeObject(ObjectOutputStream s) throws IOException {
672+ // 4352819: We only need this degenerate writeObject to make
673+ // it safe for future versions of this class to write optional
674+ // data to the stream.
675+ s.defaultWriteObject();
676+ }
677+
678+ /**
679+ * Reads default serializable fields to stream.
680+ * @exception HeadlessException if
681+ * <code>GraphicsEnvironment.isHeadless()</code> returns
682+ * <code>true</code>
683+ * @see java.awt.GraphicsEnvironment#isHeadless
684+ */
685+ private void readObject(ObjectInputStream s)
686+ throws ClassNotFoundException, IOException, HeadlessException
687+ {
688+ GraphicsEnvironment.checkHeadless();
689+ // 4352819: Gotcha! Cannot use s.defaultReadObject here and
690+ // then continue with reading optional data. Use GetField instead.
691+ ObjectInputStream.GetField f = s.readFields();
692+
693+ // Old fields
694+ scrollbarDisplayPolicy = f.get("scrollbarDisplayPolicy",
695+ SCROLLBARS_AS_NEEDED);
696+ hAdjustable = (ScrollPaneAdjustable)f.get("hAdjustable", null);
697+ vAdjustable = (ScrollPaneAdjustable)f.get("vAdjustable", null);
698+
699+ // Since 1.4
700+ wheelScrollingEnabled = f.get("wheelScrollingEnabled",
701+ defaultWheelScroll);
702+
703+// // Note to future maintainers
704+// if (f.defaulted("wheelScrollingEnabled")) {
705+// // We are reading pre-1.4 stream that doesn't have
706+// // optional data, not even the TC_ENDBLOCKDATA marker.
707+// // Reading anything after this point is unsafe as we will
708+// // read unrelated objects further down the stream (4352819).
709+// }
710+// else {
711+// // Reading data from 1.4 or later, it's ok to try to read
712+// // optional data as OptionalDataException with eof == true
713+// // will be correctly reported
714+// }
715+ }
716+
717+ class PeerFixer implements AdjustmentListener, java.io.Serializable
718+ {
719+ private static final long serialVersionUID = 1043664721353696630L;
720+
721+ PeerFixer(ScrollPane scroller) {
722+ this.scroller = scroller;
723+ }
724+
725+ /**
726+ * Invoked when the value of the adjustable has changed.
727+ */
728+ public void adjustmentValueChanged(AdjustmentEvent e) {
729+ Adjustable adj = e.getAdjustable();
730+ int value = e.getValue();
731+ ScrollPanePeer peer = (ScrollPanePeer) scroller.peer;
732+ if (peer != null) {
733+ peer.setValue(adj, value);
734+ }
735+
736+ Component c = scroller.getComponent(0);
737+ switch(adj.getOrientation()) {
738+ case Adjustable.VERTICAL:
739+ c.move(c.getLocation().x, -(value));
740+ break;
741+ case Adjustable.HORIZONTAL:
742+ c.move(-(value), c.getLocation().y);
743+ break;
744+ default:
745+ throw new IllegalArgumentException("Illegal adjustable orientation");
746+ }
747+ }
748+
749+ private ScrollPane scroller;
750+ }
751+
752+
753+/////////////////
754+// Accessibility support
755+////////////////
756+
757+ /**
758+ * Gets the AccessibleContext associated with this ScrollPane.
759+ * For scroll panes, the AccessibleContext takes the form of an
760+ * AccessibleAWTScrollPane.
761+ * A new AccessibleAWTScrollPane instance is created if necessary.
762+ *
763+ * @return an AccessibleAWTScrollPane that serves as the
764+ * AccessibleContext of this ScrollPane
765+ * @since 1.3
766+ */
767+ public AccessibleContext getAccessibleContext() {
768+ if (accessibleContext == null) {
769+ accessibleContext = new AccessibleAWTScrollPane();
770+ }
771+ return accessibleContext;
772+ }
773+
774+ /**
775+ * This class implements accessibility support for the
776+ * <code>ScrollPane</code> class. It provides an implementation of the
777+ * Java Accessibility API appropriate to scroll pane user-interface
778+ * elements.
779+ * @since 1.3
780+ */
781+ protected class AccessibleAWTScrollPane extends AccessibleAWTContainer
782+ {
783+ /*
784+ * JDK 1.3 serialVersionUID
785+ */
786+ private static final long serialVersionUID = 6100703663886637L;
787+
788+ /**
789+ * Get the role of this object.
790+ *
791+ * @return an instance of AccessibleRole describing the role of the
792+ * object
793+ * @see AccessibleRole
794+ */
795+ public AccessibleRole getAccessibleRole() {
796+ return AccessibleRole.SCROLL_PANE;
797+ }
798+
799+ } // class AccessibleAWTScrollPane
800+
801+}
802+
803+/*
804+ * In JDK 1.1.1, the pkg private class java.awt.PeerFixer was moved to
805+ * become an inner class of ScrollPane, which broke serialization
806+ * for ScrollPane objects using JDK 1.1.
807+ * Instead of moving it back out here, which would break all JDK 1.1.x
808+ * releases, we keep PeerFixer in both places. Because of the scoping rules,
809+ * the PeerFixer that is used in ScrollPane will be the one that is the
810+ * inner class. This pkg private PeerFixer class below will only be used
811+ * if the Java 2 platform is used to deserialize ScrollPane objects that were serialized
812+ * using JDK1.1
813+ */
814+class PeerFixer implements AdjustmentListener, java.io.Serializable {
815+ /*
816+ * serialVersionUID
817+ */
818+ private static final long serialVersionUID = 7051237413532574756L;
819+
820+ PeerFixer(ScrollPane scroller) {
821+ this.scroller = scroller;
822+ }
823+
824+ /**
825+ * Invoked when the value of the adjustable has changed.
826+ */
827+ public void adjustmentValueChanged(AdjustmentEvent e) {
828+ Adjustable adj = e.getAdjustable();
829+ int value = e.getValue();
830+ ScrollPanePeer peer = (ScrollPanePeer) scroller.peer;
831+ if (peer != null) {
832+ peer.setValue(adj, value);
833+ }
834+
835+ Component c = scroller.getComponent(0);
836+ switch(adj.getOrientation()) {
837+ case Adjustable.VERTICAL:
838+ c.move(c.getLocation().x, -(value));
839+ break;
840+ case Adjustable.HORIZONTAL:
841+ c.move(-(value), c.getLocation().y);
842+ break;
843+ default:
844+ throw new IllegalArgumentException("Illegal adjustable orientation");
845+ }
846+ }
847+
848+ private ScrollPane scroller;
849+}