/*
 * 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 java.awt.*;
import java.awt.event.*;
import java.awt.image.VolatileImage;
import java.awt.peer.ComponentPeer;
import java.applet.Applet;
import java.beans.Transient;
import javax.swing.plaf.ViewportUI;

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


import java.io.Serializable;


/**
 * The "viewport" or "porthole" through which you see the underlying
 * information. When you scroll, what moves is the viewport. It is like
 * peering through a camera's viewfinder. Moving the viewfinder upwards
 * brings new things into view at the top of the picture and loses
 * things that were at the bottom.
 * <p>
 * By default, <code>JViewport</code> is opaque. To change this, use the
 * <code>setOpaque</code> method.
 * <p>
 * <b>NOTE:</b>We have implemented a faster scrolling algorithm that
 * does not require a buffer to draw in. The algorithm works as follows:
 * <ol><li>The view and parent view and checked to see if they are
 * <code>JComponents</code>,
 * if they aren't, stop and repaint the whole viewport.
 * <li>If the viewport is obscured by an ancestor, stop and repaint the whole
 * viewport.
 * <li>Compute the region that will become visible, if it is as big as
 * the viewport, stop and repaint the whole view region.
 * <li>Obtain the ancestor <code>Window</code>'s graphics and
 * do a <code>copyArea</code> on the scrolled region.
 * <li>Message the view to repaint the newly visible region.
 * <li>The next time paint is invoked on the viewport, if the clip region
 * is smaller than the viewport size a timer is kicked off to repaint the
 * whole region.
 * </ol>
 * In general this approach is much faster. Compared to the backing store
 * approach this avoids the overhead of maintaining an offscreen buffer and
 * having to do two <code>copyArea</code>s.
 * Compared to the non backing store case this
 * approach will greatly reduce the painted region.
 * <p>
 * This approach can cause slower times than the backing store approach
 * when the viewport is obscured by another window, or partially offscreen.
 * When another window
 * obscures the viewport the copyArea will copy garbage and a
 * paint event will be generated by the system to inform us we need to
 * paint the newly exposed region. The only way to handle this is to
 * repaint the whole viewport, which can cause slower performance than the
 * backing store case. In most applications very rarely will the user be
 * scrolling while the viewport is obscured by another window or offscreen,
 * so this optimization is usually worth the performance hit when obscured.
 * <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}.
 *
 * @author Hans Muller
 * @author Philip Milne
 * @see JScrollPane
 */
public class JViewport extends JComponent implements Accessible
{
    /**
     * @see #getUIClassID
     * @see #readObject
     */
    private static final String uiClassID = "ViewportUI";

    /** Property used to indicate window blitting should not be done.
     */
    static final Object EnableWindowBlit = "EnableWindowBlit";

    /**
     * True when the viewport dimensions have been determined.
     * The default is false.
     */
    protected boolean isViewSizeSet = false;

    /**
     * The last <code>viewPosition</code> that we've painted, so we know how
     * much of the backing store image is valid.
     */
    protected Point lastPaintPosition = null;

    /**
     * True when this viewport is maintaining an offscreen image of its
     * contents, so that some scrolling can take place using fast "bit-blit"
     * operations instead of by accessing the view object to construct the
     * display.  The default is <code>false</code>.
     *
     * @deprecated As of Java 2 platform v1.3
     * @see #setScrollMode
     */
    @Deprecated
    protected boolean backingStore = false;

    /** The view image used for a backing store. */
    transient protected Image backingStoreImage = null;

    /**
     * The <code>scrollUnderway</code> flag is used for components like
     * <code>JList</code>.  When the downarrow key is pressed on a
     * <code>JList</code> and the selected
     * cell is the last in the list, the <code>scrollpane</code> autoscrolls.
     * Here, the old selected cell needs repainting and so we need
     * a flag to make the viewport do the optimized painting
     * only when there is an explicit call to
     * <code>setViewPosition(Point)</code>.
     * When <code>setBounds</code> is called through other routes,
     * the flag is off and the view repaints normally.  Another approach
     * would be to remove this from the <code>JViewport</code>
     * class and have the <code>JList</code> manage this case by using
     * <code>setBackingStoreEnabled</code>.  The default is
     * <code>false</code>.
     */
    protected boolean scrollUnderway = false;

    /*
     * Listener that is notified each time the view changes size.
     */
    private ComponentListener viewListener = null;

    /* Only one <code>ChangeEvent</code> is needed per
     * <code>JViewport</code> instance since the
     * event's only (read-only) state is the source property.  The source
     * of events generated here is always "this".
     */
    private transient ChangeEvent changeEvent = null;

    /**
      * Use <code>graphics.copyArea</code> to implement scrolling.
      * This is the fastest for most applications.
      *
      * @see #setScrollMode
      * @since 1.3
      */
    public static final int BLIT_SCROLL_MODE = 1;

    /**
      * Draws viewport contents into an offscreen image.
      * This was previously the default mode for <code>JTable</code>.
      * This mode may offer advantages over "blit mode"
      * in some cases, but it requires a large chunk of extra RAM.
      *
      * @see #setScrollMode
      * @since 1.3
      */
    public static final int BACKINGSTORE_SCROLL_MODE = 2;

    /**
      * This mode uses the very simple method of redrawing the entire
      * contents of the scrollpane each time it is scrolled.
      * This was the default behavior in Swing 1.0 and Swing 1.1.
      * Either of the other two options will provide better performance
      * in most cases.
      *
      * @see #setScrollMode
      * @since 1.3
      */
    public static final int SIMPLE_SCROLL_MODE = 0;

    /**
      * @see #setScrollMode
      * @since 1.3
      */
    private int scrollMode = BLIT_SCROLL_MODE;

    //
    // Window blitting:
    //
    // As mentioned in the javadoc when using windowBlit a paint event
    // will be generated by the system if copyArea copies a non-visible
    // portion of the view (in other words, it copies garbage). We are
    // not guaranteed to receive the paint event before other mouse events,
    // so we can not be sure we haven't already copied garbage a bunch of
    // times to different parts of the view. For that reason when a blit
    // happens and the Component is obscured (the check for obscurity
    // is not supported on all platforms and is checked via ComponentPeer
    // methods) the ivar repaintAll is set to true. When paint is received
    // if repaintAll is true (we previously did a blit) it is set to
    // false, and if the clip region is smaller than the viewport
    // waitingForRepaint is set to true and a timer is started. When
    // the timer fires if waitingForRepaint is true, repaint is invoked.
    // In the mean time, if the view is asked to scroll and waitingForRepaint
    // is true, a blit will not happen, instead the non-backing store case
    // of scrolling will happen, which will reset waitingForRepaint.
    // waitingForRepaint is set to false in paint when the clip rect is
    // bigger (or equal) to the size of the viewport.
    // A Timer is used instead of just a repaint as it appeared to offer
    // better performance.


    /**
     * This is set to true in <code>setViewPosition</code>
     * if doing a window blit and the viewport is obscured.
     */
    private transient boolean repaintAll;

    /**
     * This is set to true in paint, if <code>repaintAll</code>
     * is true and the clip rectangle does not match the bounds.
     * If true, and scrolling happens the
     * repaint manager is not cleared which then allows for the repaint
     * previously invoked to succeed.
     */
    private transient boolean waitingForRepaint;

    /**
     * Instead of directly invoking repaint, a <code>Timer</code>
     * is started and when it fires, repaint is invoked.
     */
    private transient Timer repaintTimer;

    /**
     * Set to true in paintView when paint is invoked.
     */
    private transient boolean inBlitPaint;

    /**
     * Whether or not a valid view has been installed.
     */
    private boolean hasHadValidView;

    /** Creates a <code>JViewport</code>. */
    public JViewport() {
        super();
        setLayout(createLayoutManager());
        setOpaque(true);
        updateUI();
        setInheritsPopupMenu(true);
    }



    /**
     * Returns the L&F object that renders this component.
     *
     * @return a <code>ViewportUI</code> object
     * @since 1.3
     */
    public ViewportUI getUI() {
        return (ViewportUI)ui;
    }


    /**
     * Sets the L&F object that renders this component.
     *
     * @param ui  the <code>ViewportUI</code> L&F object
     * @see UIDefaults#getUI
     * @beaninfo
     *        bound: true
     *       hidden: true
     *    attribute: visualUpdate true
     *  description: The UI object that implements the Component's LookAndFeel.
     * @since 1.3
     */
    public void setUI(ViewportUI ui) {
        super.setUI(ui);
    }


    /**
     * Resets the UI property to a value from the current look and feel.
     *
     * @see JComponent#updateUI
     */
    public void updateUI() {
        setUI((ViewportUI)UIManager.getUI(this));
    }


    /**
     * Returns a string that specifies the name of the L&F class
     * that renders this component.
     *
     * @return the string "ViewportUI"
     *
     * @see JComponent#getUIClassID
     * @see UIDefaults#getUI
     */
    public String getUIClassID() {
        return uiClassID;
    }


    /**
     * Sets the <code>JViewport</code>'s one lightweight child,
     * which can be <code>null</code>.
     * (Since there is only one child which occupies the entire viewport,
     * the <code>constraints</code> and <code>index</code>
     * arguments are ignored.)
     *
     * @param child       the lightweight <code>child</code> of the viewport
     * @param constraints the <code>constraints</code> to be respected
     * @param index       the index
     * @see #setView
     */
    protected void addImpl(Component child, Object constraints, int index) {
      setView(child);
    }


    /**
     * Removes the <code>Viewport</code>s one lightweight child.
     *
     * @see #setView
     */
    public void remove(Component child) {
        child.removeComponentListener(viewListener);
        super.remove(child);
    }


    /**
     * Scrolls the view so that <code>Rectangle</code>
     * within the view becomes visible.
     * <p>
     * This attempts to validate the view before scrolling if the
     * view is currently not valid - <code>isValid</code> returns false.
     * To avoid excessive validation when the containment hierarchy is
     * being created this will not validate if one of the ancestors does not
     * have a peer, or there is no validate root ancestor, or one of the
     * ancestors is not a <code>Window</code> or <code>Applet</code>.
     * <p>
     * Note that this method will not scroll outside of the
     * valid viewport; for example, if <code>contentRect</code> is larger
     * than the viewport, scrolling will be confined to the viewport's
     * bounds.
     *
     * @param contentRect the <code>Rectangle</code> to display
     * @see JComponent#isValidateRoot
     * @see java.awt.Component#isValid
     * @see java.awt.Component#getPeer
     */
    public void scrollRectToVisible(Rectangle contentRect) {
        Component view = getView();

        if (view == null) {
            return;
        } else {
            if (!view.isValid()) {
                // If the view is not valid, validate. scrollRectToVisible
                // may fail if the view is not valid first, contentRect
                // could be bigger than invalid size.
                validateView();
            }
            int dx, dy;

            dx = positionAdjustment(getWidth(), contentRect.width, contentRect.x);
            dy = positionAdjustment(getHeight(), contentRect.height, contentRect.y);

            if (dx != 0 || dy != 0) {
                Point viewPosition = getViewPosition();
                Dimension viewSize = view.getSize();
                int startX = viewPosition.x;
                int startY = viewPosition.y;
                Dimension extent = getExtentSize();

                viewPosition.x -= dx;
                viewPosition.y -= dy;
                // Only constrain the location if the view is valid. If the
                // the view isn't valid, it typically indicates the view
                // isn't visible yet and most likely has a bogus size as will
                // we, and therefore we shouldn't constrain the scrolling
                if (view.isValid()) {
                    if (getParent().getComponentOrientation().isLeftToRight()) {
                        if (viewPosition.x + extent.width > viewSize.width) {
                            viewPosition.x = Math.max(0, viewSize.width - extent.width);
                        } else if (viewPosition.x < 0) {
                            viewPosition.x = 0;
                        }
                    } else {
                        if (extent.width > viewSize.width) {
                            viewPosition.x = viewSize.width - extent.width;
                        } else {
                            viewPosition.x = Math.max(0, Math.min(viewSize.width - extent.width, viewPosition.x));
                        }
                    }
                    if (viewPosition.y + extent.height > viewSize.height) {
                        viewPosition.y = Math.max(0, viewSize.height -
                                                  extent.height);
                    }
                    else if (viewPosition.y < 0) {
                        viewPosition.y = 0;
                    }
                }
                if (viewPosition.x != startX || viewPosition.y != startY) {
                    setViewPosition(viewPosition);
                    // NOTE: How JViewport currently works with the
                    // backing store is not foolproof. The sequence of
                    // events when setViewPosition
                    // (scrollRectToVisible) is called is to reset the
                    // views bounds, which causes a repaint on the
                    // visible region and sets an ivar indicating
                    // scrolling (scrollUnderway). When
                    // JViewport.paint is invoked if scrollUnderway is
                    // true, the backing store is blitted.  This fails
                    // if between the time setViewPosition is invoked
                    // and paint is received another repaint is queued
                    // indicating part of the view is invalid. There
                    // is no way for JViewport to notice another
                    // repaint has occured and it ends up blitting
                    // what is now a dirty region and the repaint is
                    // never delivered.
                    // It just so happens JTable encounters this
                    // behavior by way of scrollRectToVisible, for
                    // this reason scrollUnderway is set to false
                    // here, which effectively disables the backing
                    // store.
                    scrollUnderway = false;
                }
            }
        }
    }

    /**
     * Ascends the <code>Viewport</code>'s parents stopping when
     * a component is found that returns
     * <code>true</code> to <code>isValidateRoot</code>.
     * If all the <code>Component</code>'s  parents are visible,
     * <code>validate</code> will then be invoked on it. The
     * <code>RepaintManager</code> is then invoked with
     * <code>removeInvalidComponent</code>. This
     * is the synchronous version of a <code>revalidate</code>.
     */
    private void validateView() {
        Component validateRoot = SwingUtilities.getValidateRoot(this, false);

        if (validateRoot == null) {
            return;
        }

        // Validate the root.
        validateRoot.validate();

        // And let the RepaintManager it does not have to validate from
        // validateRoot anymore.
        RepaintManager rm = RepaintManager.currentManager(this);

        if (rm != null) {
            rm.removeInvalidComponent((JComponent)validateRoot);
        }
    }

     /*  Used by the scrollRectToVisible method to determine the
      *  proper direction and amount to move by. The integer variables are named
      *  width, but this method is applicable to height also. The code assumes that
      *  parentWidth/childWidth are positive and childAt can be negative.
      */
    private int positionAdjustment(int parentWidth, int childWidth, int childAt)    {

        //   +-----+
        //   | --- |     No Change
        //   +-----+
        if (childAt >= 0 && childWidth + childAt <= parentWidth)    {
            return 0;
        }

        //   +-----+
        //  ---------   No Change
        //   +-----+
        if (childAt <= 0 && childWidth + childAt >= parentWidth) {
            return 0;
        }

        //   +-----+          +-----+
        //   |   ----    ->   | ----|
        //   +-----+          +-----+
        if (childAt > 0 && childWidth <= parentWidth)    {
            return -childAt + parentWidth - childWidth;
        }

        //   +-----+             +-----+
        //   |  --------  ->     |--------
        //   +-----+             +-----+
        if (childAt >= 0 && childWidth >= parentWidth)   {
            return -childAt;
        }

        //   +-----+          +-----+
        // ----    |     ->   |---- |
        //   +-----+          +-----+
        if (childAt <= 0 && childWidth <= parentWidth)   {
            return -childAt;
        }

        //   +-----+             +-----+
        //-------- |      ->   --------|
        //   +-----+             +-----+
        if (childAt < 0 && childWidth >= parentWidth)    {
            return -childAt + parentWidth - childWidth;
        }

        return 0;
    }


    /**
     * The viewport "scrolls" its child (called the "view") by the
     * normal parent/child clipping (typically the view is moved in
     * the opposite direction of the scroll).  A non-<code>null</code> border,
     * or non-zero insets, isn't supported, to prevent the geometry
     * of this component from becoming complex enough to inhibit
     * subclassing.  To create a <code>JViewport</code> with a border,
     * add it to a <code>JPanel</code> that has a border.
     * <p>Note:  If <code>border</code> is non-<code>null</code>, this
     * method will throw an exception as borders are not supported on
     * a <code>JViewPort</code>.
     *
     * @param border the <code>Border</code> to set
     * @exception IllegalArgumentException this method is not implemented
     */
    public final void setBorder(Border border) {
        if (border != null) {
            throw new IllegalArgumentException("JViewport.setBorder() not supported");
        }
    }


    /**
     * Returns the insets (border) dimensions as (0,0,0,0), since borders
     * are not supported on a <code>JViewport</code>.
     *
     * @return a <code>Rectange</code> of zero dimension and zero origin
     * @see #setBorder
     */
    public final Insets getInsets() {
        return new Insets(0, 0, 0, 0);
    }

    /**
     * Returns an <code>Insets</code> object containing this
     * <code>JViewport</code>s inset values.  The passed-in
     * <code>Insets</code> object will be reinitialized, and
     * all existing values within this object are overwritten.
     *
     * @param insets the <code>Insets</code> object which can be reused
     * @return this viewports inset values
     * @see #getInsets
     * @beaninfo
     *   expert: true
     */
    public final Insets getInsets(Insets insets) {
        insets.left = insets.top = insets.right = insets.bottom = 0;
        return insets;
    }


    private Graphics getBackingStoreGraphics(Graphics g) {
        Graphics bsg = backingStoreImage.getGraphics();
        bsg.setColor(g.getColor());
        bsg.setFont(g.getFont());
        bsg.setClip(g.getClipBounds());
        return bsg;
    }


    private void paintViaBackingStore(Graphics g) {
        Graphics bsg = getBackingStoreGraphics(g);
        try {
            super.paint(bsg);
            g.drawImage(backingStoreImage, 0, 0, this);
        } finally {
            bsg.dispose();
        }
    }

    private void paintViaBackingStore(Graphics g, Rectangle oClip) {
        Graphics bsg = getBackingStoreGraphics(g);
        try {
            super.paint(bsg);
            g.setClip(oClip);
            g.drawImage(backingStoreImage, 0, 0, this);
        } finally {
            bsg.dispose();
        }
    }

    /**
     * The <code>JViewport</code> overrides the default implementation of
     * this method (in <code>JComponent</code>) to return false.
     * This ensures
     * that the drawing machinery will call the <code>Viewport</code>'s
     * <code>paint</code>
     * implementation rather than messaging the <code>JViewport</code>'s
     * children directly.
     *
     * @return false
     */
    public boolean isOptimizedDrawingEnabled() {
        return false;
    }

    /**
     * Returns true if scroll mode is a BACKINGSTORE_SCROLL_MODE to cause
     * painting to originate from <code>JViewport</code>, or one of its
     * ancestors. Otherwise returns false.
     *
     * @return true if if scroll mode is a BACKINGSTORE_SCROLL_MODE.
     * @see JComponent#isPaintingOrigin()
     */
    boolean isPaintingOrigin() {
        return scrollMode == BACKINGSTORE_SCROLL_MODE;
    }


    /**
     * Only used by the paint method below.
     */
    private Point getViewLocation() {
        Component view = getView();
        if (view != null) {
            return view.getLocation();
        }
        else {
            return new Point(0,0);
        }
    }

    /**
     * Depending on whether the <code>backingStore</code> is enabled,
     * either paint the image through the backing store or paint
     * just the recently exposed part, using the backing store
     * to "blit" the remainder.
     * <blockquote>
     * The term "blit" is the pronounced version of the PDP-10
     * BLT (BLock Transfer) instruction, which copied a block of
     * bits. (In case you were curious.)
     * </blockquote>
     *
     * @param g the <code>Graphics</code> context within which to paint
     */
    public void paint(Graphics g)
    {
        int width = getWidth();
        int height = getHeight();

        if ((width <= 0) || (height <= 0)) {
            return;
        }

        if (inBlitPaint) {
            // We invoked paint as part of copyArea cleanup, let it through.
            super.paint(g);
            return;
        }

        if (repaintAll) {
            repaintAll = false;
            Rectangle clipB = g.getClipBounds();
            if (clipB.width < getWidth() ||
                clipB.height < getHeight()) {
                waitingForRepaint = true;
                if (repaintTimer == null) {
                    repaintTimer = createRepaintTimer();
                }
                repaintTimer.stop();
                repaintTimer.start();
                // We really don't need to paint, a future repaint will
                // take care of it, but if we don't we get an ugly flicker.
            }
            else {
                if (repaintTimer != null) {
                    repaintTimer.stop();
                }
                waitingForRepaint = false;
            }
        }
        else if (waitingForRepaint) {
            // Need a complete repaint before resetting waitingForRepaint
            Rectangle clipB = g.getClipBounds();
            if (clipB.width >= getWidth() &&
                clipB.height >= getHeight()) {
                waitingForRepaint = false;
                repaintTimer.stop();
            }
        }

        if (!backingStore || isBlitting() || getView() == null) {
            super.paint(g);
            lastPaintPosition = getViewLocation();
            return;
        }

        // If the view is smaller than the viewport and we are not opaque
        // (that is, we won't paint our background), we should set the
        // clip. Otherwise, as the bounds of the view vary, we will
        // blit garbage into the exposed areas.
        Rectangle viewBounds = getView().getBounds();
        if (!isOpaque()) {
            g.clipRect(0, 0, viewBounds.width, viewBounds.height);
        }

        if (backingStoreImage == null) {
            // Backing store is enabled but this is the first call to paint.
            // Create the backing store, paint it and then copy to g.
            // The backing store image will be created with the size of
            // the viewport. We must make sure the clip region is the
            // same size, otherwise when scrolling the backing image
            // the region outside of the clipped region will not be painted,
            // and result in empty areas.
            backingStoreImage = createImage(width, height);
            Rectangle clip = g.getClipBounds();
            if (clip.width != width || clip.height != height) {
                if (!isOpaque()) {
                    g.setClip(0, 0, Math.min(viewBounds.width, width),
                              Math.min(viewBounds.height, height));
                }
                else {
                    g.setClip(0, 0, width, height);
                }
                paintViaBackingStore(g, clip);
            }
            else {
                paintViaBackingStore(g);
            }
        }
        else {
            if (!scrollUnderway || lastPaintPosition.equals(getViewLocation())) {
                // No scrolling happened: repaint required area via backing store.
                paintViaBackingStore(g);
            } else {
                // The image was scrolled. Manipulate the backing store and flush it to g.
                Point blitFrom = new Point();
                Point blitTo = new Point();
                Dimension blitSize = new Dimension();
                Rectangle blitPaint = new Rectangle();

                Point newLocation = getViewLocation();
                int dx = newLocation.x - lastPaintPosition.x;
                int dy = newLocation.y - lastPaintPosition.y;
                boolean canBlit = computeBlit(dx, dy, blitFrom, blitTo, blitSize, blitPaint);
                if (!canBlit) {
                    // The image was either moved diagonally or
                    // moved by more than the image size: paint normally.
                    paintViaBackingStore(g);
                } else {
                    int bdx = blitTo.x - blitFrom.x;
                    int bdy = blitTo.y - blitFrom.y;

                    // Move the relevant part of the backing store.
                    Rectangle clip = g.getClipBounds();
                    // We don't want to inherit the clip region when copying
                    // bits, if it is inherited it will result in not moving
                    // all of the image resulting in garbage appearing on
                    // the screen.
                    g.setClip(0, 0, width, height);
                    Graphics bsg = getBackingStoreGraphics(g);
                    try {
                        bsg.copyArea(blitFrom.x, blitFrom.y, blitSize.width, blitSize.height, bdx, bdy);

                        g.setClip(clip.x, clip.y, clip.width, clip.height);
                        // Paint the rest of the view; the part that has just been exposed.
                        Rectangle r = viewBounds.intersection(blitPaint);
                        bsg.setClip(r);
                        super.paint(bsg);

                        // Copy whole of the backing store to g.
                        g.drawImage(backingStoreImage, 0, 0, this);
                    } finally {
                        bsg.dispose();
                    }
                }
            }
        }
        lastPaintPosition = getViewLocation();
        scrollUnderway = false;
    }


    /**
     * Sets the bounds of this viewport.  If the viewport's width
     * or height has changed, fire a <code>StateChanged</code> event.
     *
     * @param x left edge of the origin
     * @param y top edge of the origin
     * @param w width in pixels
     * @param h height in pixels
     *
     * @see JComponent#reshape(int, int, int, int)
     */
    public void reshape(int x, int y, int w, int h) {
        boolean sizeChanged = (getWidth() != w) || (getHeight() != h);
        if (sizeChanged) {
            backingStoreImage = null;
        }
        super.reshape(x, y, w, h);
        if (sizeChanged) {
            fireStateChanged();
        }
    }


    /**
      * Used to control the method of scrolling the viewport contents.
      * You may want to change this mode to get maximum performance for your
      * use case.
      *
      * @param mode one of the following values:
      * <ul>
      * <li> JViewport.BLIT_SCROLL_MODE
      * <li> JViewport.BACKINGSTORE_SCROLL_MODE
      * <li> JViewport.SIMPLE_SCROLL_MODE
      * </ul>
      *
      * @see #BLIT_SCROLL_MODE
      * @see #BACKINGSTORE_SCROLL_MODE
      * @see #SIMPLE_SCROLL_MODE
      *
      * @beaninfo
      *        bound: false
      *  description: Method of moving contents for incremental scrolls.
      *         enum: BLIT_SCROLL_MODE JViewport.BLIT_SCROLL_MODE
      *               BACKINGSTORE_SCROLL_MODE JViewport.BACKINGSTORE_SCROLL_MODE
      *               SIMPLE_SCROLL_MODE JViewport.SIMPLE_SCROLL_MODE
      *
      * @since 1.3
      */
    public void setScrollMode(int mode) {
        scrollMode = mode;
        backingStore = mode == BACKINGSTORE_SCROLL_MODE;
    }

    /**
      * Returns the current scrolling mode.
      *
      * @return the <code>scrollMode</code> property
      * @see #setScrollMode
      * @since 1.3
      */
    public int getScrollMode() {
        return scrollMode;
    }

    /**
     * Returns <code>true</code> if this viewport is maintaining
     * an offscreen image of its contents.
     *
     * @return <code>true</code> if <code>scrollMode</code> is
     *    <code>BACKINGSTORE_SCROLL_MODE</code>
     *
     * @deprecated As of Java 2 platform v1.3, replaced by
     *             <code>getScrollMode()</code>.
     */
    @Deprecated
    public boolean isBackingStoreEnabled() {
        return scrollMode == BACKINGSTORE_SCROLL_MODE;
    }


    /**
     * If true if this viewport will maintain an offscreen
     * image of its contents.  The image is used to reduce the cost
     * of small one dimensional changes to the <code>viewPosition</code>.
     * Rather than repainting the entire viewport we use
     * <code>Graphics.copyArea</code> to effect some of the scroll.
     *
     * @param enabled if true, maintain an offscreen backing store
     *
     * @deprecated As of Java 2 platform v1.3, replaced by
     *             <code>setScrollMode()</code>.
     */
    @Deprecated
    public void setBackingStoreEnabled(boolean enabled) {
        if (enabled) {
            setScrollMode(BACKINGSTORE_SCROLL_MODE);
        } else {
            setScrollMode(BLIT_SCROLL_MODE);
        }
    }

    private boolean isBlitting() {
        Component view = getView();
        return (scrollMode == BLIT_SCROLL_MODE) &&
               (view instanceof JComponent) && view.isOpaque();
    }


    /**
     * Returns the <code>JViewport</code>'s one child or <code>null</code>.
     *
     * @return the viewports child, or <code>null</code> if none exists
     *
     * @see #setView
     */
    public Component getView() {
        return (getComponentCount() > 0) ? getComponent(0) : null;
    }

    /**
     * Sets the <code>JViewport</code>'s one lightweight child
     * (<code>view</code>), which can be <code>null</code>.
     *
     * @param view the viewport's new lightweight child
     *
     * @see #getView
     */
    public void setView(Component view) {

        /* Remove the viewport's existing children, if any.
         * Note that removeAll() isn't used here because it
         * doesn't call remove() (which JViewport overrides).
         */
        int n = getComponentCount();
        for(int i = n - 1; i >= 0; i--) {
            remove(getComponent(i));
        }

        isViewSizeSet = false;

        if (view != null) {
            super.addImpl(view, null, -1);
            viewListener = createViewListener();
            view.addComponentListener(viewListener);
        }

        if (hasHadValidView) {
            // Only fire a change if a view has been installed.
            fireStateChanged();
        }
        else if (view != null) {
            hasHadValidView = true;
        }

        revalidate();
        repaint();
    }


    /**
     * If the view's size hasn't been explicitly set, return the
     * preferred size, otherwise return the view's current size.
     * If there is no view, return 0,0.
     *
     * @return a <code>Dimension</code> object specifying the size of the view
     */
    public Dimension getViewSize() {
        Component view = getView();

        if (view == null) {
            return new Dimension(0,0);
        }
        else if (isViewSizeSet) {
            return view.getSize();
        }
        else {
            return view.getPreferredSize();
        }
    }


    /**
     * Sets the size of the view.  A state changed event will be fired.
     *
     * @param newSize a <code>Dimension</code> object specifying the new
     *          size of the view
     */
    public void setViewSize(Dimension newSize) {
        Component view = getView();
        if (view != null) {
            Dimension oldSize = view.getSize();
            if (!newSize.equals(oldSize)) {
                // scrollUnderway will be true if this is invoked as the
                // result of a validate and setViewPosition was previously
                // invoked.
                scrollUnderway = false;
                view.setSize(newSize);
                isViewSizeSet = true;
                fireStateChanged();
            }
        }
    }

    /**
     * Returns the view coordinates that appear in the upper left
     * hand corner of the viewport, or 0,0 if there's no view.
     *
     * @return a <code>Point</code> object giving the upper left coordinates
     */
    public Point getViewPosition() {
        Component view = getView();
        if (view != null) {
            Point p = view.getLocation();
            p.x = -p.x;
            p.y = -p.y;
            return p;
        }
        else {
            return new Point(0,0);
        }
    }


    /**
     * Sets the view coordinates that appear in the upper left
     * hand corner of the viewport, does nothing if there's no view.
     *
     * @param p  a <code>Point</code> object giving the upper left coordinates
     */
    public void setViewPosition(Point p)
    {
        Component view = getView();
        if (view == null) {
            return;
        }

        int oldX, oldY, x = p.x, y = p.y;

        /* Collect the old x,y values for the views location
         * and do the song and dance to avoid allocating
         * a Rectangle object if we don't have to.
         */
        if (view instanceof JComponent) {
            JComponent c = (JComponent)view;
            oldX = c.getX();
            oldY = c.getY();
        }
        else {
            Rectangle r = view.getBounds();
            oldX = r.x;
            oldY = r.y;
        }

        /* The view scrolls in the opposite direction to mouse
         * movement.
         */
        int newX = -x;
        int newY = -y;

        if ((oldX != newX) || (oldY != newY)) {
            if (!waitingForRepaint && isBlitting() && canUseWindowBlitter()) {
                RepaintManager rm = RepaintManager.currentManager(this);
                // The cast to JComponent will work, if view is not
                // a JComponent, isBlitting will return false.
                JComponent jview = (JComponent)view;
                Rectangle dirty = rm.getDirtyRegion(jview);
                if (dirty == null || !dirty.contains(jview.getVisibleRect())) {
                    rm.beginPaint();
                    try {
                        Graphics g = JComponent.safelyGetGraphics(this);
                        flushViewDirtyRegion(g, dirty);
                        view.setLocation(newX, newY);
                        g.setClip(0,0,getWidth(), Math.min(getHeight(),
                                                           jview.getHeight()));
                        // Repaint the complete component if the blit succeeded
                        // and needsRepaintAfterBlit returns true.
                        repaintAll = (windowBlitPaint(g) &&
                                      needsRepaintAfterBlit());
                        g.dispose();
                        rm.markCompletelyClean((JComponent)getParent());
                        rm.markCompletelyClean(this);
                        rm.markCompletelyClean(jview);
                    } finally {
                        rm.endPaint();
                    }
                }
                else {
                    // The visible region is dirty, no point in doing copyArea
                    view.setLocation(newX, newY);
                    repaintAll = false;
                }
            }
            else {
                scrollUnderway = true;
                // This calls setBounds(), and then repaint().
                view.setLocation(newX, newY);
                repaintAll = false;
            }
            fireStateChanged();
        }
    }


    /**
     * Returns a rectangle whose origin is <code>getViewPosition</code>
     * and size is <code>getExtentSize</code>.
     * This is the visible part of the view, in view coordinates.
     *
     * @return a <code>Rectangle</code> giving the visible part of
     *          the view using view coordinates.
     */
    public Rectangle getViewRect() {
        return new Rectangle(getViewPosition(), getExtentSize());
    }


    /**
     * Computes the parameters for a blit where the backing store image
     * currently contains <code>oldLoc</code> in the upper left hand corner
     * and we're scrolling to <code>newLoc</code>.
     * The parameters are modified
     * to return the values required for the blit.
     *
     * @param dx  the horizontal delta
     * @param dy  the vertical delta
     * @param blitFrom the <code>Point</code> we're blitting from
     * @param blitTo the <code>Point</code> we're blitting to
     * @param blitSize the <code>Dimension</code> of the area to blit
     * @param blitPaint the area to blit
     * @return  true if the parameters are modified and we're ready to blit;
     *          false otherwise
     */
    protected boolean computeBlit(
        int dx,
        int dy,
        Point blitFrom,
        Point blitTo,
        Dimension blitSize,
        Rectangle blitPaint)
    {
        int dxAbs = Math.abs(dx);
        int dyAbs = Math.abs(dy);
        Dimension extentSize = getExtentSize();

        if ((dx == 0) && (dy != 0) && (dyAbs < extentSize.height)) {
            if (dy < 0) {
                blitFrom.y = -dy;
                blitTo.y = 0;
                blitPaint.y = extentSize.height + dy;
            }
            else {
                blitFrom.y = 0;
                blitTo.y = dy;
                blitPaint.y = 0;
            }

            blitPaint.x = blitFrom.x = blitTo.x = 0;

            blitSize.width = extentSize.width;
            blitSize.height = extentSize.height - dyAbs;

            blitPaint.width = extentSize.width;
            blitPaint.height = dyAbs;

            return true;
        }

        else if ((dy == 0) && (dx != 0) && (dxAbs < extentSize.width)) {
            if (dx < 0) {
                blitFrom.x = -dx;
                blitTo.x = 0;
                blitPaint.x = extentSize.width + dx;
            }
            else {
                blitFrom.x = 0;
                blitTo.x = dx;
                blitPaint.x = 0;
            }

            blitPaint.y = blitFrom.y = blitTo.y = 0;

            blitSize.width = extentSize.width - dxAbs;
            blitSize.height = extentSize.height;

            blitPaint.width = dxAbs;
            blitPaint.height = extentSize.height;

            return true;
        }

        else {
            return false;
        }
    }


    /**
     * Returns the size of the visible part of the view in view coordinates.
     *
     * @return a <code>Dimension</code> object giving the size of the view
     */
    @Transient
    public Dimension getExtentSize() {
        return getSize();
    }


    /**
     * Converts a size in pixel coordinates to view coordinates.
     * Subclasses of viewport that support "logical coordinates"
     * will override this method.
     *
     * @param size  a <code>Dimension</code> object using pixel coordinates
     * @return a <code>Dimension</code> object converted to view coordinates
     */
    public Dimension toViewCoordinates(Dimension size) {
        return new Dimension(size);
    }

    /**
     * Converts a point in pixel coordinates to view coordinates.
     * Subclasses of viewport that support "logical coordinates"
     * will override this method.
     *
     * @param p  a <code>Point</code> object using pixel coordinates
     * @return a <code>Point</code> object converted to view coordinates
     */
    public Point toViewCoordinates(Point p) {
        return new Point(p);
    }


    /**
     * Sets the size of the visible part of the view using view coordinates.
     *
     * @param newExtent  a <code>Dimension</code> object specifying
     *          the size of the view
     */
    public void setExtentSize(Dimension newExtent) {
        Dimension oldExtent = getExtentSize();
        if (!newExtent.equals(oldExtent)) {
            setSize(newExtent);
            fireStateChanged();
        }
    }

    /**
     * A listener for the view.
     * <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 ViewListener extends ComponentAdapter implements Serializable
    {
        public void componentResized(ComponentEvent e) {
            fireStateChanged();
            revalidate();
        }
    }

    /**
     * Creates a listener for the view.
     * @return a <code>ViewListener</code>
     */
    protected ViewListener createViewListener() {
        return new ViewListener();
    }


    /**
     * Subclassers can override this to install a different
     * layout manager (or <code>null</code>) in the constructor.  Returns
     * the <code>LayoutManager</code> to install on the <code>JViewport</code>.
     *
     * @return a <code>LayoutManager</code>
     */
    protected LayoutManager createLayoutManager() {
        return ViewportLayout.SHARED_INSTANCE;
    }


    /**
     * Adds a <code>ChangeListener</code> to the list that is
     * notified each time the view's
     * size, position, or the viewport's extent size has changed.
     *
     * @param l the <code>ChangeListener</code> to add
     * @see #removeChangeListener
     * @see #setViewPosition
     * @see #setViewSize
     * @see #setExtentSize
     */
    public void addChangeListener(ChangeListener l) {
        listenerList.add(ChangeListener.class, l);
    }

    /**
     * Removes a <code>ChangeListener</code> from the list that's notified each
     * time the views size, position, or the viewports extent size
     * has changed.
     *
     * @param l the <code>ChangeListener</code> to remove
     * @see #addChangeListener
     */
    public void removeChangeListener(ChangeListener l) {
        listenerList.remove(ChangeListener.class, l);
    }

    /**
     * Returns an array of all the <code>ChangeListener</code>s added
     * to this JViewport with addChangeListener().
     *
     * @return all of the <code>ChangeListener</code>s added or an empty
     *         array if no listeners have been added
     * @since 1.4
     */
    public ChangeListener[] getChangeListeners() {
        return listenerList.getListeners(ChangeListener.class);
    }

    /**
     * Notifies all <code>ChangeListeners</code> when the views
     * size, position, or the viewports extent size has changed.
     *
     * @see #addChangeListener
     * @see #removeChangeListener
     * @see EventListenerList
     */
    protected void fireStateChanged()
    {
        Object[] listeners = listenerList.getListenerList();
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i] == ChangeListener.class) {
                if (changeEvent == null) {
                    changeEvent = new ChangeEvent(this);
                }
                ((ChangeListener)listeners[i + 1]).stateChanged(changeEvent);
            }
        }
    }

    /**
     * Always repaint in the parents coordinate system to make sure
     * only one paint is performed by the <code>RepaintManager</code>.
     *
     * @param     tm   maximum time in milliseconds before update
     * @param     x    the <code>x</code> coordinate (pixels over from left)
     * @param     y    the <code>y</code> coordinate (pixels down from top)
     * @param     w    the width
     * @param     h   the height
     * @see       java.awt.Component#update(java.awt.Graphics)
     */
    public void repaint(long tm, int x, int y, int w, int h) {
        Container parent = getParent();
        if(parent != null)
            parent.repaint(tm,x+getX(),y+getY(),w,h);
        else
            super.repaint(tm,x,y,w,h);
    }


    /**
     * Returns a string representation of this <code>JViewport</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>JViewport</code>
     */
    protected String paramString() {
        String isViewSizeSetString = (isViewSizeSet ?
                                      "true" : "false");
        String lastPaintPositionString = (lastPaintPosition != null ?
                                          lastPaintPosition.toString() : "");
        String scrollUnderwayString = (scrollUnderway ?
                                       "true" : "false");

        return super.paramString() +
        ",isViewSizeSet=" + isViewSizeSetString +
        ",lastPaintPosition=" + lastPaintPositionString +
        ",scrollUnderway=" + scrollUnderwayString;
    }

    //
    // Following is used when doBlit is true.
    //

    /**
     * Notifies listeners of a property change. This is subclassed to update
     * the <code>windowBlit</code> property.
     * (The <code>putClientProperty</code> property is final).
     *
     * @param propertyName a string containing the property name
     * @param oldValue the old value of the property
     * @param newValue  the new value of the property
     */
    protected void firePropertyChange(String propertyName, Object oldValue,
                                      Object newValue) {
        super.firePropertyChange(propertyName, oldValue, newValue);
        if (propertyName.equals(EnableWindowBlit)) {
            if (newValue != null) {
                setScrollMode(BLIT_SCROLL_MODE);
            } else {
                setScrollMode(SIMPLE_SCROLL_MODE);
            }
        }
    }

    /**
     * Returns true if the component needs to be completely repainted after
     * a blit and a paint is received.
     */
    private boolean needsRepaintAfterBlit() {
        // Find the first heavy weight ancestor. isObscured and
        // canDetermineObscurity are only appropriate for heavy weights.
        Component heavyParent = getParent();

        while (heavyParent != null && heavyParent.isLightweight()) {
            heavyParent = heavyParent.getParent();
        }

        if (heavyParent != null) {
            ComponentPeer peer = heavyParent.getPeer();

            if (peer != null && peer.canDetermineObscurity() &&
                                !peer.isObscured()) {
                // The peer says we aren't obscured, therefore we can assume
                // that we won't later be messaged to paint a portion that
                // we tried to blit that wasn't valid.
                // It is certainly possible that when we blited we were
                // obscured, and by the time this is invoked we aren't, but the
                // chances of that happening are pretty slim.
                return false;
            }
        }
        return true;
    }

    private Timer createRepaintTimer() {
        Timer timer = new Timer(300, new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                // waitingForRepaint will be false if a paint came down
                // with the complete clip rect, in which case we don't
                // have to cause a repaint.
                if (waitingForRepaint) {
                    repaint();
                }
            }
        });
        timer.setRepeats(false);
        return timer;
    }

    /**
     * If the repaint manager has a dirty region for the view, the view is
     * asked to paint.
     *
     * @param g  the <code>Graphics</code> context within which to paint
     */
    private void flushViewDirtyRegion(Graphics g, Rectangle dirty) {
        JComponent view = (JComponent) getView();
        if(dirty != null && dirty.width > 0 && dirty.height > 0) {
            dirty.x += view.getX();
            dirty.y += view.getY();
            Rectangle clip = g.getClipBounds();
            if (clip == null) {
                // Only happens in 1.2
                g.setClip(0, 0, getWidth(), getHeight());
            }
            g.clipRect(dirty.x, dirty.y, dirty.width, dirty.height);
            clip = g.getClipBounds();
            // Only paint the dirty region if it is visible.
            if (clip.width > 0 && clip.height > 0) {
                paintView(g);
            }
        }
    }

    /**
     * Used when blitting.
     *
     * @param g  the <code>Graphics</code> context within which to paint
     * @return true if blitting succeeded; otherwise false
     */
    private boolean windowBlitPaint(Graphics g) {
        int width = getWidth();
        int height = getHeight();

        if ((width == 0) || (height == 0)) {
            return false;
        }

        boolean retValue;
        RepaintManager rm = RepaintManager.currentManager(this);
        JComponent view = (JComponent) getView();

        if (lastPaintPosition == null ||
            lastPaintPosition.equals(getViewLocation())) {
            paintView(g);
            retValue = false;
        } else {
            // The image was scrolled. Manipulate the backing store and flush
            // it to g.
            Point blitFrom = new Point();
            Point blitTo = new Point();
            Dimension blitSize = new Dimension();
            Rectangle blitPaint = new Rectangle();

            Point newLocation = getViewLocation();
            int dx = newLocation.x - lastPaintPosition.x;
            int dy = newLocation.y - lastPaintPosition.y;
            boolean canBlit = computeBlit(dx, dy, blitFrom, blitTo, blitSize,
                                          blitPaint);
            if (!canBlit) {
                paintView(g);
                retValue = false;
            } else {
                // Prepare the rest of the view; the part that has just been
                // exposed.
                Rectangle r = view.getBounds().intersection(blitPaint);
                r.x -= view.getX();
                r.y -= view.getY();

                blitDoubleBuffered(view, g, r.x, r.y, r.width, r.height,
                                   blitFrom.x, blitFrom.y, blitTo.x, blitTo.y,
                                   blitSize.width, blitSize.height);
                retValue = true;
            }
        }
        lastPaintPosition = getViewLocation();
        return retValue;
    }

    //
    // NOTE: the code below uses paintForceDoubleBuffered for historical
    // reasons.  If we're going to allow a blit we've already accounted for
    // everything that paintImmediately and _paintImmediately does, for that
    // reason we call into paintForceDoubleBuffered to diregard whether or
    // not setDoubleBuffered(true) was invoked on the view.
    //

    private void blitDoubleBuffered(JComponent view, Graphics g,
                                    int clipX, int clipY, int clipW, int clipH,
                                    int blitFromX, int blitFromY, int blitToX, int blitToY,
                                    int blitW, int blitH) {
        // NOTE:
        //   blitFrom/blitTo are in JViewport coordinates system
        //     not the views coordinate space.
        //   clip* are in the views coordinate space.
        RepaintManager rm = RepaintManager.currentManager(this);
        int bdx = blitToX - blitFromX;
        int bdy = blitToY - blitFromY;

        // Shift the scrolled region
        rm.copyArea(this, g, blitFromX, blitFromY, blitW, blitH, bdx, bdy,
                    false);

        // Paint the newly exposed region.
        int x = view.getX();
        int y = view.getY();
        g.translate(x, y);
        g.setClip(clipX, clipY, clipW, clipH);
        view.paintForceDoubleBuffered(g);
        g.translate(-x, -y);
    }

    /**
     * Called to paint the view, usually when <code>blitPaint</code>
     * can not blit.
     *
     * @param g the <code>Graphics</code> context within which to paint
     */
    private void paintView(Graphics g) {
        Rectangle clip = g.getClipBounds();
        JComponent view = (JComponent)getView();

        if (view.getWidth() >= getWidth()) {
            // Graphics is relative to JViewport, need to map to view's
            // coordinates space.
            int x = view.getX();
            int y = view.getY();
            g.translate(x, y);
            g.setClip(clip.x - x, clip.y - y, clip.width, clip.height);
            view.paintForceDoubleBuffered(g);
            g.translate(-x, -y);
            g.setClip(clip.x, clip.y, clip.width, clip.height);
        }
        else {
            // To avoid any problems that may result from the viewport being
            // bigger than the view we start painting from the viewport.
            try {
                inBlitPaint = true;
                paintForceDoubleBuffered(g);
            } finally {
                inBlitPaint = false;
            }
        }
    }

    /**
     * Returns true if the viewport is not obscured by one of its ancestors,
     * or its ancestors children and if the viewport is showing. Blitting
     * when the view isn't showing will work,
     * or rather <code>copyArea</code> will work,
     * but will not produce the expected behavior.
     */
    private boolean canUseWindowBlitter() {
        if (!isShowing() || (!(getParent() instanceof JComponent) &&
                             !(getView() instanceof JComponent))) {
            return false;
        }
        if (isPainting()) {
            // We're in the process of painting, don't blit. If we were
            // to blit we would draw on top of what we're already drawing,
            // so bail.
            return false;
        }

        Rectangle dirtyRegion = RepaintManager.currentManager(this).
                                getDirtyRegion((JComponent)getParent());

        if (dirtyRegion != null && dirtyRegion.width > 0 &&
            dirtyRegion.height > 0) {
            // Part of the scrollpane needs to be repainted too, don't blit.
            return false;
        }

        Rectangle clip = new Rectangle(0,0,getWidth(),getHeight());
        Rectangle oldClip = new Rectangle();
        Rectangle tmp2 = null;
        Container parent;
        Component lastParent = null;
        int x, y, w, h;

        for(parent = this; parent != null && isLightweightComponent(parent); parent = parent.getParent()) {
            x = parent.getX();
            y = parent.getY();
            w = parent.getWidth();
            h = parent.getHeight();

            oldClip.setBounds(clip);
            SwingUtilities.computeIntersection(0, 0, w, h, clip);
            if(!clip.equals(oldClip))
                return false;

            if(lastParent != null && parent instanceof JComponent &&
               !((JComponent)parent).isOptimizedDrawingEnabled()) {
                Component comps[] = parent.getComponents();
                int index = 0;

                for(int i = comps.length - 1 ;i >= 0; i--) {
                    if(comps[i] == lastParent) {
                        index = i - 1;
                        break;
                    }
                }

                while(index >= 0) {
                    tmp2 = comps[index].getBounds(tmp2);

                    if(tmp2.intersects(clip))
                        return false;
                    index--;
                }
            }
            clip.x += x;
            clip.y += y;
            lastParent = parent;
        }
        if (parent == null) {
            // No Window parent.
            return false;
        }
        return true;
    }


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

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

    /**
     * This class implements accessibility support for the
     * <code>JViewport</code> class.  It provides an implementation of the
     * Java Accessibility API appropriate to viewport 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 AccessibleJViewport extends AccessibleJComponent {
        /**
         * Get the role of this object.
         *
         * @return an instance of AccessibleRole describing the role of
         * the object
         */
        public AccessibleRole getAccessibleRole() {
            return AccessibleRole.VIEWPORT;
        }
    } // inner class AccessibleJViewport
}
