Index: javax/swing/JScrollPane.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JScrollPane.java,v
retrieving revision 1.27
diff -u -r1.27 JScrollPane.java
--- javax/swing/JScrollPane.java 12 Sep 2005 20:59:15 -0000 1.27
+++ javax/swing/JScrollPane.java 23 Sep 2005 20:23:59 -0000
@@ -40,16 +40,12 @@
import java.awt.Component;
import java.awt.ComponentOrientation;
-import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
-import java.awt.Point;
import java.awt.Rectangle;
import javax.accessibility.Accessible;
import javax.swing.border.Border;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
import javax.swing.plaf.ScrollPaneUI;
import javax.swing.plaf.UIResource;
@@ -100,7 +96,6 @@
Border viewportBorder;
boolean wheelScrollingEnabled;
- ChangeListener scrollListener;
public JViewport getColumnHeader()
{
@@ -331,18 +326,6 @@
firePropertyChange("horizontalScrollBar", old, h);
sync();
- if (old != null)
- {
- BoundedRangeModel model = old.getModel();
- if (model != null)
- model.removeChangeListener(scrollListener);
- }
- if (h != null)
- {
- BoundedRangeModel model = h.getModel();
- if (model != null)
- model.addChangeListener(scrollListener);
- }
}
public void setHorizontalScrollBarPolicy(int h)
@@ -359,6 +342,7 @@
horizontalScrollBarPolicy = h;
firePropertyChange("horizontalScrollBarPolicy", old, h);
sync();
+ revalidate();
}
public void setLayout(LayoutManager l)
@@ -403,19 +387,6 @@
addNonNull(v, JScrollPane.VERTICAL_SCROLLBAR);
firePropertyChange("verticalScrollBar", old, v);
sync();
-
- if (old != null)
- {
- BoundedRangeModel model = old.getModel();
- if (model != null)
- model.removeChangeListener(scrollListener);
- }
- if (v != null)
- {
- BoundedRangeModel model = v.getModel();
- if (model != null)
- model.addChangeListener(scrollListener);
- }
}
public void setVerticalScrollBarPolicy(int v)
@@ -432,6 +403,7 @@
verticalScrollBarPolicy = v;
firePropertyChange("verticalScrollBarPolicy", old, v);
sync();
+ revalidate();
}
public void setWheelScrollingEnabled(boolean b)
@@ -452,11 +424,7 @@
JViewport old = viewport;
removeNonNull(old);
- if (old != null)
- old.removeChangeListener(scrollListener);
viewport = v;
- if (v != null)
- v.addChangeListener(scrollListener);
addNonNull(v, JScrollPane.VIEWPORT);
revalidate();
repaint();
@@ -494,79 +462,6 @@
return true;
}
- ChangeListener createScrollListener()
- {
- return new ChangeListener()
- {
-
- public void stateChanged(ChangeEvent event)
- {
- JScrollBar vsb = JScrollPane.this.getVerticalScrollBar();
- JScrollBar hsb = JScrollPane.this.getHorizontalScrollBar();
- JViewport vp = JScrollPane.this.getViewport();
-
- if (vp != null && event.getSource() == vp)
- {
- // if the viewport changed, we should update the VSB / HSB
- // models according to the new vertical and horizontal sizes
-
- Rectangle vr = vp.getViewRect();
- Dimension vs = vp.getViewSize();
- if (vsb != null
- && (vsb.getMinimum() != 0
- || vsb.getMaximum() != vs.height
- || vsb.getValue() != vr.y
- || vsb.getVisibleAmount() != vr.height))
- vsb.setValues(vr.y, vr.height, 0, vs.height);
-
- if (hsb != null
- && (hsb.getMinimum() != 0
- || hsb.getMaximum() != vs.width
- || hsb.getValue() != vr.width
- || hsb.getVisibleAmount() != vr.height))
- hsb.setValues(vr.x, vr.width, 0, vs.width);
- }
- else
- {
- // otherwise we got a change update from either the VSB or
- // HSB model, and we need to update the viewport positions of
- // both the main viewport and any row or column headers to
- // match.
-
- int xpos = 0;
- int ypos = 0;
-
- if (vsb != null)
- ypos = vsb.getValue();
-
- if (hsb != null)
- xpos = hsb.getValue();
-
- Point pt = new Point(xpos, ypos);
-
- if (vp != null
- && vp.getViewPosition() != pt)
- vp.setViewPosition(pt);
-
- pt.x = 0;
-
- if (rowHeader != null
- && rowHeader.getViewPosition() != pt)
- rowHeader.setViewPosition(pt);
-
- pt.x = xpos;
- pt.y = 0;
-
- if (columnHeader != null
- && columnHeader.getViewPosition() != pt)
- columnHeader.setViewPosition(pt);
-
- }
- }
- };
- }
-
-
/**
* Creates a new JScrollPane
without a view. The scrollbar
* policy is set to address@hidden #VERTICAL_SCROLLBAR_AS_NEEDED} and
@@ -627,7 +522,6 @@
*/
public JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
{
- scrollListener = createScrollListener();
setVerticalScrollBarPolicy(vsbPolicy);
setVerticalScrollBar(createVerticalScrollBar());
setHorizontalScrollBarPolicy(hsbPolicy);
@@ -635,7 +529,6 @@
viewport = createViewport();
if (view != null)
getViewport().setView(view);
- viewport.addChangeListener(scrollListener);
add(viewport,0);
setLayout(new ScrollPaneLayout());
setOpaque(false);
Index: javax/swing/plaf/basic/BasicScrollPaneUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java,v
retrieving revision 1.12
diff -u -r1.12 BasicScrollPaneUI.java
--- javax/swing/plaf/basic/BasicScrollPaneUI.java 26 Jul 2005 14:16:43 -0000 1.12
+++ javax/swing/plaf/basic/BasicScrollPaneUI.java 23 Sep 2005 20:23:59 -0000
@@ -40,13 +40,22 @@
import java.awt.Dimension;
import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
+import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
+import javax.swing.JViewport;
import javax.swing.ScrollPaneConstants;
import javax.swing.ScrollPaneLayout;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ScrollPaneUI;
@@ -54,9 +63,195 @@
implements ScrollPaneConstants
{
+ /**
+ * Listens for changes in the state of the horizontal scrollbar's model and
+ * updates the scrollpane accordingly.
+ *
+ * @author Roman Kennke (address@hidden)
+ */
+ 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.y = 0;
+ JViewport columnHeader = scrollpane.getColumnHeader();
+ if (columnHeader != null
+ && !columnHeader.getViewPosition().equals(viewPosition))
+ columnHeader.setViewPosition(viewPosition);
+ }
+
+ }
+
+ /**
+ * Listens for changes in the state of the vertical scrollbar's model and
+ * updates the scrollpane accordingly.
+ *
+ * @author Roman Kennke (address@hidden)
+ */
+ 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.x)
+ {
+ viewPosition.y = ypos;
+ vp.setViewPosition(viewPosition);
+ }
+
+ viewPosition.x = 0;
+ JViewport rowHeader = scrollpane.getRowHeader();
+ if (rowHeader != null
+ && !rowHeader.getViewPosition().equals(viewPosition))
+ rowHeader.setViewPosition(viewPosition);
+ }
+
+ }
+
+ /**
+ * Listens for changes of the viewport's extent size and updates the
+ * scrollpane accordingly.
+ *
+ * @author Roman Kennke (address@hidden)
+ */
+ public class ViewportChangeHandler implements ChangeListener
+ {
+
+ /**
+ * Receives notification when the view's size, position or extent size
+ * changes. When the extents size has changed, this method calls
+ * address@hidden BasicScrollPaneUI#syncScrollPaneWithViewport()} to adjust the
+ * scrollbars extents as well.
+ *
+ * @param event the change event
+ */
+ public void stateChanged(ChangeEvent event)
+ {
+ JViewport vp = scrollpane.getViewport();
+ JScrollBar hsb = scrollpane.getHorizontalScrollBar();
+ JScrollBar vsb = scrollpane.getVerticalScrollBar();
+ Dimension extents = vp.getExtentSize();
+ if (extents.width != hsb.getModel().getExtent()
+ || extents.height != vsb.getModel().getExtent())
+ syncScrollPaneWithViewport();
+ }
+
+ }
+
+ /**
+ * Listens for property changes on the scrollpane and update the view
+ * accordingly.
+ *
+ * @author Roman Kennke (address@hidden)
+ */
+ public class PropertyChangeHandler implements PropertyChangeListener
+ {
+
+ /**
+ * Receives notification when any of the scrollpane's bound property
+ * changes. This method calls the appropriate update method on the
+ * ScrollBarUI
.
+ *
+ * @param e the property change event
+ *
+ * @see BasicScrollPaneUI#updateColumnHeader(PropertyChangeEvent)
+ * @see BasicScrollPaneUI#updateRowHeader(PropertyChangeEvent)
+ * @see BasicScrollPaneUI#updateScrollBarDisplayPolicy(PropertyChangeEvent)
+ * @see BasicScrollPaneUI#updateViewport(PropertyChangeEvent)
+ */
+ public void propertyChange(PropertyChangeEvent e)
+ {
+ if (e.getPropertyName().equals("viewport"))
+ updateViewport(e);
+ else if (e.getPropertyName().equals("rowHeader"))
+ updateRowHeader(e);
+ else if (e.getPropertyName().equals("columnHeader"))
+ updateColumnHeader(e);
+ else if (e.getPropertyName().equals("horizontalScrollBarPolicy")
+ || e.getPropertyName().equals("verticalScrollBarPolicy"))
+ updateScrollBarDisplayPolicy(e);
+ }
+
+ }
+
+ /**
+ * Listens for mouse wheel events and update the scrollpane accordingly.
+ *
+ * @author Roman Kennke (address@hidden)
+ *
+ * @since 1.4
+ */
+ protected class MouseWheelHandler implements MouseWheelListener
+ {
+
+ /**
+ * Receives notification whenever the mouse wheel is moved.
+ *
+ * @param event the mouse wheel event
+ */
+ public void mouseWheelMoved(MouseWheelEvent event)
+ {
+ }
+
+ }
+
/** The Scrollpane for which the UI is provided by this class. */
protected JScrollPane scrollpane;
+ /**
+ * The horizontal scrollbar listener.
+ */
+ protected ChangeListener hsbChangeListener;
+
+ /**
+ * The vertical scrollbar listener.
+ */
+ protected ChangeListener vsbChangeListener;
+
+ /**
+ * The viewport listener.
+ */
+ protected ChangeListener viewportChangeListener;
+
+ /**
+ * The scrollpane property change listener.
+ */
+ protected PropertyChangeListener spPropertyChangeListener;
+
+ /**
+ * The mousewheel listener for the scrollpane.
+ */
+ MouseWheelListener mouseWheelListener;
+
public static ComponentUI createUI(final JComponent c)
{
return new BasicScrollPaneUI();
@@ -85,16 +280,103 @@
public void installUI(final JComponent c)
{
super.installUI(c);
- this.installDefaults((JScrollPane)c);
+ installDefaults((JScrollPane) c);
+ installListeners((JScrollPane) c);
+ }
+
+ /**
+ * Installs the listeners on the scrollbars, the viewport and the scrollpane.
+ *
+ * @param sp the scrollpane on which to install the listeners
+ */
+ protected void installListeners(JScrollPane sp)
+ {
+ if (spPropertyChangeListener == null)
+ spPropertyChangeListener = createPropertyChangeListener();
+ sp.addPropertyChangeListener(spPropertyChangeListener);
+
+ if (hsbChangeListener == null)
+ hsbChangeListener = createHSBChangeListener();
+ sp.getHorizontalScrollBar().getModel().addChangeListener(hsbChangeListener);
+
+ if (vsbChangeListener == null)
+ vsbChangeListener = createVSBChangeListener();
+ sp.getVerticalScrollBar().getModel().addChangeListener(vsbChangeListener);
+
+ if (viewportChangeListener == null)
+ viewportChangeListener = createViewportChangeListener();
+ sp.getViewport().addChangeListener(viewportChangeListener);
+
+ if (mouseWheelListener == null)
+ mouseWheelListener = new MouseWheelHandler();
+ sp.addMouseWheelListener(mouseWheelListener);
+ }
+
+ /**
+ * Creates and returns the change listener for the horizontal scrollbar.
+ *
+ * @return the change listener for the horizontal scrollbar
+ */
+ protected ChangeListener createHSBChangeListener()
+ {
+ return new HSBChangeListener();
+ }
+
+ /**
+ * Creates and returns the change listener for the vertical scrollbar.
+ *
+ * @return the change listener for the vertical scrollbar
+ */
+ protected ChangeListener createVSBChangeListener()
+ {
+ return new VSBChangeListener();
+ }
+
+ /**
+ * Creates and returns the change listener for the viewport.
+ *
+ * @return the change listener for the viewport
+ */
+ protected ChangeListener createViewportChangeListener()
+ {
+ return new ViewportChangeHandler();
+ }
+
+ /**
+ * Creates and returns the property change listener for the scrollpane.
+ *
+ * @return the property change listener for the scrollpane
+ */
+ protected PropertyChangeListener createPropertyChangeListener()
+ {
+ return new PropertyChangeHandler();
}
public void uninstallUI(final JComponent c)
{
super.uninstallUI(c);
this.uninstallDefaults((JScrollPane)c);
+ uninstallListeners((JScrollPane) c);
+ }
+
+ /**
+ * Uninstalls all the listeners that have been installed in
+ * address@hidden #installListeners(JScrollPane)}.
+ *
+ * @param c the scrollpane from which to uninstall the listeners
+ */
+ protected void uninstallListeners(JComponent c)
+ {
+ JScrollPane sp = (JScrollPane) c;
+ sp.removePropertyChangeListener(spPropertyChangeListener);
+ sp.getHorizontalScrollBar().getModel()
+ .removeChangeListener(hsbChangeListener);
+ sp.getVerticalScrollBar().getModel()
+ .removeChangeListener(vsbChangeListener);
+ sp.getViewport().removeChangeListener(viewportChangeListener);
+ sp.removeMouseWheelListener(mouseWheelListener);
}
-
public Dimension getMinimumSize(JComponent c)
{
JScrollPane p = (JScrollPane ) c;
@@ -106,6 +388,68 @@
{
// do nothing; the normal painting-of-children algorithm, along with
// ScrollPaneLayout, does all the relevant work.
+ }
+
+ /**
+ * Synchronizes the scrollbars with the viewport's extents.
+ */
+ protected void syncScrollPaneWithViewport()
+ {
+ JViewport vp = scrollpane.getViewport();
+ JScrollBar vsb = scrollpane.getVerticalScrollBar();
+ JScrollBar hsb = scrollpane.getHorizontalScrollBar();
+ hsb.getModel().setExtent(vp.getExtentSize().width);
+ vsb.getModel().setExtent(vp.getExtentSize().height);
+ }
+
+ /**
+ * Receives notification when the columnHeader
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?
+ }
+
+ /**
+ * Receives notification when the rowHeader
property has changed
+ * on the scrollpane.
+ *
+ * @param ev the property change event
+ */
+ protected void updateRowHeader(PropertyChangeEvent ev)
+ {
+ // TODO: Find out what should be done here. Or is this only a hook?
+ }
+
+ /**
+ * Receives notification when the scrollBarDisplayPolicy
+ * property has changed on the scrollpane.
+ *
+ * @param ev the property change event
+ */
+ protected void updateScrollBarDisplayPolicy(PropertyChangeEvent ev)
+ {
+ // TODO: Find out what should be done here. Or is this only a hook?
+ }
+
+ /**
+ * Receives notification when the viewport
property has changed
+ * on the scrollpane.
+ *
+ * This method sets removes the viewportChangeListener from the old viewport
+ * and adds it to the new viewport.
+ *
+ * @param ev the property change event
+ */
+ protected void updateViewport(PropertyChangeEvent ev)
+ {
+ JViewport oldViewport = (JViewport) ev.getOldValue();
+ oldViewport.removeChangeListener(viewportChangeListener);
+ JViewport newViewport = (JViewport) ev.getNewValue();
+ oldViewport.addChangeListener(viewportChangeListener);
}
}