Surely, we can make via BasicScrollPaneUI and then have the JTrees scrolling with the wheel as well!

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

   * javax/swing/JTable.java (ROWS_PER_WHEEL_CLICK): New field.
   (getScrollableUnitIncrement): Rewritten.
   * javax/swing/JTree.java (ROWS_PER_WHEEL_CLICK): New field.
   (getScrollableUnitIncrement): Rewritten.
   (getScrollableBlockIncrement): Rewritten.
   * javax/swing/plaf/basic/BasicScrollPaneUI.java
(MouseWheelHandler): Implemented. (ViewportContainerListener): New class.
   (containerListener): New field. (SCROLL_NON_SCROLABLES): New field.
   (installListeners): Install wheel listeners. (uninstallListeners):
   Uninstall wheel listeners.
   * javax/swing/plaf/basic/BasicTableUI.java: Remove the implementation
   of the MouseWheelListener. (installListeners): Do not install wheel
   listener. (ROWS_PER_WHEEL_CLICK): Removed.
Index: swing/JTable.java
===================================================================
RCS file: /sources/classpath/classpath/javax/swing/JTable.java,v
retrieving revision 1.86
diff -u -r1.86 JTable.java
--- swing/JTable.java	18 Mar 2006 21:47:08 -0000	1.86
+++ swing/JTable.java	19 Mar 2006 23:55:03 -0000
@@ -1325,7 +1325,12 @@
    * in the table) to provide or absorb excess space requirements.
    */
   public static final int AUTO_RESIZE_LAST_COLUMN = 3;
-
+  
+  /**
+   * The number of rows to scroll per mouse wheel click. From impression,
+   * Sun seems using the value 3.
+   */
+  static int ROWS_PER_WHEEL_CLICK = 3;  
 
   /**
    * A table mapping [EMAIL PROTECTED] java.lang.Class} objects to 
@@ -2097,26 +2102,27 @@
     else
       return true;
   }
-
-  public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction)
+  
+  /**
+   * Get the amount to scroll per one mouse wheel click.
+   */
+  public int getScrollableUnitIncrement(Rectangle visibleRect, 
+                                        int orientation, int direction)
   {
-    // FIXME: I don't exactly know what sun does here. in both cases they
-    // pick values which do *not* simply expose the next cell in a given
-    // scroll direction.
-
     if (orientation == SwingConstants.VERTICAL)
-      return direction * rowHeight;
+      {
+        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 direction * inc;
+        return inc;
       }
   }
 
-
   /**
    * Get the cell editor, suitable for editing the given cell. The default
    * method requests the editor from the column model. If the column model does
Index: swing/JTree.java
===================================================================
RCS file: /sources/classpath/classpath/javax/swing/JTree.java,v
retrieving revision 1.56
diff -u -r1.56 JTree.java
--- swing/JTree.java	27 Jan 2006 21:05:13 -0000	1.56
+++ swing/JTree.java	19 Mar 2006 23:55:09 -0000
@@ -1347,6 +1347,12 @@
   }
 
   private static final long serialVersionUID = 7559816092864483649L;
+  
+  /**
+   * The number of rows to scroll per mouse wheel click. From impression,
+   * Sun seems using the value 3.
+   */
+  static int ROWS_PER_WHEEL_CLICK = 3;    
 
   public static final String CELL_EDITOR_PROPERTY = "cellEditor";
 
@@ -1625,13 +1631,13 @@
   public int getScrollableUnitIncrement(Rectangle visibleRect,
                                         int orientation, int direction)
   {
-    return 1;
+    return rowHeight*ROWS_PER_WHEEL_CLICK;
   }
 
   public int getScrollableBlockIncrement(Rectangle visibleRect,
                                          int orientation, int direction)
   {
-    return 1;
+    return getScrollableUnitIncrement(visibleRect, orientation, direction);
   }
 
   public boolean getScrollableTracksViewportHeight()
Index: swing/plaf/basic/BasicScrollPaneUI.java
===================================================================
RCS file: /sources/classpath/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java,v
retrieving revision 1.20
diff -u -r1.20 BasicScrollPaneUI.java
--- swing/plaf/basic/BasicScrollPaneUI.java	3 Jan 2006 15:29:52 -0000	1.20
+++ swing/plaf/basic/BasicScrollPaneUI.java	19 Mar 2006 23:55:13 -0000
@@ -38,9 +38,14 @@
 
 package javax.swing.plaf.basic;
 
+import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.ComponentListener;
+import java.awt.event.ContainerEvent;
+import java.awt.event.ContainerListener;
 import java.awt.event.MouseWheelEvent;
 import java.awt.event.MouseWheelListener;
 import java.beans.PropertyChangeEvent;
@@ -53,6 +58,8 @@
 import javax.swing.LookAndFeel;
 import javax.swing.ScrollPaneConstants;
 import javax.swing.ScrollPaneLayout;
+import javax.swing.Scrollable;
+import javax.swing.SwingConstants;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 import javax.swing.plaf.ComponentUI;
@@ -222,18 +229,118 @@
    */
   protected class MouseWheelHandler implements MouseWheelListener
   {
+    /**
+     * Use to compute the visible rectangle.
+     */
+    Rectangle rect = new Rectangle();
 
     /**
-     * Receives notification whenever the mouse wheel is moved.
-     *
-     * @param event the mouse wheel event
+     * Scroll with the mouse whell.
+     * 
+     * @author Audrius Meskauskas ([EMAIL PROTECTED])
      */
-    public void mouseWheelMoved(MouseWheelEvent event)
+    public void mouseWheelMoved(MouseWheelEvent e)
     {
-      // TODO: Implement this properly.
-    }
+      if (scrollpane.getViewport().getComponentCount() == 0)
+        return;
 
+      Component target = scrollpane.getViewport().getComponent(0);
+      JScrollBar bar = scrollpane.getVerticalScrollBar();
+      Scrollable scrollable = (target instanceof Scrollable) ? (Scrollable) target
+                                                            : null;
+
+      boolean tracksHeight = scrollable != null
+                             && scrollable.getScrollableTracksViewportHeight();
+      int wheel = e.getWheelRotation();
+
+      // If possible, scroll vertically.
+      if (bar != null && ! tracksHeight)
+        {
+          int y, delta;
+          if (scrollable != null)
+            {
+              scrollpane.getViewport().computeVisibleRect(rect);
+              delta = wheel * scrollable.getScrollableUnitIncrement(
+                rect, SwingConstants.VERTICAL, wheel);
+            }
+          else
+            {
+              // 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);
+        }
+      // If not, try to scroll horizontally
+      else
+        {
+          bar = scrollpane.getHorizontalScrollBar();
+          boolean tracksWidth = scrollable != null
+                                && scrollable.getScrollableTracksViewportWidth();
+
+          if (bar != null && ! tracksWidth)
+            {
+              int x, delta;
+              if (scrollable != null)
+                {
+                  scrollpane.getViewport().computeVisibleRect(rect);
+                  delta = wheel * scrollable.getScrollableUnitIncrement(
+                     rect, SwingConstants.HORIZONTAL, wheel);
+                }
+              else
+                {
+                  // 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);
+            }
+        }
+    }
+  }
+  
+  /**
+   * Adds/removes the mouse wheel listener when the component is added/removed
+   * to/from the scroll pane view port.
+   * 
+   * @author Audrius Meskauskas ([EMAIL PROTECTED])
+   */
+  class ViewportContainerListener implements ContainerListener
+  {
+    /**
+     * Add the mouse wheel listener, allowing to scroll with the mouse.
+     */
+    public void componentAdded(ContainerEvent e)
+    {
+      e.getChild().addMouseWheelListener(mouseWheelListener);
+    }
+    
+    /**
+     * Remove the mouse wheel listener.
+     */
+    public void componentRemoved(ContainerEvent e)
+    {
+      e.getChild().removeMouseWheelListener(mouseWheelListener);
+    }
   }
+  
+  /**
+   * The number of pixels by that we should scroll the content that does
+   * not implement Scrollable.
+   */
+  static int SCROLL_NON_SCROLLABLES = 10;
 
   /** The Scrollpane for which the UI is provided by this class. */
   protected JScrollPane scrollpane;
@@ -262,6 +369,12 @@
    * The mousewheel listener for the scrollpane.
    */
   MouseWheelListener mouseWheelListener;
+  
+  /**
+   * The listener to add and remove the mouse wheel listener to/from
+   * the component container.
+   */
+  ContainerListener containerListener;
 
   public static ComponentUI createUI(final JComponent c) 
   {
@@ -316,11 +429,21 @@
 
     if (viewportChangeListener == null)
       viewportChangeListener = createViewportChangeListener();
-    sp.getViewport().addChangeListener(viewportChangeListener);
-
+    
     if (mouseWheelListener == null)
       mouseWheelListener = createMouseWheelListener();
-    sp.addMouseWheelListener(mouseWheelListener);
+    
+    if (containerListener == null)
+      containerListener = new ViewportContainerListener();
+    
+    JViewport v = sp.getViewport();
+    v.addChangeListener(viewportChangeListener);
+    v.addContainerListener(containerListener);
+    
+    // Add mouse wheel listeners to the componets that are probably already
+    // in the view port.
+    for (int i = 0; i < v.getComponentCount(); i++)
+      v.getComponent(i).addMouseWheelListener(mouseWheelListener);
   }
 
   /**
@@ -408,8 +531,14 @@
                                .removeChangeListener(hsbChangeListener);
     sp.getVerticalScrollBar().getModel()
                              .removeChangeListener(vsbChangeListener);
-    sp.getViewport().removeChangeListener(viewportChangeListener);
-    sp.removeMouseWheelListener(mouseWheelListener);
+    
+    JViewport v = sp.getViewport();
+    v.removeChangeListener(viewportChangeListener);
+    v.removeContainerListener(containerListener);
+ 
+    for (int i = 0; i < v.getComponentCount(); i++)
+      v.getComponent(i).removeMouseWheelListener(mouseWheelListener);
+
   }
 
   /**
Index: swing/plaf/basic/BasicTableUI.java
===================================================================
RCS file: /sources/classpath/classpath/javax/swing/plaf/basic/BasicTableUI.java,v
retrieving revision 1.46
diff -u -r1.46 BasicTableUI.java
--- swing/plaf/basic/BasicTableUI.java	19 Mar 2006 13:12:04 -0000	1.46
+++ swing/plaf/basic/BasicTableUI.java	19 Mar 2006 23:55:15 -0000
@@ -52,8 +52,6 @@
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
 import java.awt.event.MouseEvent;
-import java.awt.event.MouseWheelEvent;
-import java.awt.event.MouseWheelListener;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 
@@ -64,10 +62,7 @@
 import javax.swing.DefaultListSelectionModel;
 import javax.swing.InputMap;
 import javax.swing.JComponent;
-import javax.swing.JScrollBar;
-import javax.swing.JScrollPane;
 import javax.swing.JTable;
-import javax.swing.JViewport;
 import javax.swing.KeyStroke;
 import javax.swing.ListSelectionModel;
 import javax.swing.LookAndFeel;
@@ -85,13 +80,7 @@
 import javax.swing.table.TableModel;
 
 public class BasicTableUI extends TableUI
-{ 
-  /**
-   * The number of the table lines to scroll per one mouse wheel click
-   * (from impressions Sun seems scrolling three lines per click.
-   */
-  static int ROWS_PER_WHEEL_CLICK = 3;
-  
+{
   public static ComponentUI createUI(JComponent comp) 
   {
     return new BasicTableUI();
@@ -99,7 +88,7 @@
 
   protected FocusListener focusListener;  
   protected KeyListener keyListener;   
-  protected MouseInputListener	mouseInputListener;   
+  protected MouseInputListener  mouseInputListener;   
   protected CellRendererPane rendererPane;   
   protected JTable table;
 
@@ -183,8 +172,7 @@
     }
   }
 
-  public class MouseInputHandler 
-    implements MouseInputListener, MouseWheelListener
+  public class MouseInputHandler implements MouseInputListener
   {
     Point begin, curr;
 
@@ -309,40 +297,6 @@
           curr = null;
         }
     }
-    
-    /**
-     * Scroll vertically with the mouse whell, the defined number of
-     * rows per wheel click.
-     * 
-     * @author Audrius Meskauskas ([EMAIL PROTECTED])
-     */
-    public void mouseWheelMoved(MouseWheelEvent e)
-    {
-      if (table.getParent() instanceof JViewport)
-        if (table.getParent().getParent() instanceof JScrollPane)
-          {
-            JScrollPane pane = (JScrollPane) table.getParent().getParent();
-            JScrollBar scroll = pane.getVerticalScrollBar();
-
-            if (scroll != null)
-              {
-                int v = e.getWheelRotation() * ROWS_PER_WHEEL_CLICK;
-                int h = table.getRowHeight()
-                        + table.getIntercellSpacing().height;
-                int delta = v * h;
-                int y = pane.getVerticalScrollBar().getValue();
-                
-                // Round to the whole number of the table rows.
-                y = ((y + delta+h/2)/h)*h;
-                
-                if (y < scroll.getMinimum())
-                  y = scroll.getMinimum();
-                if (y > scroll.getMaximum())
-                  y = scroll.getMaximum();
-                pane.getVerticalScrollBar().setValue(y);
-              }
-          }
-    }
   }
 
   /**
@@ -1204,7 +1158,6 @@
       mouseInputListener = createMouseInputListener();
     table.addMouseListener(mouseInputListener);    
     table.addMouseMotionListener(mouseInputListener);
-    table.addMouseWheelListener( (MouseWheelListener) mouseInputListener);
     if (propertyChangeListener == null)
       propertyChangeListener = new PropertyChangeHandler();
     table.addPropertyChangeListener(propertyChangeListener);

Reply via email to