/*
 * Copyright 1997-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.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 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 = 0, dy = 0;

            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 = null;

        /* Find the first JComponent ancestor of this component whose
         * isValidateRoot() method returns true.
         */
        for(Component c = this; c != null; c = c.getParent()) {
            if ((c instanceof CellRendererPane) || (c.getPeer() == null)) {
                return;
            }
            if ((c instanceof JComponent) &&
                (((JComponent)c).isValidateRoot())) {
                validateRoot = c;
                break;
            }
        }

        // If no validateRoot, nothing to validate from.
        if (validateRoot == null) {
            return;
        }

        // Make sure all ancestors are visible.
        Component root = null;

        for(Component c = validateRoot; c != null; c = c.getParent()) {
            // We don't check isVisible here, otherwise if the component
            // is contained in something like a JTabbedPane when the
            // component is made visible again it won't have scrolled
            // to the correct location.
            if (c.getPeer() == null) {
                return;
            }
            if ((c instanceof Window) || (c instanceof Applet)) {
                root = c;
                break;
            }
        }

        // Make sure there is a Window ancestor.
        if (root == 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() {
        if (scrollMode == BACKINGSTORE_SCROLL_MODE) {
            return true;
        }
        return false;
    }


    /**
     * 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;
        if (mode == BACKINGSTORE_SCROLL_MODE) {
            backingStore = true;
        } else {
            backingStore = false;
        }
    }

    /**
      * 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 final boolean isBlitting() {
        Component view = getView();
        return (scrollMode == BLIT_SCROLL_MODE) &&
               (view instanceof JComponent) && ((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
     */
    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 (ChangeListener[])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
}
