2006-03-20  Audrius Meskauskas  <[EMAIL PROTECTED]>

   * javax/swing/JTable.java (getScrollableUnitIncrement): Rewritten.
   * javax/swing/JTree.java (getScrollableUnitIncrement): Rewritten.
   (getScrollableUnitIncrement
   * javax/swing/Scrollable.java: Documented.
   * javax/swing/plaf/basic/BasicScrollPaneUI.java
   (MouseWheelHandler):Rewritten.
Index: swing/JTable.java
===================================================================
RCS file: /sources/classpath/classpath/javax/swing/JTable.java,v
retrieving revision 1.87
diff -u -r1.87 JTable.java
--- swing/JTable.java	20 Mar 2006 00:08:27 -0000	1.87
+++ swing/JTable.java	20 Mar 2006 09:03:32 -0000
@@ -2104,23 +2104,31 @@
   }
   
   /**
-   * Get the amount to scroll per one mouse wheel click.
+   * Return the preferred scrolling amount (in pixels) for the given scrolling
+   * direction and orientation.
+   * 
+   * @param visibleRect the currently visible part of the component.
+   * @param orientation the scrolling orientation
+   * @param direction the scrolling direction (negative - up, positive -down).
+   *          The values greater than one means that more mouse wheel or similar
+   *          events were generated, and hence it is better to scroll the longer
+   *          distance.
    */
-  public int getScrollableUnitIncrement(Rectangle visibleRect, 
-                                        int orientation, int direction)
+  public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
+                                        int direction)
   {
+    int h = (rowHeight + rowMargin);
+    int delta = h * ROWS_PER_WHEEL_CLICK * direction;
+    
+    // Round so that the top would start from the row boundary 
     if (orientation == SwingConstants.VERTICAL)
       {
-        return (rowHeight + rowMargin) * ROWS_PER_WHEEL_CLICK;
-      }
-    else
-      {
-        int sum = 0;
-        for (int i = 0; i < getColumnCount(); ++i)
-          sum += columnModel.getColumn(0).getWidth();
-        int inc = getColumnCount() == 0 ? 10 : sum / getColumnCount();
-        return inc;
+        int near = ((visibleRect.y + delta +h/2) / h) * h;
+        int diff = visibleRect.y + delta - near;
+        delta -= diff;
       }
+    return delta;
+    // TODO when scrollng horizontally, scroll into the column boundary.    
   }
 
   /**
Index: swing/JTree.java
===================================================================
RCS file: /sources/classpath/classpath/javax/swing/JTree.java,v
retrieving revision 1.57
diff -u -r1.57 JTree.java
--- swing/JTree.java	20 Mar 2006 00:08:27 -0000	1.57
+++ swing/JTree.java	20 Mar 2006 09:03:38 -0000
@@ -1627,11 +1627,42 @@
   {
     return new Dimension (getPreferredSize().width, getVisibleRowCount()*getRowHeight());
   }
-
-  public int getScrollableUnitIncrement(Rectangle visibleRect,
-                                        int orientation, int direction)
+  
+  /**
+   * Return the preferred scrolling amount (in pixels) for the given scrolling
+   * direction and orientation.
+   * 
+   * @param visibleRect the currently visible part of the component.
+   * @param orientation the scrolling orientation
+   * @param direction the scrolling direction (negative - up, positive -down).
+   *          The values greater than one means that more mouse wheel or similar
+   *          events were generated, and hence it is better to scroll the longer
+   *          distance.
+   *          
+   * @author Audrius Meskauskas ([EMAIL PROTECTED])          
+   */
+  public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
+                                        int direction)
   {
-    return rowHeight*ROWS_PER_WHEEL_CLICK;
+    int delta;
+
+    // Round so that the top would start from the row boundary
+    if (orientation == SwingConstants.VERTICAL)
+      {
+        int row = getClosestRowForLocation(visibleRect.x, visibleRect.y);
+        row = row + direction;
+        if (row < 0)
+          row = 0;
+        if (row > getRowCount())
+          row = getRowCount();
+        
+        Rectangle newTop = getRowBounds(row);
+        delta = newTop.y - visibleRect.y;
+      }
+    else
+      delta = direction * ROWS_PER_WHEEL_CLICK * rowHeight == 0 ? 20
+                                                               : rowHeight;
+    return delta;
   }
 
   public int getScrollableBlockIncrement(Rectangle visibleRect,
Index: swing/Scrollable.java
===================================================================
RCS file: /sources/classpath/classpath/javax/swing/Scrollable.java,v
retrieving revision 1.6
diff -u -r1.6 Scrollable.java
--- swing/Scrollable.java	13 Sep 2005 09:17:21 -0000	1.6
+++ swing/Scrollable.java	20 Mar 2006 09:03:39 -0000
@@ -50,14 +50,57 @@
 {
   Dimension getPreferredScrollableViewportSize();
 
+  /**
+   * Return the preferred scrolling amount (in pixels) for the given
+   * scrolling direction and orientation when scrolling in small amounts
+   * like table lines.
+   * 
+   * @param visibleRect the currently visible part of the component. 
+   * @param orientation the scrolling orientation
+   * @param direction the scrolling direction (negative - up, positive -down).
+   * The values greater than one means that more mouse wheel or similar 
+   * events were generated, and hence it is better to scroll the longer
+   * distance.
+   * 
+   * @return the preferred scrolling distance, negative if up or left.
+   */
   int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
                                  int direction);
 
+  /**
+   * Return the preferred scrolling amount (in pixels) for the given
+   * scrolling direction and orientation when scrolling in large amounts
+   * (pages).
+   * 
+   * @param visibleRect the currently visible part of the component. 
+   * @param orientation the scrolling orientation
+   * @param direction the scrolling direction (negative - up, positive -down).
+   * The values greater than one means that more mouse wheel or similar 
+   * events were generated, and hence it is better to scroll the longer
+   * distance.
+   * 
+   * @return the preferred scrolling distance, negative if up or left. 
+   */
   int getScrollableBlockIncrement(Rectangle visibleRect, int orientation,
                                   int direction);
 
+  /**
+   * Return true if the width of the scrollable is always equal to the
+   * view, where it is displayed, width (for instance, the text area with
+   * the word wrap). In such case, the horizontal scrolling should not be
+   * performed.
+   * 
+   * @return true is no horizontal scrolling is assumed, faster otherwise.
+   */
   boolean getScrollableTracksViewportWidth();
 
+  /**
+   * Return true if the height of the scrollable is always equal to the view,
+   * where it is displayed, height.In such case, the vertical scrolling should
+   * not be performed.
+   * 
+   * @return true is no horizontal scrolling is assumed, faster otherwise.
+   */
   boolean getScrollableTracksViewportHeight();
 
 }
Index: swing/plaf/basic/BasicScrollPaneUI.java
===================================================================
RCS file: /sources/classpath/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java,v
retrieving revision 1.21
diff -u -r1.21 BasicScrollPaneUI.java
--- swing/plaf/basic/BasicScrollPaneUI.java	20 Mar 2006 00:08:27 -0000	1.21
+++ swing/plaf/basic/BasicScrollPaneUI.java	20 Mar 2006 09:03:41 -0000
@@ -232,7 +232,7 @@
     /**
      * Use to compute the visible rectangle.
      */
-    Rectangle rect = new Rectangle();
+    final Rectangle rect = new Rectangle();
 
     /**
      * Scroll with the mouse whell.
@@ -252,15 +252,15 @@
       boolean tracksHeight = scrollable != null
                              && scrollable.getScrollableTracksViewportHeight();
       int wheel = e.getWheelRotation();
+      int delta;
 
       // If possible, scroll vertically.
       if (bar != null && ! tracksHeight)
         {
-          int y, delta;
           if (scrollable != null)
             {
-              scrollpane.getViewport().computeVisibleRect(rect);
-              delta = wheel * scrollable.getScrollableUnitIncrement(
+              bounds(target);
+              delta = scrollable.getScrollableUnitIncrement(
                 rect, SwingConstants.VERTICAL, wheel);
             }
           else
@@ -268,14 +268,7 @@
               // Scroll non scrollables.
               delta = wheel * SCROLL_NON_SCROLLABLES;
             }
-          y = bar.getValue() + delta;
-
-          if (y < bar.getMinimum())
-            y = bar.getMinimum();
-          if (y > bar.getMaximum())
-            y = bar.getMaximum();
-
-          bar.setValue(y);
+          scroll(bar, delta);
         }
       // If not, try to scroll horizontally
       else
@@ -286,11 +279,10 @@
 
           if (bar != null && ! tracksWidth)
             {
-              int x, delta;
               if (scrollable != null)
                 {
-                  scrollpane.getViewport().computeVisibleRect(rect);
-                  delta = wheel * scrollable.getScrollableUnitIncrement(
+                  bounds(target);
+                  delta = scrollable.getScrollableUnitIncrement(
                      rect, SwingConstants.HORIZONTAL, wheel);
                 }
               else
@@ -298,17 +290,50 @@
                   // Scroll non scrollables.
                   delta = wheel * SCROLL_NON_SCROLLABLES;
                 }
-              x = bar.getValue() + delta;
-
-              if (x < bar.getMinimum())
-                x = bar.getMinimum();
-              if (x > bar.getMaximum())
-                x = bar.getMaximum();
-
-              bar.setValue(x);
+              scroll(bar, delta);
             }
         }
     }
+    
+    /**
+     * Place the component bounds into rect. The x and y values 
+     * need to be reversed.
+     * 
+     * @param target the target being scrolled
+     */
+    final void bounds(Component target)
+    {
+      // Viewport bounds, translated by the scroll bar positions.
+      target.getParent().getBounds(rect);
+      rect.x = getValue(scrollpane.getHorizontalScrollBar());
+      rect.y = getValue(scrollpane.getVerticalScrollBar());
+    }
+    
+    /**
+     * Get the scroll bar value or null if there is no such scroll bar.
+     */
+    final int getValue(JScrollBar bar)
+    {
+      return bar != null ? bar.getValue() : 0;
+    }
+    
+    /**
+     * Scroll the given distance.
+     * 
+     * @param bar the scrollbar to scroll
+     * @param delta the distance
+     */
+    final void scroll(JScrollBar bar, int delta)
+    {
+      int y = bar.getValue() + delta;
+
+      if (y < bar.getMinimum())
+        y = bar.getMinimum();
+      if (y > bar.getMaximum())
+        y = bar.getMaximum();
+
+      bar.setValue(y);
+    }
   }
   
   /**

Reply via email to