My last patch obviously made JScrollPane unusable. This was caused by a
small typo. While debugging this I found a couple more buglets, which I
don't want to hold back.

2006-09-21  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/plaf/basic/BasicScrollPaneUI.java
        (syncScrollPaneWithViewport): Fixed typo (hsb vs. vsb).
        Use more efficient getViewPosition() and getViewSize() methods
        to avoid creating a rectangle.
        (HSBChangeListener.stateChanged): Update the view position
        unconditionally. Let the Viewport figure out if something
        changed.
        (VSBChangeListener.stateChanged): Update the view position
        unconditionally. Let the Viewport figure out if something
        changed.
        * javax/swing/JViewport.java
        (ViewListener.componentResized): Fire state change, because
        the extentSize changes.
        (extentSize): Removed unneeded field.
        (viewSize): Removed unneeded field.
        (getExtentSize): Return the viewport's size here.
        (getViewRect): Reformatted.
        (getViewSize): Reordered for only one return statement.
        (paintImmediately2): Fixed up javadoc.
        (paint): Removed unneeded statement.
        (setExtentSize): Set viewport size and check for actual change
        of value.
        (setViewPosition): Simplified condition. Set scrollUnderway
        true and don't set isViewSizeSet. Avoid creating one Point
        object.
        (setViewSize): Fixed != comparison with equals(). Set scrollUnderway
        to false.
        * javax/swing/JScrollBar.java
        (ScrollBarListener): New class. Forwards change events from
        the model as adjustment events.
        (sbChangeListener): New field.
        (JScrollBar): Install listener on new model.
        (fireAdjustmentValueChanged(int,int,int)): Delegate to new helper
        method.
        (fireAdjustmentValueChanged(int,int,int,boolean)): New helper
        method to allow custom isAdjusting value.
        (setMaximum): Only forward to model.
        (setMinimum): Only forward to model.
        (setValue): Only forward to model.
        (setVisibleAmount): Only forward to model.
        (setValues): Only forward to model.
        (setModel): Update the change listener.

/Roman

Index: javax/swing/JViewport.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JViewport.java,v
retrieving revision 1.47
diff -u -1 -5 -r1.47 JViewport.java
--- javax/swing/JViewport.java	23 Aug 2006 22:03:23 -0000	1.47
+++ javax/swing/JViewport.java	21 Sep 2006 10:03:21 -0000
@@ -145,30 +145,33 @@
      */
     protected ViewListener()
     {
       // Nothing to do here.
     }
 
     /**
      * Receives notification when a component (in this case: the view
      * component) changes it's size. This simply triggers a revalidate() on the
      * viewport.
      *
      * @param ev the ComponentEvent describing the change
      */
     public void componentResized(ComponentEvent ev)
     {
+      // Fire state change, because resizing the view means changing the
+      // extentSize.
+      fireStateChanged();
       revalidate();
     }
   }
 
   public static final int SIMPLE_SCROLL_MODE = 0;
   public static final int BLIT_SCROLL_MODE = 1;
   public static final int BACKINGSTORE_SCROLL_MODE = 2;
 
   private static final long serialVersionUID = -6925142919680527970L;
 
   /**
    * The default scrollmode to be used by all JViewports as determined by
    * the system property gnu.javax.swing.JViewport.scrollMode.
    */
   private static final int defaultScrollMode;
@@ -186,46 +189,30 @@
   /**
    * The backingstore image used for the backingstore and blit scroll methods.
    */
   protected Image backingStoreImage;
 
   /**
    * The position at which the view has been drawn the last time. This is used
    * to determine the bittable area.
    */
   protected Point lastPaintPosition;
 
   ChangeEvent changeEvent = new ChangeEvent(this);
 
   int scrollMode;
 
-  /** 
-   * The width and height of the Viewport's area in terms of view
-   * coordinates.  Typically this will be the same as the width and height
-   * of the viewport's bounds, unless the viewport transforms units of
-   * width and height, which it may do, for example if it magnifies or
-   * rotates its view.
-   *
-   * @see #toViewCoordinates(Dimension)
-   */
-  Dimension extentSize;
-
-  /**
-   * The width and height of the view in its own coordinate space.
-   */
-  Dimension viewSize;
-
   /**
    * The ViewListener instance.
    */
   ViewListener viewListener;
 
   /**
    * Stores the location from where to blit. This is a cached Point object used
    * in blitting calculations.
    */
   Point cachedBlitFrom;
 
   /**
    * Stores the location where to blit to. This is a cached Point object used
    * in blitting calculations.
    */
@@ -278,128 +265,126 @@
   public JViewport()
   {
     setOpaque(true);
     setScrollMode(defaultScrollMode);
     updateUI();
     setLayout(createLayoutManager());
     lastPaintPosition = new Point();
     cachedBlitFrom = new Point();
     cachedBlitTo = new Point();
     cachedBlitSize = new Dimension();
     cachedBlitPaint = new Rectangle();
   }
 
   public Dimension getExtentSize()
   {
-    if (extentSize == null)
-      return toViewCoordinates(getSize());
-    else
-      return extentSize;
+    return getSize();
   }
 
   public Dimension toViewCoordinates(Dimension size)
   {
     return size;
   }
 
   public Point toViewCoordinates(Point p)
   {
     Point pos = getViewPosition();
     return new Point(p.x + pos.x,
                      p.y + pos.y);
   }
 
   public void setExtentSize(Dimension newSize)
   {
-    extentSize = newSize;
-    fireStateChanged();
+    Dimension oldExtent = getExtentSize();
+    if (! newSize.equals(oldExtent))
+      {
+        setSize(newSize);
+        fireStateChanged();
+      }
   }
 
   /**
    * Returns the viewSize when set, or the preferred size of the set
    * Component view.  If no viewSize and no Component view is set an
    * empty Dimension is returned.
    */
   public Dimension getViewSize()
   {
-    if (isViewSizeSet)
-      return viewSize;
-    else
+    Dimension size; 
+    Component view = getView();
+    if (view != null)
       {
-	Component view = getView();
-	if (view != null)
-	  return view.getPreferredSize();
-	else
-	  return new Dimension();
+        if (isViewSizeSet)
+          size = view.getSize();
+        else
+	  size = view.getPreferredSize();
       }
+    else
+      size = new Dimension(0, 0);
+    return size;
   }
 
 
   public void setViewSize(Dimension newSize)
   {
-    viewSize = newSize;
     Component view = getView();
     if (view != null)
       {
-        if (newSize != view.getSize())
+        if (! newSize.equals(view.getSize()))
           {
-            view.setSize(viewSize);
+            scrollUnderway = false;
+            view.setSize(newSize);
+            isViewSizeSet = true;
             fireStateChanged();
           }
       }
-    isViewSizeSet = true;
   }
 
   /**
    * Get the viewport's position in view space. Despite confusing name,
    * this really does return the viewport's (0,0) position in view space,
    * not the view's position.
    */
 
   public Point getViewPosition()
   {
     Component view = getView();
     if (view == null)
       return new Point(0,0);
     else
       {
         Point p = view.getLocation();
         p.x = -p.x;
         p.y = -p.y;
         return p;
       }
   }
 
   public void setViewPosition(Point p)
   {
-    if (getViewPosition().equals(p))
-      return;
     Component view = getView();
-    if (view != null)
+    if (view != null && ! p.equals(getViewPosition()))
       {
-        Point q = new Point(-p.x, -p.y);
-        view.setLocation(q);
-        isViewSizeSet = false;
+        scrollUnderway = true;
+        view.setLocation(-p.x, -p.y);
         fireStateChanged();
       }
-    repaint();
   }
 
   public Rectangle getViewRect()
   {
-    return new Rectangle(getViewPosition(), 
-                         getExtentSize());
+    return new Rectangle(getViewPosition(), getExtentSize());
   }
 
   /**
    * @deprecated 1.4
    */
   public boolean isBackingStoreEnabled()
   {
     return scrollMode == BACKINGSTORE_SCROLL_MODE;
   }
 
   /**
    * @deprecated 1.4
    */
   public void setBackingStoreEnabled(boolean b)
   {
@@ -483,31 +468,30 @@
    *
    * @return <code>false</code>
    */
   public boolean isOptimizedDrawingEnabled()
   {
     return false;
   }
 
   public void paint(Graphics g)
   {
     Component view = getView();
 
     if (view == null)
       return;
 
-    Point pos = getViewPosition();
     Rectangle viewBounds = view.getBounds();
     Rectangle portBounds = getBounds();
 
     if (viewBounds.width == 0 
         || viewBounds.height == 0
         || portBounds.width == 0
         || portBounds.height == 0)
       return;
 
     switch (getScrollMode())
       {
 
       case JViewport.BACKINGSTORE_SCROLL_MODE:
         paintBackingStore(g);
         break;
@@ -928,24 +912,27 @@
         finally
           {
             g.setClip(oldClip);
           }
       }
     // If blitting is not possible for some reason, fall back to repainting
     // everything.
     else
       paintSimple(g);
     lastPaintPosition.setLocation(getViewPosition());
   }
 
   /**
    * Overridden from JComponent to set the [EMAIL PROTECTED] #isPaintRoot} flag.
    *
-   * @param r the rectangle to paint
+   * @param x the rectangle to paint, X coordinate
+   * @param y the rectangle to paint, Y coordinate
+   * @param w the rectangle to paint, width
+   * @param h the rectangle to paint, height
    */
   void paintImmediately2(int x, int y, int w, int h)
   {
     isPaintRoot = true;
     super.paintImmediately2(x, y, w, h);
     isPaintRoot = false;
   }
 }
Index: javax/swing/JScrollBar.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JScrollBar.java,v
retrieving revision 1.16
diff -u -1 -5 -r1.16 JScrollBar.java
--- javax/swing/JScrollBar.java	5 May 2006 02:08:33 -0000	1.16
+++ javax/swing/JScrollBar.java	21 Sep 2006 10:03:21 -0000
@@ -38,30 +38,32 @@
 
 package javax.swing;
 
 import java.awt.Adjustable;
 import java.awt.Dimension;
 import java.awt.event.AdjustmentEvent;
 import java.awt.event.AdjustmentListener;
 import java.beans.PropertyChangeEvent;
 
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
 import javax.accessibility.AccessibleState;
 import javax.accessibility.AccessibleStateSet;
 import javax.accessibility.AccessibleValue;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
 import javax.swing.plaf.ScrollBarUI;
 
 /**
  * The JScrollBar. Two buttons control how the values that the 
  * scroll bar can take. You can also drag the thumb or click the track
  * to move the scroll bar. Typically, the JScrollBar is used with
  * other components to translate the value of the bar to the viewable
  * contents of the other components.
  */
 public class JScrollBar extends JComponent implements Adjustable, Accessible
 {
   /**
    * Provides the accessibility features for the <code>JScrollBar</code>
    * component.
    */
@@ -160,44 +162,72 @@
       return new Integer(getMinimum());
     }
 
     /**
      * Returns the maximum value of the [EMAIL PROTECTED] JScrollBar} component, as an
      * [EMAIL PROTECTED] Integer}.
      *
      * @return The maximum value of the [EMAIL PROTECTED] JScrollBar} component.
      */
     public Number getMaximumAccessibleValue()
     {
       return new Integer(getMaximum() - model.getExtent());
     }
   }
 
+  /**
+   * Listens for changes on the model and fires them to interested
+   * listeners on the JScrollBar, after re-sourcing them.
+   */
+  private class ScrollBarChangeListener
+    implements ChangeListener
+  {
+
+    public void stateChanged(ChangeEvent event)
+    {
+      Object o = event.getSource();
+      if (o instanceof BoundedRangeModel)
+        {
+          BoundedRangeModel m = (BoundedRangeModel) o;
+          fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                                     AdjustmentEvent.TRACK, m.getValue(),
+                                     m.getValueIsAdjusting());
+        }
+    }
+    
+  }
+
   private static final long serialVersionUID = -8195169869225066566L;
   
   /** How much the thumb moves when moving in a block. */
   protected int blockIncrement = 10;
 
   /** The model that holds the scroll bar's data. */
   protected BoundedRangeModel model;
 
   /** The orientation of the scroll bar. */
   protected int orientation = SwingConstants.VERTICAL;
 
   /** How much the thumb moves when moving in a unit. */
   protected int unitIncrement = 1;
 
+  /**
+   * This ChangeListener forwards events fired from the model and re-sources
+   * them to originate from this JScrollBar.
+   */
+  private ChangeListener sbChangeListener;
+
   /** 
    * Creates a new horizontal JScrollBar object with a minimum
    * of 0, a maxmium of 100, a value of 0 and an extent of 10.
    */
   public JScrollBar()
   {
     this(SwingConstants.VERTICAL, 0, 10, 0, 100);
   }
 
   /**
    * Creates a new JScrollBar object with a minimum of 0, a 
    * maximum of 100, a value of 0, an extent of 10 and the given
    * orientation.
    *
    * @param orientation The orientation of the JScrollBar.
@@ -208,30 +238,32 @@
   }
 
   /**
    * Creates a new JScrollBar object with the given orientation, 
    * value, min, max, and extent.
    *
    * @param orientation The orientation to use.
    * @param value The value to use.
    * @param extent The extent to use.
    * @param min The minimum value of the scrollbar.
    * @param max The maximum value of the scrollbar.
    */
   public JScrollBar(int orientation, int value, int extent, int min, int max)
   {
     model = new DefaultBoundedRangeModel(value, extent, min, max);
+    sbChangeListener = new ScrollBarChangeListener();
+    model.addChangeListener(sbChangeListener);
     if (orientation != SwingConstants.HORIZONTAL
         && orientation != SwingConstants.VERTICAL)
       throw new IllegalArgumentException(orientation
                                          + " is not a legal orientation");
     this.orientation = orientation;
     updateUI();
   }
 
   /**
    * This method sets the UI of this scrollbar to
    * the given UI.
    *
    * @param ui The UI to use with this scrollbar.
    */
   public void setUI(ScrollBarUI ui)
@@ -307,36 +339,37 @@
    * @return The scrollbar's model.
    */
   public BoundedRangeModel getModel()
   {
     return model;
   }
 
   /**
    * This method sets the model to use with
    * the scrollbar.
    *
    * @param newModel The new model to use with the scrollbar.
    */
   public void setModel(BoundedRangeModel newModel)
   {
-    if (model != newModel)
-      {
-	BoundedRangeModel oldModel = model;
-	model = newModel;
-	firePropertyChange("model", oldModel, model);
-      }
+    BoundedRangeModel oldModel = model;
+    if (oldModel != null)
+      oldModel.removeChangeListener(sbChangeListener);
+    model = newModel;
+    if (model != null)
+      model.addChangeListener(sbChangeListener);
+    firePropertyChange("model", oldModel, model);
   }
 
   /**
    * This method returns how much the scrollbar's value
    * should change for a unit increment depending on the 
    * given direction.
    *
    * @param direction The direction to scroll in.
    *
    * @return The amount the scrollbar's value will change given the direction.
    */
   public int getUnitIncrement(int direction)
   {
     return direction * unitIncrement;
   }
@@ -412,113 +445,93 @@
    *
    * @return The value of the scrollbar.
    */
   public int getValue()
   {
     return model.getValue();
   }
 
   /**
    * This method changes the value of the scrollbar.
    *
    * @param value The new value of the scrollbar.
    */
   public void setValue(int value)
   {
-    if (isEnabled() && value != getValue())
-    {
-      model.setValue(value);
-      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
-                                 AdjustmentEvent.TRACK, value);
-    }
+    model.setValue(value);
   }
 
   /**
    * This method returns the visible amount (AKA extent). 
    * The visible amount can be used by UI delegates to 
    * determine the size of the thumb.
    *
    * @return The visible amount (AKA extent).
    */
   public int getVisibleAmount()
   {
     return model.getExtent();
   }
 
   /**
    * This method sets the visible amount (AKA extent).
    *
    * @param extent The visible amount (AKA extent).
    */
   public void setVisibleAmount(int extent)
   {
-    if (extent != getVisibleAmount())
-    {
-      model.setExtent(extent);
-      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
-                                 AdjustmentEvent.TRACK, extent);
-    }
+    model.setExtent(extent);
   }
 
   /**
    * This method returns the minimum value of the scrollbar.
    *
    * @return The minimum value of the scrollbar.
    */
   public int getMinimum()
   {
     return model.getMinimum();
   }
 
   /**
    * This method sets the minimum value of the scrollbar.
    *
    * @param minimum The minimum value of the scrollbar.
    */
   public void setMinimum(int minimum)
   {
-    if (minimum != getMinimum())
-    {
-      model.setMinimum(minimum);
-      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
-                                 AdjustmentEvent.TRACK, minimum);
-    }
+    model.setMinimum(minimum);
   }
 
   /**
    * This method returns the maximum value of the scrollbar.
    *
    * @return The maximum value of the scrollbar.
    */
   public int getMaximum()
   {
     return model.getMaximum();
   }
 
   /**
    * This method sets the maximum value of the scrollbar.
    *
    * @param maximum The maximum value of the scrollbar.
    */
   public void setMaximum(int maximum)
   {
-    if (maximum != getMaximum())
-    {
-      model.setMaximum(maximum);
-      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
-                                 AdjustmentEvent.TRACK, maximum);
-    }
+    model.setMaximum(maximum);
   }
 
   /**
    * This method returns the model's isAjusting value.
    *
    * @return The model's isAdjusting value.
    */
   public boolean getValueIsAdjusting()
   {
     return model.getValueIsAdjusting();
   }
 
   /**
    * This method sets the model's isAdjusting value.
    *
@@ -528,41 +541,32 @@
   {
     model.setValueIsAdjusting(b);
   }
 
   /**
    * This method sets the value, extent, minimum and 
    * maximum.
    *
    * @param newValue The new value.
    * @param newExtent The new extent.
    * @param newMin The new minimum.
    * @param newMax The new maximum.
    */
   public void setValues(int newValue, int newExtent, int newMin, int newMax)
   {
-    if (!isEnabled())
-      newValue = model.getValue();
-    // It seems to be that on any change the value is fired.
-    if (newValue != getValue() || newExtent != getVisibleAmount() ||
-        newMin != getMinimum() || newMax != getMaximum())
-    {
-      model.setRangeProperties(newValue, newExtent, newMin, newMax,
-                               model.getValueIsAdjusting());
-      fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
-                                 AdjustmentEvent.TRACK, newValue);
-    }
+    model.setRangeProperties(newValue, newExtent, newMin, newMax,
+                             model.getValueIsAdjusting());
   }
 
   /**
    * This method adds an AdjustmentListener to the scroll bar.
    *
    * @param listener The listener to add.
    */
   public void addAdjustmentListener(AdjustmentListener listener)
   {
     listenerList.add(AdjustmentListener.class, listener);
   }
 
   /**
    * This method removes an AdjustmentListener from the scroll bar. 
    *
@@ -584,39 +588,54 @@
     return (AdjustmentListener[]) listenerList.getListeners(AdjustmentListener.class);
   }
 
   /**
    * This method is called to fired AdjustmentEvents to the listeners
    * of this scroll bar. All AdjustmentEvents that are fired
    * will have an ID of ADJUSTMENT_VALUE_CHANGED and a type of
    * TRACK. 
    *
    * @param id The ID of the adjustment event.
    * @param type The Type of change.
    * @param value The new value for the property that was changed..
    */
   protected void fireAdjustmentValueChanged(int id, int type, int value)
   {
+    fireAdjustmentValueChanged(id, type, value, getValueIsAdjusting());
+  }
+
+  /**
+   * Helper method for firing adjustment events that can have their
+   * isAdjusting field modified.
+   *
+   * This is package private to avoid an accessor method.
+   *
+   * @param id the ID of the event
+   * @param type the type of the event
+   * @param value the value
+   * @param isAdjusting if the scrollbar is adjusting or not
+   */
+  void fireAdjustmentValueChanged(int id, int type, int value,
+                                          boolean isAdjusting)
+  {
     Object[] adjustmentListeners = listenerList.getListenerList();
-    AdjustmentEvent adjustmentEvent = new AdjustmentEvent(this, 
-                                            AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
-					    AdjustmentEvent.TRACK,
-					    value);
+    AdjustmentEvent adjustmentEvent = new AdjustmentEvent(this, id, type,
+                                                          value, isAdjusting);
     for (int i = adjustmentListeners.length - 2; i >= 0; i -= 2)
       {
-	if (adjustmentListeners[i] == AdjustmentListener.class)
-	  ((AdjustmentListener) adjustmentListeners[i + 1]).adjustmentValueChanged(adjustmentEvent);
+        if (adjustmentListeners[i] == AdjustmentListener.class)
+          ((AdjustmentListener) adjustmentListeners[i + 1]).adjustmentValueChanged(adjustmentEvent);
       }
   }
 
   /**
    * This method returns the minimum size for this scroll bar.
    *
    * @return The minimum size.
    */
   public Dimension getMinimumSize()
   {
     return ui.getMinimumSize(this);
   }
 
   /**
    * This method returns the maximum size for this scroll bar.
Index: javax/swing/plaf/basic/BasicScrollPaneUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java,v
retrieving revision 1.31
diff -u -1 -5 -r1.31 BasicScrollPaneUI.java
--- javax/swing/plaf/basic/BasicScrollPaneUI.java	19 Sep 2006 09:18:31 -0000	1.31
+++ javax/swing/plaf/basic/BasicScrollPaneUI.java	21 Sep 2006 10:03:21 -0000
@@ -89,67 +89,58 @@
    */
   public class HSBChangeListener implements ChangeListener
   {
 
     /**
      * Receives notification when the state of the horizontal scrollbar
      * model has changed.
      *
      * @param event the change event
      */
     public void stateChanged(ChangeEvent event)
     {
       JScrollBar hsb = scrollpane.getHorizontalScrollBar();
       JViewport vp = scrollpane.getViewport();
       Point viewPosition = vp.getViewPosition();
-      int xpos = hsb.getValue();
-
-      if (xpos != viewPosition.x)
-        {
-          viewPosition.x = xpos;
-          vp.setViewPosition(viewPosition);
-        }
+      viewPosition.x = hsb.getValue();
+      vp.setViewPosition(viewPosition);
     }
 
   }
 
   /**
    * Listens for changes in the state of the vertical scrollbar's model and
    * updates the scrollpane accordingly.
    *
    * @author Roman Kennke ([EMAIL PROTECTED])
    */
   public class VSBChangeListener implements ChangeListener
   {
 
     /**
      * Receives notification when the state of the vertical scrollbar
      * model has changed.
      *
      * @param event the change event
      */
     public void stateChanged(ChangeEvent event)
     {
       JScrollBar vsb = scrollpane.getVerticalScrollBar();
       JViewport vp = scrollpane.getViewport();
       Point viewPosition = vp.getViewPosition();
-      int ypos = vsb.getValue();
-      if (ypos != viewPosition.y)
-        {
-          viewPosition.y = ypos;
-          vp.setViewPosition(viewPosition);
-        }
+      viewPosition.y = vsb.getValue();
+      vp.setViewPosition(viewPosition);
     }
  
   }
 
   /**
    * Listens for changes of the viewport's extent size and updates the
    * scrollpane accordingly.
    *
    * @author Roman Kennke ([EMAIL PROTECTED])
    */
   public class ViewportChangeHandler implements ChangeListener
   {
 
     /**
      * Receives notification when the view's size, position or extent size
@@ -807,65 +798,66 @@
         vpBorder.paintBorder(scrollpane, g, r.x, r.y, r.width, r.height);
       }
   }
 
   /**
    * Synchronizes the scrollbar and header settings positions and extent
    * with the viewport's view position and extent.
    */
   protected void syncScrollPaneWithViewport()
   {
     JViewport vp = scrollpane.getViewport();
 
     if (vp != null)
       {
         Dimension extentSize = vp.getExtentSize();
-        Rectangle viewBounds = vp.getViewRect();
+        Point viewPos = vp.getViewPosition();
+        Dimension viewSize = vp.getViewSize();
 
         // Update the vertical scrollbar.
         JScrollBar vsb = scrollpane.getVerticalScrollBar();
         if (vsb != null)
           {
             int extent = extentSize.height;
-            int max = viewBounds.height;
-            vsb.setValues(Math.max(0, Math.min(viewBounds.y, max - extent)),
-                          extent, 0, max);
+            int max = viewSize.height;
+            int val = Math.max(0, Math.min(viewPos.y, max - extent));
+            vsb.setValues(val, extent, 0, max);
           }
 
         // Update the horizontal scrollbar.
         JScrollBar hsb = scrollpane.getHorizontalScrollBar();
         if (hsb != null)
           {
             int extent = extentSize.width;
-            int max = viewBounds.width;
-            vsb.setValues(Math.max(0, Math.min(viewBounds.x, max - extent)),
-                          extent, 0, max);
+            int max = viewSize.width;
+            int val = Math.max(0, Math.min(viewPos.x, max - extent));
+            hsb.setValues(val, extent, 0, max);
           }
 
         // Update the row header.
         JViewport rowHeader = scrollpane.getRowHeader();
         if (rowHeader != null)
           {
-            Point p = new Point(0, viewBounds.y);
+            Point p = new Point(0, viewPos.y);
             rowHeader.setViewPosition(p);
           }
 
         // Update the column header.
         JViewport colHeader = scrollpane.getColumnHeader();
         if (colHeader != null)
           {
-            Point p = new Point(viewBounds.x, 0);
+            Point p = new Point(viewPos.x, 0);
             colHeader.setViewPosition(p);
           }
       }
   }
 
   /**
    * Receives notification when the <code>columnHeader</code> property has
    * changed on the scrollpane.
    *
    * @param ev the property change event
    */
   protected void updateColumnHeader(PropertyChangeEvent ev)
   {
     // TODO: Find out what should be done here. Or is this only a hook?
   }

Reply via email to