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);