//
// $Id: ScrollablePanel.java,v 1.3 2002/11/12 05:52:03 mdb Exp $

package com.samskivert.swing;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;

import javax.swing.JPanel;
import javax.swing.Scrollable;
import javax.swing.SwingConstants;

/**
 * A {@link JPanel} extension that implements the {@link Scrollable}
 * interface, instructing it to scroll partially obscured components into
 * view if scrolling is done in the direction of a partially obscured
 * component. If no component is partially obscured, the next component is
 * scrolled into view in its entirety. Presently the code only works with
 * vertically laid out components, horizontal scrolling simply moves by a
 * default number of pixels every time.
 */
public class ScrollablePanel extends JPanel
    implements Scrollable
{
    /**
     * Pass through constructor.
     */
    public ScrollablePanel (LayoutManager layout, boolean isDoubleBuffered)
    {
        super(layout, isDoubleBuffered);
    }

    /**
     * Pass through constructor.
     */
    public ScrollablePanel (LayoutManager layout)
    {
        super(layout);
    }

    /**
     * Pass through constructor.
     */
    public ScrollablePanel (boolean isDoubleBuffered)
    {
        super(isDoubleBuffered);
    }

    /**
     * Pass through constructor.
     */
    public ScrollablePanel ()
    {
    }

    /**
     * Instructs this panel to not scroll in the horizontal direction but
     * to set its viewport's horizontal size when it is sized.
     */
    public void setTracksViewportWidth (boolean tracksWidth)
    {
        _tracksWidth = tracksWidth;
    }

    /**
     * Instructs this panel to not scroll in the vertical direction but to
     * set its viewport's vertical size when it is sized.
     */
    public void setTracksViewportHeight (boolean tracksHeight)
    {
        _tracksHeight = tracksHeight;
    }

    // documentation inherited from interface
    public Dimension getPreferredScrollableViewportSize ()
    {
        return getPreferredSize();
    }

    // documentation inherited from interface
    public int getScrollableUnitIncrement (
        Rectangle visibleRect, int orientation, int direction)
    {
        Insets insets = getInsets();

        if (orientation == SwingConstants.HORIZONTAL) {
            // nothing sensible to do here

        } else {
            if (direction > 0) {
                int rectbot = visibleRect.y + visibleRect.height;
                Component comp = getComponentAt(insets.left, rectbot);

                // if there's no component at the edge, drop down 5
                // pixels and look again
                if (comp == this) {
                    comp = getComponentAt(insets.left, rectbot+5);
                }

                if (comp != this && comp != null) {
                    int compbot = comp.getY() + comp.getHeight();
                    return compbot - rectbot + 5;
                }

            } else {
                Component comp = getComponentAt(insets.left, visibleRect.y);

                // if there's no component at the edge, move up 5
                // pixels and look again
                if (comp == this) {
                    comp = getComponentAt(insets.left, visibleRect.y-5);
                }

                if (comp != this && comp != null) {
                    return visibleRect.y - comp.getY() + 5;
                }
            }
        }

        return DEFAULT_SCROLL_AMOUNT;
    }

    // documentation inherited from interface
    public int getScrollableBlockIncrement (
        Rectangle visibleRect, int orientation, int direction)
    {
        if (orientation == SwingConstants.HORIZONTAL) {
            return visibleRect.width;
        } else {
            return visibleRect.height;
        }
    }

    // documentation inherited from interface
    public boolean getScrollableTracksViewportWidth ()
    {
        return _tracksWidth;
    }

    // documentation inherited from interface
    public boolean getScrollableTracksViewportHeight ()
    {
        return _tracksHeight;
    }

    protected boolean _tracksWidth = false;
    protected boolean _tracksHeight = false;

    /** The number of pixels to scroll if we can't find a component to
     * scroll into view or if we're scrolling horizontally. */
    protected static final int DEFAULT_SCROLL_AMOUNT = 10;
}

@@ -33,33 +33,33 @@
 v 1.
-3
+4
  200
-2
+3
 /11/
-12 05:52:03 mdb
+05 03:22:28 ray
  Exp
@@ -1953,32 +1953,175 @@
 sHeight;%0A    %7D%0A%0A
+    /**%0A     * Set the unit scroll increment.%0A     */%0A    public void setUnitScrollIncrement (int inc)%0A    %7B%0A        _unitScroll = inc;%0A    %7D%0A%0A
     // documenta
@@ -2408,32 +2408,108 @@
 irection)%0A    %7B%0A
+        if (_unitScroll != -1) %7B%0A            return _unitScroll;%0A        %7D%0A%0A
         Insets i
@@ -4429,16 +4429,16 @@
  false;%0A
-
     prot
@@ -4475,16 +4475,53 @@
 false;%0A%0A
+    protected int _unitScroll = -1;%0A%0A
     /** 

Allow the unit scroll increment to be set.