/*
 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javax.swing;

import javax.swing.plaf.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.accessibility.*;

import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Rectangle;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Point;

import java.io.ObjectOutputStream;
import java.io.IOException;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.Transient;

/**
 * Provides a scrollable view of a lightweight component.
 * A <code>JScrollPane</code> manages a viewport, optional
 * vertical and horizontal scroll bars, and optional row and
 * column heading viewports.
 * You can find task-oriented documentation of <code>JScrollPane</code> in
 *  <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/scrollpane.html">How to Use Scroll Panes</a>,
 * a section in <em>The Java Tutorial</em>.  Note that
 * <code>JScrollPane</code> does not support heavyweight components.
 * <p>
 * <TABLE ALIGN="RIGHT" BORDER="0" SUMMARY="layout">
 *    <TR>
 *    <TD ALIGN="CENTER">
 *      <P ALIGN="CENTER"><IMG SRC="doc-files/JScrollPane-1.gif"
 *      alt="The following text describes this image."
 *      WIDTH="256" HEIGHT="248" ALIGN="BOTTOM" BORDER="0">
 *    </TD>
 *    </TR>
 * </TABLE>
 * The <code>JViewport</code> provides a window,
 * or &quot;viewport&quot; onto a data
 * source -- for example, a text file. That data source is the
 * &quot;scrollable client&quot; (aka data model) displayed by the
 * <code>JViewport</code> view.
 * A <code>JScrollPane</code> basically consists of <code>JScrollBar</code>s,
 * a <code>JViewport</code>, and the wiring between them,
 * as shown in the diagram at right.
 * <p>
 * In addition to the scroll bars and viewport,
 * a <code>JScrollPane</code> can have a
 * column header and a row header. Each of these is a
 * <code>JViewport</code> object that
 * you specify with <code>setRowHeaderView</code>,
 * and <code>setColumnHeaderView</code>.
 * The column header viewport automatically scrolls left and right, tracking
 * the left-right scrolling of the main viewport.
 * (It never scrolls vertically, however.)
 * The row header acts in a similar fashion.
 * <p>
 * Where two scroll bars meet, the row header meets the column header,
 * or a scroll bar meets one of the headers, both components stop short
 * of the corner, leaving a rectangular space which is, by default, empty.
 * These spaces can potentially exist in any number of the four corners.
 * In the previous diagram, the top right space is present and identified
 * by the label "corner component".
 * <p>
 * Any number of these empty spaces can be replaced by using the
 * <code>setCorner</code> method to add a component to a particular corner.
 * (Note: The same component cannot be added to multiple corners.)
 * This is useful if there's
 * some extra decoration or function you'd like to add to the scroll pane.
 * The size of each corner component is entirely determined by the size of the
 * headers and/or scroll bars that surround it.
 * <p>
 * A corner component will only be visible if there is an empty space in that
 * corner for it to exist in. For example, consider a component set into the
 * top right corner of a scroll pane with a column header. If the scroll pane's
 * vertical scrollbar is not present, perhaps because the view component hasn't
 * grown large enough to require it, then the corner component will not be
 * shown (since there is no empty space in that corner created by the meeting
 * of the header and vertical scroll bar). Forcing the scroll bar to always be
 * shown, using
 * <code>setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_ALWAYS)</code>,
 * will ensure that the space for the corner component always exists.
 * <p>
 * To add a border around the main viewport,
 * you can use <code>setViewportBorder</code>.
 * (Of course, you can also add a border around the whole scroll pane using
 * <code>setBorder</code>.)
 * <p>
 * A common operation to want to do is to set the background color that will
 * be used if the main viewport view is smaller than the viewport, or is
 * not opaque. This can be accomplished by setting the background color
 * of the viewport, via <code>scrollPane.getViewport().setBackground()</code>.
 * The reason for setting the color of the viewport and not the scrollpane
 * is that by default <code>JViewport</code> is opaque
 * which, among other things, means it will completely fill
 * in its background using its background color.  Therefore when
 * <code>JScrollPane</code> draws its background the viewport will
 * usually draw over it.
 * <p>
 * By default <code>JScrollPane</code> uses <code>ScrollPaneLayout</code>
 * to handle the layout of its child Components. <code>ScrollPaneLayout</code>
 * determines the size to make the viewport view in one of two ways:
 * <ol>
 *   <li>If the view implements <code>Scrollable</code>
 *       a combination of <code>getPreferredScrollableViewportSize</code>,
 *       <code>getScrollableTracksViewportWidth</code> and
 *       <code>getScrollableTracksViewportHeight</code>is used, otherwise
 *   <li><code>getPreferredSize</code> is used.
 * </ol>
 * <p>
 * <strong>Warning:</strong> Swing is not thread safe. For more
 * information see <a
 * href="package-summary.html#threading">Swing's Threading
 * Policy</a>.
 * <p>
 * <strong>Warning:</strong>
 * Serialized objects of this class will not be compatible with
 * future Swing releases. The current serialization support is
 * appropriate for short term storage or RMI between applications running
 * the same version of Swing.  As of 1.4, support for long term storage
 * of all JavaBeans<sup><font size="-2">TM</font></sup>
 * has been added to the <code>java.beans</code> package.
 * Please see {@link java.beans.XMLEncoder}.
 *
 * @see JScrollBar
 * @see JViewport
 * @see ScrollPaneLayout
 * @see Scrollable
 * @see Component#getPreferredSize
 * @see #setViewportView
 * @see #setRowHeaderView
 * @see #setColumnHeaderView
 * @see #setCorner
 * @see #setViewportBorder
 *
 * @beaninfo
 *     attribute: isContainer true
 *     attribute: containerDelegate getViewport
 *   description: A specialized container that manages a viewport, optional scrollbars and headers
 *
 * @author Hans Muller
 */
public class JScrollPane extends JComponent implements ScrollPaneConstants, Accessible
{
    private Border viewportBorder;

    /**
     * @see #getUIClassID
     * @see #readObject
     */
    private static final String uiClassID = "ScrollPaneUI";

    /**
     * The display policy for the vertical scrollbar.
     * The default is
     * <code>ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED</code>.
     * @see #setVerticalScrollBarPolicy
     */
    protected int verticalScrollBarPolicy = VERTICAL_SCROLLBAR_AS_NEEDED;


    /**
     * The display policy for the horizontal scrollbar.
     * The default is
     * <code>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED</code>.
     * @see #setHorizontalScrollBarPolicy
     */
    protected int horizontalScrollBarPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED;


    /**
     * The scrollpane's viewport child.  Default is an empty
     * <code>JViewport</code>.
     * @see #setViewport
     */
    protected JViewport viewport;


    /**
     * The scrollpane's vertical scrollbar child.
     * Default is a <code>JScrollBar</code>.
     * @see #setVerticalScrollBar
     */
    protected JScrollBar verticalScrollBar;


    /**
     * The scrollpane's horizontal scrollbar child.
     * Default is a <code>JScrollBar</code>.
     * @see #setHorizontalScrollBar
     */
    protected JScrollBar horizontalScrollBar;


    /**
     * The row header child.  Default is <code>null</code>.
     * @see #setRowHeader
     */
    protected JViewport rowHeader;


    /**
     * The column header child.  Default is <code>null</code>.
     * @see #setColumnHeader
     */
    protected JViewport columnHeader;


    /**
     * The component to display in the lower left corner.
     * Default is <code>null</code>.
     * @see #setCorner
     */
    protected Component lowerLeft;


    /**
     * The component to display in the lower right corner.
     * Default is <code>null</code>.
     * @see #setCorner
     */
    protected Component lowerRight;


    /**
     * The component to display in the upper left corner.
     * Default is <code>null</code>.
     * @see #setCorner
     */
    protected Component upperLeft;


    /**
     * The component to display in the upper right corner.
     * Default is <code>null</code>.
     * @see #setCorner
     */
    protected Component upperRight;

    /*
     * State flag for mouse wheel scrolling
     */
    private boolean wheelScrollState = true;

    /**
     * Creates a <code>JScrollPane</code> that displays the view
     * component in a viewport
     * whose view position can be controlled with a pair of scrollbars.
     * The scrollbar policies specify when the scrollbars are displayed,
     * For example, if <code>vsbPolicy</code> is
     * <code>VERTICAL_SCROLLBAR_AS_NEEDED</code>
     * then the vertical scrollbar only appears if the view doesn't fit
     * vertically. The available policy settings are listed at
     * {@link #setVerticalScrollBarPolicy} and
     * {@link #setHorizontalScrollBarPolicy}.
     *
     * @see #setViewportView
     *
     * @param view the component to display in the scrollpanes viewport
     * @param vsbPolicy an integer that specifies the vertical
     *          scrollbar policy
     * @param hsbPolicy an integer that specifies the horizontal
     *          scrollbar policy
     */
    public JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
    {
        setLayout(new ScrollPaneLayout.UIResource());
        setVerticalScrollBarPolicy(vsbPolicy);
        setHorizontalScrollBarPolicy(hsbPolicy);
        setViewport(createViewport());
        setVerticalScrollBar(createVerticalScrollBar());
        setHorizontalScrollBar(createHorizontalScrollBar());
        if (view != null) {
            setViewportView(view);
        }
        setUIProperty("opaque",true);
        updateUI();

        if (!this.getComponentOrientation().isLeftToRight()) {
            viewport.setViewPosition(new Point(Integer.MAX_VALUE, 0));
        }
    }


    /**
     * Creates a <code>JScrollPane</code> that displays the
     * contents of the specified
     * component, where both horizontal and vertical scrollbars appear
     * whenever the component's contents are larger than the view.
     *
     * @see #setViewportView
     * @param view the component to display in the scrollpane's viewport
     */
    public JScrollPane(Component view) {
        this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
    }


    /**
     * Creates an empty (no viewport view) <code>JScrollPane</code>
     * with specified
     * scrollbar policies. The available policy settings are listed at
     * {@link #setVerticalScrollBarPolicy} and
     * {@link #setHorizontalScrollBarPolicy}.
     *
     * @see #setViewportView
     *
     * @param vsbPolicy an integer that specifies the vertical
     *          scrollbar policy
     * @param hsbPolicy an integer that specifies the horizontal
     *          scrollbar policy
     */
    public JScrollPane(int vsbPolicy, int hsbPolicy) {
        this(null, vsbPolicy, hsbPolicy);
    }


    /**
     * Creates an empty (no viewport view) <code>JScrollPane</code>
     * where both horizontal and vertical scrollbars appear when needed.
     */
    public JScrollPane() {
        this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
    }


    /**
     * Returns the look and feel (L&F) object that renders this component.
     *
     * @return the <code>ScrollPaneUI</code> object that renders this
     *                          component
     * @see #setUI
     * @beaninfo
     *        bound: true
     *       hidden: true
     *    attribute: visualUpdate true
     *  description: The UI object that implements the Component's LookAndFeel.
     */
    public ScrollPaneUI getUI() {
        return (ScrollPaneUI)ui;
    }


    /**
     * Sets the <code>ScrollPaneUI</code> object that provides the
     * look and feel (L&F) for this component.
     *
     * @param ui the <code>ScrollPaneUI</code> L&F object
     * @see #getUI
     */
    public void setUI(ScrollPaneUI ui) {
        super.setUI(ui);
    }


    /**
     * Replaces the current <code>ScrollPaneUI</code> object with a version
     * from the current default look and feel.
     * To be called when the default look and feel changes.
     *
     * @see JComponent#updateUI
     * @see UIManager#getUI
     */
    public void updateUI() {
        setUI((ScrollPaneUI)UIManager.getUI(this));
    }


    /**
     * Returns the suffix used to construct the name of the L&F class used to
     * render this component.
     *
     * @return the string "ScrollPaneUI"
     * @see JComponent#getUIClassID
     * @see UIDefaults#getUI
     *
     * @beaninfo
     *    hidden: true
     */
    public String getUIClassID() {
        return uiClassID;
    }



    /**
     * Sets the layout manager for this <code>JScrollPane</code>.
     * This method overrides <code>setLayout</code> in
     * <code>java.awt.Container</code> to ensure that only
     * <code>LayoutManager</code>s which
     * are subclasses of <code>ScrollPaneLayout</code> can be used in a
     * <code>JScrollPane</code>. If <code>layout</code> is non-null, this
     * will invoke <code>syncWithScrollPane</code> on it.
     *
     * @param layout the specified layout manager
     * @exception ClassCastException if layout is not a
     *                  <code>ScrollPaneLayout</code>
     * @see java.awt.Container#getLayout
     * @see java.awt.Container#setLayout
     *
     * @beaninfo
     *    hidden: true
     */
    public void setLayout(LayoutManager layout) {
        if (layout instanceof ScrollPaneLayout) {
            super.setLayout(layout);
            ((ScrollPaneLayout)layout).syncWithScrollPane(this);
        }
        else if (layout == null) {
            super.setLayout(layout);
        }
        else {
            String s = "layout of JScrollPane must be a ScrollPaneLayout";
            throw new ClassCastException(s);
        }
    }

    /**
     * Overridden to return true so that any calls to <code>revalidate</code>
     * on any descendants of this <code>JScrollPane</code> will cause the
     * entire tree beginning with this <code>JScrollPane</code> to be
     * validated.
     *
     * @return true
     * @see java.awt.Container#validate
     * @see JComponent#revalidate
     * @see JComponent#isValidateRoot
     * @see java.awt.Container#isValidateRoot
     *
     * @beaninfo
     *    hidden: true
     */
    @Override
    public boolean isValidateRoot() {
        return true;
    }


    /**
     * Returns the vertical scroll bar policy value.
     * @return the <code>verticalScrollBarPolicy</code> property
     * @see #setVerticalScrollBarPolicy
     */
    public int getVerticalScrollBarPolicy() {
        return verticalScrollBarPolicy;
    }


    /**
     * Determines when the vertical scrollbar appears in the scrollpane.
     * Legal values are:
     * <ul>
     * <li><code>ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED</code>
     * <li><code>ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER</code>
     * <li><code>ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS</code>
     * </ul>
     *
     * @param policy one of the three values listed above
     * @exception IllegalArgumentException if <code>policy</code>
     *                          is not one of the legal values shown above
     * @see #getVerticalScrollBarPolicy
     *
     * @beaninfo
     *   preferred: true
     *       bound: true
     * description: The scrollpane vertical scrollbar policy
     *        enum: VERTICAL_SCROLLBAR_AS_NEEDED ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED
     *              VERTICAL_SCROLLBAR_NEVER ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER
     *              VERTICAL_SCROLLBAR_ALWAYS ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS
     */
    public void setVerticalScrollBarPolicy(int policy) {
        switch (policy) {
        case VERTICAL_SCROLLBAR_AS_NEEDED:
        case VERTICAL_SCROLLBAR_NEVER:
        case VERTICAL_SCROLLBAR_ALWAYS:
                break;
        default:
            throw new IllegalArgumentException("invalid verticalScrollBarPolicy");
        }
        int old = verticalScrollBarPolicy;
        verticalScrollBarPolicy = policy;
        firePropertyChange("verticalScrollBarPolicy", old, policy);
        revalidate();
        repaint();
    }


    /**
     * Returns the horizontal scroll bar policy value.
     * @return the <code>horizontalScrollBarPolicy</code> property
     * @see #setHorizontalScrollBarPolicy
     */
    public int getHorizontalScrollBarPolicy() {
        return horizontalScrollBarPolicy;
    }


    /**
     * Determines when the horizontal scrollbar appears in the scrollpane.
     * The options are:<ul>
     * <li><code>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED</code>
     * <li><code>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER</code>
     * <li><code>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS</code>
     * </ul>
     *
     * @param policy one of the three values listed above
     * @exception IllegalArgumentException if <code>policy</code>
     *                          is not one of the legal values shown above
     * @see #getHorizontalScrollBarPolicy
     *
     * @beaninfo
     *   preferred: true
     *       bound: true
     * description: The scrollpane scrollbar policy
     *        enum: HORIZONTAL_SCROLLBAR_AS_NEEDED ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED
     *              HORIZONTAL_SCROLLBAR_NEVER ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
     *              HORIZONTAL_SCROLLBAR_ALWAYS ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS
     */
    public void setHorizontalScrollBarPolicy(int policy) {
        switch (policy) {
        case HORIZONTAL_SCROLLBAR_AS_NEEDED:
        case HORIZONTAL_SCROLLBAR_NEVER:
        case HORIZONTAL_SCROLLBAR_ALWAYS:
                break;
        default:
            throw new IllegalArgumentException("invalid horizontalScrollBarPolicy");
        }
        int old = horizontalScrollBarPolicy;
        horizontalScrollBarPolicy = policy;
        firePropertyChange("horizontalScrollBarPolicy", old, policy);
        revalidate();
        repaint();
    }


    /**
     * Returns the <code>Border</code> object that surrounds the viewport.
     *
     * @return the <code>viewportBorder</code> property
     * @see #setViewportBorder
     */
    public Border getViewportBorder() {
        return viewportBorder;
    }


    /**
     * Adds a border around the viewport.  Note that the border isn't
     * set on the viewport directly, <code>JViewport</code> doesn't support
     * the <code>JComponent</code> border property.
     * Similarly setting the <code>JScrollPane</code>s
     * viewport doesn't affect the <code>viewportBorder</code> property.
     * <p>
     * The default value of this property is computed by the look
     * and feel implementation.
     *
     * @param viewportBorder the border to be added
     * @see #getViewportBorder
     * @see #setViewport
     *
     * @beaninfo
     *   preferred: true
     *       bound: true
     * description: The border around the viewport.
     */
    public void setViewportBorder(Border viewportBorder) {
        Border oldValue = this.viewportBorder;
        this.viewportBorder = viewportBorder;
        firePropertyChange("viewportBorder", oldValue, viewportBorder);
    }


    /**
     * Returns the bounds of the viewport's border.
     *
     * @return a <code>Rectangle</code> object specifying the viewport border
     */
    public Rectangle getViewportBorderBounds()
    {
        Rectangle borderR = new Rectangle(getSize());

        Insets insets = getInsets();
        borderR.x = insets.left;
        borderR.y = insets.top;
        borderR.width -= insets.left + insets.right;
        borderR.height -= insets.top + insets.bottom;

        boolean leftToRight = SwingUtilities.isLeftToRight(this);

        /* If there's a visible column header remove the space it
         * needs from the top of borderR.
         */

        JViewport colHead = getColumnHeader();
        if ((colHead != null) && (colHead.isVisible())) {
            int colHeadHeight = colHead.getHeight();
            borderR.y += colHeadHeight;
            borderR.height -= colHeadHeight;
        }

        /* If there's a visible row header remove the space it needs
         * from the left of borderR.
         */

        JViewport rowHead = getRowHeader();
        if ((rowHead != null) && (rowHead.isVisible())) {
            int rowHeadWidth = rowHead.getWidth();
            if ( leftToRight ) {
                borderR.x += rowHeadWidth;
            }
            borderR.width -= rowHeadWidth;
        }

        /* If there's a visible vertical scrollbar remove the space it needs
         * from the width of borderR.
         */
        JScrollBar vsb = getVerticalScrollBar();
        if ((vsb != null) && (vsb.isVisible())) {
            int vsbWidth = vsb.getWidth();
            if ( !leftToRight ) {
                borderR.x += vsbWidth;
            }
            borderR.width -= vsbWidth;
        }

        /* If there's a visible horizontal scrollbar remove the space it needs
         * from the height of borderR.
         */
        JScrollBar hsb = getHorizontalScrollBar();
        if ((hsb != null) && (hsb.isVisible())) {
            borderR.height -= hsb.getHeight();
        }

        return borderR;
    }


    /**
     * By default <code>JScrollPane</code> creates scrollbars
     * that are instances
     * of this class.  <code>Scrollbar</code> overrides the
     * <code>getUnitIncrement</code> and <code>getBlockIncrement</code>
     * methods so that, if the viewport's view is a <code>Scrollable</code>,
     * the view is asked to compute these values. Unless
     * the unit/block increment have been explicitly set.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     *
     * @see Scrollable
     * @see JScrollPane#createVerticalScrollBar
     * @see JScrollPane#createHorizontalScrollBar
     */
    protected class ScrollBar extends JScrollBar implements UIResource
    {
        /**
         * Set to true when the unit increment has been explicitly set.
         * If this is false the viewport's view is obtained and if it
         * is an instance of <code>Scrollable</code> the unit increment
         * from it is used.
         */
        private boolean unitIncrementSet;
        /**
         * Set to true when the block increment has been explicitly set.
         * If this is false the viewport's view is obtained and if it
         * is an instance of <code>Scrollable</code> the block increment
         * from it is used.
         */
        private boolean blockIncrementSet;

        /**
         * Creates a scrollbar with the specified orientation.
         * The options are:
         * <ul>
         * <li><code>ScrollPaneConstants.VERTICAL</code>
         * <li><code>ScrollPaneConstants.HORIZONTAL</code>
         * </ul>
         *
         * @param orientation  an integer specifying one of the legal
         *      orientation values shown above
         * @since 1.4
         */
        public ScrollBar(int orientation) {
            super(orientation);
            this.putClientProperty("JScrollBar.fastWheelScrolling",
                                   Boolean.TRUE);
        }

        /**
         * Messages super to set the value, and resets the
         * <code>unitIncrementSet</code> instance variable to true.
         *
         * @param unitIncrement the new unit increment value, in pixels
         */
        public void setUnitIncrement(int unitIncrement) {
            unitIncrementSet = true;
            this.putClientProperty("JScrollBar.fastWheelScrolling", null);
            super.setUnitIncrement(unitIncrement);
        }

        /**
         * Computes the unit increment for scrolling if the viewport's
         * view is a <code>Scrollable</code> object.
         * Otherwise return <code>super.getUnitIncrement</code>.
         *
         * @param direction less than zero to scroll up/left,
         *      greater than zero for down/right
         * @return an integer, in pixels, containing the unit increment
         * @see Scrollable#getScrollableUnitIncrement
         */
        public int getUnitIncrement(int direction) {
            JViewport vp = getViewport();
            if (!unitIncrementSet && (vp != null) &&
                (vp.getView() instanceof Scrollable)) {
                Scrollable view = (Scrollable)(vp.getView());
                Rectangle vr = vp.getViewRect();
                return view.getScrollableUnitIncrement(vr, getOrientation(), direction);
            }
            else {
                return super.getUnitIncrement(direction);
            }
        }

        /**
         * Messages super to set the value, and resets the
         * <code>blockIncrementSet</code> instance variable to true.
         *
         * @param blockIncrement the new block increment value, in pixels
         */
        public void setBlockIncrement(int blockIncrement) {
            blockIncrementSet = true;
            this.putClientProperty("JScrollBar.fastWheelScrolling", null);
            super.setBlockIncrement(blockIncrement);
        }

        /**
         * Computes the block increment for scrolling if the viewport's
         * view is a <code>Scrollable</code> object.  Otherwise
         * the <code>blockIncrement</code> equals the viewport's width
         * or height.  If there's no viewport return
         * <code>super.getBlockIncrement</code>.
         *
         * @param direction less than zero to scroll up/left,
         *      greater than zero for down/right
         * @return an integer, in pixels, containing the block increment
         * @see Scrollable#getScrollableBlockIncrement
         */
        public int getBlockIncrement(int direction) {
            JViewport vp = getViewport();
            if (blockIncrementSet || vp == null) {
                return super.getBlockIncrement(direction);
            }
            else if (vp.getView() instanceof Scrollable) {
                Scrollable view = (Scrollable)(vp.getView());
                Rectangle vr = vp.getViewRect();
                return view.getScrollableBlockIncrement(vr, getOrientation(), direction);
            }
            else if (getOrientation() == VERTICAL) {
                return vp.getExtentSize().height;
            }
            else {
                return vp.getExtentSize().width;
            }
        }

    }


    /**
     * Returns a <code>JScrollPane.ScrollBar</code> by default.
     * Subclasses may override this method to force <code>ScrollPaneUI</code>
     * implementations to use a <code>JScrollBar</code> subclass.
     * Used by <code>ScrollPaneUI</code> implementations to
     * create the horizontal scrollbar.
     *
     * @return a <code>JScrollBar</code> with a horizontal orientation
     * @see JScrollBar
     */
    public JScrollBar createHorizontalScrollBar() {
        return new ScrollBar(JScrollBar.HORIZONTAL);
    }


    /**
     * Returns the horizontal scroll bar that controls the viewport's
     * horizontal view position.
     *
     * @return the <code>horizontalScrollBar</code> property
     * @see #setHorizontalScrollBar
     */
    @Transient
    public JScrollBar getHorizontalScrollBar() {
        return horizontalScrollBar;
    }


    /**
     * Adds the scrollbar that controls the viewport's horizontal view
     * position to the scrollpane.
     * This is usually unnecessary, as <code>JScrollPane</code> creates
     * horizontal and vertical scrollbars by default.
     *
     * @param horizontalScrollBar the horizontal scrollbar to be added
     * @see #createHorizontalScrollBar
     * @see #getHorizontalScrollBar
     *
     * @beaninfo
     *        expert: true
     *         bound: true
     *   description: The horizontal scrollbar.
     */
    public void setHorizontalScrollBar(JScrollBar horizontalScrollBar) {
        JScrollBar old = getHorizontalScrollBar();
        this.horizontalScrollBar = horizontalScrollBar;
        if (horizontalScrollBar != null) {
            add(horizontalScrollBar, HORIZONTAL_SCROLLBAR);
        }
        else if (old != null) {
            remove(old);
        }
        firePropertyChange("horizontalScrollBar", old, horizontalScrollBar);

        revalidate();
        repaint();
    }


    /**
     * Returns a <code>JScrollPane.ScrollBar</code> by default.  Subclasses
     * may override this method to force <code>ScrollPaneUI</code>
     * implementations to use a <code>JScrollBar</code> subclass.
     * Used by <code>ScrollPaneUI</code> implementations to create the
     * vertical scrollbar.
     *
     * @return a <code>JScrollBar</code> with a vertical orientation
     * @see JScrollBar
     */
    public JScrollBar createVerticalScrollBar() {
        return new ScrollBar(JScrollBar.VERTICAL);
    }


    /**
     * Returns the vertical scroll bar that controls the viewports
     * vertical view position.
     *
     * @return the <code>verticalScrollBar</code> property
     * @see #setVerticalScrollBar
     */
    @Transient
    public JScrollBar getVerticalScrollBar() {
        return verticalScrollBar;
    }


    /**
     * Adds the scrollbar that controls the viewports vertical view position
     * to the scrollpane.  This is usually unnecessary,
     * as <code>JScrollPane</code> creates vertical and
     * horizontal scrollbars by default.
     *
     * @param verticalScrollBar the new vertical scrollbar to be added
     * @see #createVerticalScrollBar
     * @see #getVerticalScrollBar
     *
     * @beaninfo
     *        expert: true
     *         bound: true
     *   description: The vertical scrollbar.
     */
    public void setVerticalScrollBar(JScrollBar verticalScrollBar) {
        JScrollBar old = getVerticalScrollBar();
        this.verticalScrollBar = verticalScrollBar;
        add(verticalScrollBar, VERTICAL_SCROLLBAR);
        firePropertyChange("verticalScrollBar", old, verticalScrollBar);

        revalidate();
        repaint();
    }


    /**
     * Returns a new <code>JViewport</code> by default.
     * Used to create the
     * viewport (as needed) in <code>setViewportView</code>,
     * <code>setRowHeaderView</code>, and <code>setColumnHeaderView</code>.
     * Subclasses may override this method to return a subclass of
     * <code>JViewport</code>.
     *
     * @return a new <code>JViewport</code>
     */
    protected JViewport createViewport() {
        return new JViewport();
    }


    /**
     * Returns the current <code>JViewport</code>.
     *
     * @see #setViewport
     * @return the <code>viewport</code> property
     */
    public JViewport getViewport() {
        return viewport;
    }


    /**
     * Removes the old viewport (if there is one); forces the
     * viewPosition of the new viewport to be in the +x,+y quadrant;
     * syncs up the row and column headers (if there are any) with the
     * new viewport; and finally syncs the scrollbars and
     * headers with the new viewport.
     * <p>
     * Most applications will find it more convenient to use
     * <code>setViewportView</code>
     * to add a viewport and a view to the scrollpane.
     *
     * @param viewport the new viewport to be used; if viewport is
     *          <code>null</code>, the old viewport is still removed
     *          and the new viewport is set to <code>null</code>
     * @see #createViewport
     * @see #getViewport
     * @see #setViewportView
     *
     * @beaninfo
     *       expert: true
     *        bound: true
     *    attribute: visualUpdate true
     *  description: The viewport child for this scrollpane
     *
     */
    public void setViewport(JViewport viewport) {
        JViewport old = getViewport();
        this.viewport = viewport;
        if (viewport != null) {
            add(viewport, VIEWPORT);
        }
        else if (old != null) {
            remove(old);
        }
        firePropertyChange("viewport", old, viewport);

        if (accessibleContext != null) {
            ((AccessibleJScrollPane)accessibleContext).resetViewPort();
        }

        revalidate();
        repaint();
    }


    /**
     * Creates a viewport if necessary and then sets its view.  Applications
     * that don't provide the view directly to the <code>JScrollPane</code>
     * constructor
     * should use this method to specify the scrollable child that's going
     * to be displayed in the scrollpane. For example:
     * <pre>
     * JScrollPane scrollpane = new JScrollPane();
     * scrollpane.setViewportView(myBigComponentToScroll);
     * </pre>
     * Applications should not add children directly to the scrollpane.
     *
     * @param view the component to add to the viewport
     * @see #setViewport
     * @see JViewport#setView
     */
    public void setViewportView(Component view) {
        if (getViewport() == null) {
            setViewport(createViewport());
        }
        getViewport().setView(view);
    }



    /**
     * Returns the row header.
     * @return the <code>rowHeader</code> property
     * @see #setRowHeader
     */
    @Transient
    public JViewport getRowHeader() {
        return rowHeader;
    }


    /**
     * Removes the old rowHeader, if it exists; if the new rowHeader
     * isn't <code>null</code>, syncs the y coordinate of its
     * viewPosition with
     * the viewport (if there is one) and then adds it to the scroll pane.
     * <p>
     * Most applications will find it more convenient to use
     * <code>setRowHeaderView</code>
     * to add a row header component and its viewport to the scroll pane.
     *
     * @param rowHeader the new row header to be used; if <code>null</code>
     *          the old row header is still removed and the new rowHeader
     *          is set to <code>null</code>
     * @see #getRowHeader
     * @see #setRowHeaderView
     *
     * @beaninfo
     *        bound: true
     *       expert: true
     *  description: The row header child for this scrollpane
     */
    public void setRowHeader(JViewport rowHeader) {
        JViewport old = getRowHeader();
        this.rowHeader = rowHeader;
        if (rowHeader != null) {
            add(rowHeader, ROW_HEADER);
        }
        else if (old != null) {
            remove(old);
        }
        firePropertyChange("rowHeader", old, rowHeader);
        revalidate();
        repaint();
    }


    /**
     * Creates a row-header viewport if necessary, sets
     * its view and then adds the row-header viewport
     * to the scrollpane.  For example:
     * <pre>
     * JScrollPane scrollpane = new JScrollPane();
     * scrollpane.setViewportView(myBigComponentToScroll);
     * scrollpane.setRowHeaderView(myBigComponentsRowHeader);
     * </pre>
     *
     * @see #setRowHeader
     * @see JViewport#setView
     * @param view the component to display as the row header
     */
    public void setRowHeaderView(Component view) {
        if (getRowHeader() == null) {
            setRowHeader(createViewport());
        }
        getRowHeader().setView(view);
    }



    /**
     * Returns the column header.
     * @return the <code>columnHeader</code> property
     * @see #setColumnHeader
     */
    @Transient
    public JViewport getColumnHeader() {
        return columnHeader;
    }


    /**
     * Removes the old columnHeader, if it exists; if the new columnHeader
     * isn't <code>null</code>, syncs the x coordinate of its viewPosition
     * with the viewport (if there is one) and then adds it to the scroll pane.
     * <p>
     * Most applications will find it more convenient to use
     * <code>setColumnHeaderView</code>
     * to add a column header component and its viewport to the scroll pane.
     *
     * @see #getColumnHeader
     * @see #setColumnHeaderView
     *
     * @beaninfo
     *        bound: true
     *  description: The column header child for this scrollpane
     *    attribute: visualUpdate true
     */
    public void setColumnHeader(JViewport columnHeader) {
        JViewport old = getColumnHeader();
        this.columnHeader = columnHeader;
        if (columnHeader != null) {
            add(columnHeader, COLUMN_HEADER);
        }
        else if (old != null) {
            remove(old);
        }
        firePropertyChange("columnHeader", old, columnHeader);

        revalidate();
        repaint();
    }



    /**
     * Creates a column-header viewport if necessary, sets
     * its view, and then adds the column-header viewport
     * to the scrollpane.  For example:
     * <pre>
     * JScrollPane scrollpane = new JScrollPane();
     * scrollpane.setViewportView(myBigComponentToScroll);
     * scrollpane.setColumnHeaderView(myBigComponentsColumnHeader);
     * </pre>
     *
     * @see #setColumnHeader
     * @see JViewport#setView
     *
     * @param view the component to display as the column header
     */
    public void setColumnHeaderView(Component view) {
        if (getColumnHeader() == null) {
            setColumnHeader(createViewport());
        }
        getColumnHeader().setView(view);
    }


    /**
     * Returns the component at the specified corner. The
     * <code>key</code> value specifying the corner is one of:
     * <ul>
     * <li>ScrollPaneConstants.LOWER_LEFT_CORNER
     * <li>ScrollPaneConstants.LOWER_RIGHT_CORNER
     * <li>ScrollPaneConstants.UPPER_LEFT_CORNER
     * <li>ScrollPaneConstants.UPPER_RIGHT_CORNER
     * <li>ScrollPaneConstants.LOWER_LEADING_CORNER
     * <li>ScrollPaneConstants.LOWER_TRAILING_CORNER
     * <li>ScrollPaneConstants.UPPER_LEADING_CORNER
     * <li>ScrollPaneConstants.UPPER_TRAILING_CORNER
     * </ul>
     *
     * @param key one of the values as shown above
     * @return the corner component (which may be <code>null</code>)
     *         identified by the given key, or <code>null</code>
     *         if the key is invalid
     * @see #setCorner
     */
    public Component getCorner(String key) {
        boolean isLeftToRight = getComponentOrientation().isLeftToRight();
        if (key.equals(LOWER_LEADING_CORNER)) {
            key = isLeftToRight ? LOWER_LEFT_CORNER : LOWER_RIGHT_CORNER;
        } else if (key.equals(LOWER_TRAILING_CORNER)) {
            key = isLeftToRight ? LOWER_RIGHT_CORNER : LOWER_LEFT_CORNER;
        } else if (key.equals(UPPER_LEADING_CORNER)) {
            key = isLeftToRight ? UPPER_LEFT_CORNER : UPPER_RIGHT_CORNER;
        } else if (key.equals(UPPER_TRAILING_CORNER)) {
            key = isLeftToRight ? UPPER_RIGHT_CORNER : UPPER_LEFT_CORNER;
        }
        if (key.equals(LOWER_LEFT_CORNER)) {
            return lowerLeft;
        }
        else if (key.equals(LOWER_RIGHT_CORNER)) {
            return lowerRight;
        }
        else if (key.equals(UPPER_LEFT_CORNER)) {
            return upperLeft;
        }
        else if (key.equals(UPPER_RIGHT_CORNER)) {
            return upperRight;
        }
        else {
            return null;
        }
    }


    /**
     * Adds a child that will appear in one of the scroll panes
     * corners, if there's room.   For example with both scrollbars
     * showing (on the right and bottom edges of the scrollpane)
     * the lower left corner component will be shown in the space
     * between ends of the two scrollbars. Legal values for
     * the <b>key</b> are:
     * <ul>
     * <li>ScrollPaneConstants.LOWER_LEFT_CORNER
     * <li>ScrollPaneConstants.LOWER_RIGHT_CORNER
     * <li>ScrollPaneConstants.UPPER_LEFT_CORNER
     * <li>ScrollPaneConstants.UPPER_RIGHT_CORNER
     * <li>ScrollPaneConstants.LOWER_LEADING_CORNER
     * <li>ScrollPaneConstants.LOWER_TRAILING_CORNER
     * <li>ScrollPaneConstants.UPPER_LEADING_CORNER
     * <li>ScrollPaneConstants.UPPER_TRAILING_CORNER
     * </ul>
     * <p>
     * Although "corner" doesn't match any beans property
     * signature, <code>PropertyChange</code> events are generated with the
     * property name set to the corner key.
     *
     * @param key identifies which corner the component will appear in
     * @param corner one of the following components:
     * <ul>
     * <li>lowerLeft
     * <li>lowerRight
     * <li>upperLeft
     * <li>upperRight
     * </ul>
     * @exception IllegalArgumentException if corner key is invalid
     */
    public void setCorner(String key, Component corner)
    {
        Component old;
        boolean isLeftToRight = getComponentOrientation().isLeftToRight();
        if (key.equals(LOWER_LEADING_CORNER)) {
            key = isLeftToRight ? LOWER_LEFT_CORNER : LOWER_RIGHT_CORNER;
        } else if (key.equals(LOWER_TRAILING_CORNER)) {
            key = isLeftToRight ? LOWER_RIGHT_CORNER : LOWER_LEFT_CORNER;
        } else if (key.equals(UPPER_LEADING_CORNER)) {
            key = isLeftToRight ? UPPER_LEFT_CORNER : UPPER_RIGHT_CORNER;
        } else if (key.equals(UPPER_TRAILING_CORNER)) {
            key = isLeftToRight ? UPPER_RIGHT_CORNER : UPPER_LEFT_CORNER;
        }
        if (key.equals(LOWER_LEFT_CORNER)) {
            old = lowerLeft;
            lowerLeft = corner;
        }
        else if (key.equals(LOWER_RIGHT_CORNER)) {
            old = lowerRight;
            lowerRight = corner;
        }
        else if (key.equals(UPPER_LEFT_CORNER)) {
            old = upperLeft;
            upperLeft = corner;
        }
        else if (key.equals(UPPER_RIGHT_CORNER)) {
            old = upperRight;
            upperRight = corner;
        }
        else {
            throw new IllegalArgumentException("invalid corner key");
        }
        if (old != null) {
            remove(old);
        }
        if (corner != null) {
            add(corner, key);
        }
        firePropertyChange(key, old, corner);
        revalidate();
        repaint();
    }

    /**
     * Sets the orientation for the vertical and horizontal
     * scrollbars as determined by the
     * <code>ComponentOrientation</code> argument.
     *
     * @param  co one of the following values:
     * <ul>
     * <li>java.awt.ComponentOrientation.LEFT_TO_RIGHT
     * <li>java.awt.ComponentOrientation.RIGHT_TO_LEFT
     * <li>java.awt.ComponentOrientation.UNKNOWN
     * </ul>
     * @see java.awt.ComponentOrientation
     */
    public void setComponentOrientation( ComponentOrientation co ) {
        super.setComponentOrientation( co );
        if( verticalScrollBar != null )
            verticalScrollBar.setComponentOrientation( co );
        if( horizontalScrollBar != null )
            horizontalScrollBar.setComponentOrientation( co );
    }

    /**
     * Indicates whether or not scrolling will take place in response to the
     * mouse wheel.  Wheel scrolling is enabled by default.
     *
     * @see #setWheelScrollingEnabled
     * @since 1.4
     * @beaninfo
     *       bound: true
     * description: Flag for enabling/disabling mouse wheel scrolling
     */
    public boolean isWheelScrollingEnabled() {return wheelScrollState;}

    /**
     * Enables/disables scrolling in response to movement of the mouse wheel.
     * Wheel scrolling is enabled by default.
     *
     * @param handleWheel   <code>true</code> if scrolling should be done
     *                      automatically for a MouseWheelEvent,
     *                      <code>false</code> otherwise.
     * @see #isWheelScrollingEnabled
     * @see java.awt.event.MouseWheelEvent
     * @see java.awt.event.MouseWheelListener
     * @since 1.4
     * @beaninfo
     *       bound: true
     * description: Flag for enabling/disabling mouse wheel scrolling
     */
    public void setWheelScrollingEnabled(boolean handleWheel) {
        boolean old = wheelScrollState;
        wheelScrollState = handleWheel;
        firePropertyChange("wheelScrollingEnabled", old, handleWheel);
    }

    /**
     * See <code>readObject</code> and <code>writeObject</code> in
     * <code>JComponent</code> for more
     * information about serialization in Swing.
     */
    private void writeObject(ObjectOutputStream s) throws IOException {
        s.defaultWriteObject();
        if (getUIClassID().equals(uiClassID)) {
            byte count = JComponent.getWriteObjCounter(this);
            JComponent.setWriteObjCounter(this, --count);
            if (count == 0 && ui != null) {
                ui.installUI(this);
            }
        }
    }


    /**
     * Returns a string representation of this <code>JScrollPane</code>.
     * This method
     * is intended to be used only for debugging purposes, and the
     * content and format of the returned string may vary between
     * implementations. The returned string may be empty but may not
     * be <code>null</code>.
     *
     * @return  a string representation of this <code>JScrollPane</code>.
     */
    protected String paramString() {
        String viewportBorderString = (viewportBorder != null ?
                                       viewportBorder.toString() : "");
        String viewportString = (viewport != null ?
                                 viewport.toString() : "");
        String verticalScrollBarPolicyString;
        if (verticalScrollBarPolicy == VERTICAL_SCROLLBAR_AS_NEEDED) {
            verticalScrollBarPolicyString = "VERTICAL_SCROLLBAR_AS_NEEDED";
        } else if (verticalScrollBarPolicy == VERTICAL_SCROLLBAR_NEVER) {
            verticalScrollBarPolicyString = "VERTICAL_SCROLLBAR_NEVER";
        } else if (verticalScrollBarPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
            verticalScrollBarPolicyString = "VERTICAL_SCROLLBAR_ALWAYS";
        } else verticalScrollBarPolicyString = "";
        String horizontalScrollBarPolicyString;
        if (horizontalScrollBarPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED) {
            horizontalScrollBarPolicyString = "HORIZONTAL_SCROLLBAR_AS_NEEDED";
        } else if (horizontalScrollBarPolicy == HORIZONTAL_SCROLLBAR_NEVER) {
            horizontalScrollBarPolicyString = "HORIZONTAL_SCROLLBAR_NEVER";
        } else if (horizontalScrollBarPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
            horizontalScrollBarPolicyString = "HORIZONTAL_SCROLLBAR_ALWAYS";
        } else horizontalScrollBarPolicyString = "";
        String horizontalScrollBarString = (horizontalScrollBar != null ?
                                            horizontalScrollBar.toString()
                                            : "");
        String verticalScrollBarString = (verticalScrollBar != null ?
                                          verticalScrollBar.toString() : "");
        String columnHeaderString = (columnHeader != null ?
                                     columnHeader.toString() : "");
        String rowHeaderString = (rowHeader != null ?
                                  rowHeader.toString() : "");
        String lowerLeftString = (lowerLeft != null ?
                                  lowerLeft.toString() : "");
        String lowerRightString = (lowerRight != null ?
                                  lowerRight.toString() : "");
        String upperLeftString = (upperLeft != null ?
                                  upperLeft.toString() : "");
        String upperRightString = (upperRight != null ?
                                  upperRight.toString() : "");

        return super.paramString() +
        ",columnHeader=" + columnHeaderString +
        ",horizontalScrollBar=" + horizontalScrollBarString +
        ",horizontalScrollBarPolicy=" + horizontalScrollBarPolicyString +
        ",lowerLeft=" + lowerLeftString +
        ",lowerRight=" + lowerRightString +
        ",rowHeader=" + rowHeaderString +
        ",upperLeft=" + upperLeftString +
        ",upperRight=" + upperRightString +
        ",verticalScrollBar=" + verticalScrollBarString +
        ",verticalScrollBarPolicy=" + verticalScrollBarPolicyString +
        ",viewport=" + viewportString +
        ",viewportBorder=" + viewportBorderString;
    }

/////////////////
// Accessibility support
////////////////

    /**
     * Gets the AccessibleContext associated with this JScrollPane.
     * For scroll panes, the AccessibleContext takes the form of an
     * AccessibleJScrollPane.
     * A new AccessibleJScrollPane instance is created if necessary.
     *
     * @return an AccessibleJScrollPane that serves as the
     *         AccessibleContext of this JScrollPane
     */
    public AccessibleContext getAccessibleContext() {
        if (accessibleContext == null) {
            accessibleContext = new AccessibleJScrollPane();
        }
        return accessibleContext;
    }

    /**
     * This class implements accessibility support for the
     * <code>JScrollPane</code> class.  It provides an implementation of the
     * Java Accessibility API appropriate to scroll pane user-interface
     * elements.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     */
    protected class AccessibleJScrollPane extends AccessibleJComponent
        implements ChangeListener, PropertyChangeListener {

        protected JViewport viewPort = null;

        /*
         * Resets the viewport ChangeListener and PropertyChangeListener
         */
        public void resetViewPort() {
            if (viewPort != null) {
                viewPort.removeChangeListener(this);
                viewPort.removePropertyChangeListener(this);
            }
            viewPort = JScrollPane.this.getViewport();
            if (viewPort != null) {
                viewPort.addChangeListener(this);
                viewPort.addPropertyChangeListener(this);
            }
        }

        /**
         * AccessibleJScrollPane constructor
         */
        public AccessibleJScrollPane() {
            super();

            resetViewPort();

            // initialize the AccessibleRelationSets for the JScrollPane
            // and JScrollBar(s)
            JScrollBar scrollBar = getHorizontalScrollBar();
            if (scrollBar != null) {
                setScrollBarRelations(scrollBar);
            }
            scrollBar = getVerticalScrollBar();
            if (scrollBar != null) {
                setScrollBarRelations(scrollBar);
            }
        }

        /**
         * Get the role of this object.
         *
         * @return an instance of AccessibleRole describing the role of the
         * object
         * @see AccessibleRole
         */
        public AccessibleRole getAccessibleRole() {
            return AccessibleRole.SCROLL_PANE;
        }

        /**
         * Invoked when the target of the listener has changed its state.
         *
         * @param e  a <code>ChangeEvent</code> object. Must not be null.
         *
         * @throws NullPointerException if the parameter is null.
         */
        public void stateChanged(ChangeEvent e) {
            if (e == null) {
                throw new NullPointerException();
            }
            firePropertyChange(ACCESSIBLE_VISIBLE_DATA_PROPERTY,
                               Boolean.valueOf(false),
                               Boolean.valueOf(true));
        }

        /**
         * This method gets called when a bound property is changed.
         * @param e A <code>PropertyChangeEvent</code> object describing
         * the event source and the property that has changed. Must not be null.
         *
         * @throws NullPointerException if the parameter is null.
         * @since 1.5
         */
        public void propertyChange(PropertyChangeEvent e) {
            String propertyName = e.getPropertyName();
            if (propertyName == "horizontalScrollBar" ||
                propertyName == "verticalScrollBar") {

                if (e.getNewValue() instanceof JScrollBar) {
                    setScrollBarRelations((JScrollBar)e.getNewValue());
                }
            }
        }


        /*
         * Sets the CONTROLLER_FOR and CONTROLLED_BY AccessibleRelations for
         * the JScrollPane and JScrollBar. JScrollBar must not be null.
         */
        void setScrollBarRelations(JScrollBar scrollBar) {
            /*
             * The JScrollBar is a CONTROLLER_FOR the JScrollPane.
             * The JScrollPane is CONTROLLED_BY the JScrollBar.
             */
            AccessibleRelation controlledBy =
                new AccessibleRelation(AccessibleRelation.CONTROLLED_BY,
                                       scrollBar);
            AccessibleRelation controllerFor =
                new AccessibleRelation(AccessibleRelation.CONTROLLER_FOR,
                                       JScrollPane.this);

            // set the relation set for the scroll bar
            AccessibleContext ac = scrollBar.getAccessibleContext();
            ac.getAccessibleRelationSet().add(controllerFor);

            // set the relation set for the scroll pane
            getAccessibleRelationSet().add(controlledBy);
        }
    }
}
