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); + } } /**