FileDocCategorySizeDatePackage
BasicScrollPaneUI.javaAPI DocJava SE 6 API41581Tue Jun 10 00:26:48 BST 2008javax.swing.plaf.basic

BasicScrollPaneUI

public class BasicScrollPaneUI extends ScrollPaneUI implements ScrollPaneConstants
A default L&F implementation of ScrollPaneUI.
version
1.73 11/17/05
author
Hans Muller

Fields Summary
protected JScrollPane
scrollpane
protected ChangeListener
vsbChangeListener
protected ChangeListener
hsbChangeListener
protected ChangeListener
viewportChangeListener
protected PropertyChangeListener
spPropertyChangeListener
private MouseWheelListener
mouseScrollListener
private PropertyChangeListener
vsbPropertyChangeListener
PropertyChangeListener installed on the vertical scrollbar.
private PropertyChangeListener
hsbPropertyChangeListener
PropertyChangeListener installed on the horizontal scrollbar.
private Handler
handler
private boolean
setValueCalled
State flag that shows whether setValue() was called from a user program before the value of "extent" was set in right-to-left component orientation.
Constructors Summary
Methods Summary
protected javax.swing.event.ChangeListenercreateHSBChangeListener()

	return getHandler();
    
private java.beans.PropertyChangeListenercreateHSBPropertyChangeListener()
Returns a PropertyChangeListener that will be installed on the horizontal JScrollBar.

        return getHandler();
    
protected java.awt.event.MouseWheelListenercreateMouseWheelListener()
Creates an instance of MouseWheelListener, which is added to the JScrollPane by installUI(). The returned MouseWheelListener is used to handle mouse wheel-driven scrolling.

return
MouseWheelListener which implements wheel-driven scrolling
see
#installUI
see
MouseWheelHandler
since
1.4

        return getHandler();
    
protected java.beans.PropertyChangeListenercreatePropertyChangeListener()
Creates an instance of PropertyChangeListener that's added to the JScrollPane by installUI(). Subclasses can override this method to return a custom PropertyChangeListener, e.g.
class MyScrollPaneUI extends BasicScrollPaneUI {
protected PropertyChangeListener createPropertyChangeListener() {
return new MyPropertyChangeListener();
}
public class MyPropertyChangeListener extends PropertyChangeListener {
public void propertyChange(PropertyChangeEvent e) {
if (e.getPropertyName().equals("viewport")) {
// do some extra work when the viewport changes
}
super.propertyChange(e);
}
}
}

see
java.beans.PropertyChangeListener
see
#installUI

        return getHandler();
    
public static javax.swing.plaf.ComponentUIcreateUI(javax.swing.JComponent x)



         
	return new BasicScrollPaneUI();
    
protected javax.swing.event.ChangeListenercreateVSBChangeListener()

	return getHandler();
    
private java.beans.PropertyChangeListenercreateVSBPropertyChangeListener()
Returns a PropertyChangeListener that will be installed on the vertical JScrollBar.

        return getHandler();
    
protected javax.swing.event.ChangeListenercreateViewportChangeListener()

	return getHandler();
    
public intgetBaseline(javax.swing.JComponent c, int width, int height)
Returns the baseline.

throws
NullPointerException {@inheritDoc}
throws
IllegalArgumentException {@inheritDoc}
see
javax.swing.JComponent#getBaseline(int, int)
since
1.6

        JViewport viewport = scrollpane.getViewport();
        Insets spInsets = scrollpane.getInsets();
        int y = spInsets.top;
        height = height - spInsets.top - spInsets.bottom;
        width = width - spInsets.left - spInsets.right;
        JViewport columnHeader = scrollpane.getColumnHeader();
        if (columnHeader != null && columnHeader.isVisible()) {
            Component header = columnHeader.getView();
            if (header != null && header.isVisible()) {
                // Header is always given it's preferred size.
                Dimension headerPref = header.getPreferredSize();
                int baseline = header.getBaseline(headerPref.width,
                                                  headerPref.height);
                if (baseline >= 0) {
                    return y + baseline;
                }
            }
            Dimension columnPref = columnHeader.getPreferredSize();
            height -= columnPref.height;
            y += columnPref.height;
        }
        Component view = (viewport == null) ? null : viewport.getView();
        if (view != null && view.isVisible() &&
                view.getBaselineResizeBehavior() ==
                Component.BaselineResizeBehavior.CONSTANT_ASCENT) {
            Border viewportBorder = scrollpane.getViewportBorder();
            if (viewportBorder != null) {
                Insets vpbInsets = viewportBorder.getBorderInsets(scrollpane);
                y += vpbInsets.top;
                height = height - vpbInsets.top - vpbInsets.bottom;
                width = width - vpbInsets.left - vpbInsets.right;
            }
            if (view.getWidth() > 0 && view.getHeight() > 0) {
                Dimension min = view.getMinimumSize();
                width = Math.max(min.width, view.getWidth());
                height = Math.max(min.height, view.getHeight());
            }
            if (width > 0 && height > 0) {
                int baseline = view.getBaseline(width, height);
                if (baseline > 0) {
                    return y + baseline;
                }
            }
        }
        return -1;
    
public java.awt.Component$BaselineResizeBehaviorgetBaselineResizeBehavior(javax.swing.JComponent c)
Returns an enum indicating how the baseline of the component changes as the size changes.

throws
NullPointerException {@inheritDoc}
see
javax.swing.JComponent#getBaseline(int, int)
since
1.6

        super.getBaselineResizeBehavior(c);
        // Baseline is either from the header, in which case it's always
        // the same size and therefor can be created as CONSTANT_ASCENT.
        // If the header doesn't have a baseline than the baseline will only
        // be valid if it's BaselineResizeBehavior is
        // CONSTANT_ASCENT, so, return CONSTANT_ASCENT.
        return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
    
private javax.swing.plaf.basic.BasicScrollPaneUI$HandlergetHandler()

        if (handler == null) {
            handler = new Handler();
        }
        return handler;
    
javax.swing.InputMapgetInputMap(int condition)

	if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
	    InputMap keyMap = (InputMap)DefaultLookup.get(scrollpane, this,
                                        "ScrollPane.ancestorInputMap");
	    InputMap rtlKeyMap;

	    if (scrollpane.getComponentOrientation().isLeftToRight() ||
		    ((rtlKeyMap = (InputMap)DefaultLookup.get(scrollpane, this,
                    "ScrollPane.ancestorInputMap.RightToLeft")) == null)) {
		return keyMap;
	    } else {
		rtlKeyMap.setParent(keyMap);
		return rtlKeyMap;
	    }
	}
	return null;
    
public java.awt.DimensiongetMaximumSize(javax.swing.JComponent c)

return
new Dimension(Short.MAX_VALUE, Short.MAX_VALUE)

	return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
    
protected voidinstallDefaults(javax.swing.JScrollPane scrollpane)

	LookAndFeel.installBorder(scrollpane, "ScrollPane.border");
	LookAndFeel.installColorsAndFont(scrollpane, 
	    "ScrollPane.background", 
	    "ScrollPane.foreground", 
            "ScrollPane.font");

        Border vpBorder = scrollpane.getViewportBorder();
        if ((vpBorder == null) ||( vpBorder instanceof UIResource)) {
	    vpBorder = UIManager.getBorder("ScrollPane.viewportBorder");
	    scrollpane.setViewportBorder(vpBorder);
        }
        LookAndFeel.installProperty(scrollpane, "opaque", Boolean.TRUE);
    
protected voidinstallKeyboardActions(javax.swing.JScrollPane c)

	InputMap inputMap = getInputMap(JComponent.
				  WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

	SwingUtilities.replaceUIInputMap(c, JComponent.
			       WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap);

        LazyActionMap.installLazyActionMap(c, BasicScrollPaneUI.class,
                                           "ScrollPane.actionMap");
    
protected voidinstallListeners(javax.swing.JScrollPane c)

	vsbChangeListener = createVSBChangeListener();
        vsbPropertyChangeListener = createVSBPropertyChangeListener();
	hsbChangeListener = createHSBChangeListener();
        hsbPropertyChangeListener = createHSBPropertyChangeListener();
	viewportChangeListener = createViewportChangeListener();
	spPropertyChangeListener = createPropertyChangeListener();

	JViewport viewport = scrollpane.getViewport();
	JScrollBar vsb = scrollpane.getVerticalScrollBar();
	JScrollBar hsb = scrollpane.getHorizontalScrollBar();

	if (viewport != null) {
	    viewport.addChangeListener(viewportChangeListener);
	}
	if (vsb != null) {
	    vsb.getModel().addChangeListener(vsbChangeListener);
            vsb.addPropertyChangeListener(vsbPropertyChangeListener);
	}
	if (hsb != null) {
	    hsb.getModel().addChangeListener(hsbChangeListener);
            hsb.addPropertyChangeListener(hsbPropertyChangeListener);
	}

	scrollpane.addPropertyChangeListener(spPropertyChangeListener);

    mouseScrollListener = createMouseWheelListener();
    scrollpane.addMouseWheelListener(mouseScrollListener);

    
public voidinstallUI(javax.swing.JComponent x)

	scrollpane = (JScrollPane)x;
	installDefaults(scrollpane);
	installListeners(scrollpane);
	installKeyboardActions(scrollpane);
    
static voidloadActionMap(javax.swing.plaf.basic.LazyActionMap map)

        map.put(new Actions(Actions.SCROLL_UP));
	map.put(new Actions(Actions.SCROLL_DOWN));
	map.put(new Actions(Actions.SCROLL_HOME));
	map.put(new Actions(Actions.SCROLL_END));
	map.put(new Actions(Actions.UNIT_SCROLL_UP));
	map.put(new Actions(Actions.UNIT_SCROLL_DOWN));
        map.put(new Actions(Actions.SCROLL_LEFT));
        map.put(new Actions(Actions.SCROLL_RIGHT));
        map.put(new Actions(Actions.UNIT_SCROLL_RIGHT));
        map.put(new Actions(Actions.UNIT_SCROLL_LEFT));
    
public voidpaint(java.awt.Graphics g, javax.swing.JComponent c)

	Border vpBorder = scrollpane.getViewportBorder();
	if (vpBorder != null) {
	    Rectangle r = scrollpane.getViewportBorderBounds();
	    vpBorder.paintBorder(scrollpane, g, r.x, r.y, r.width, r.height);
	}
    
protected voidsyncScrollPaneWithViewport()

	JViewport viewport = scrollpane.getViewport();
	JScrollBar vsb = scrollpane.getVerticalScrollBar();
	JScrollBar hsb = scrollpane.getHorizontalScrollBar();
	JViewport rowHead = scrollpane.getRowHeader();
	JViewport colHead = scrollpane.getColumnHeader();
	boolean ltr = scrollpane.getComponentOrientation().isLeftToRight();

	if (viewport != null) {
	    Dimension extentSize = viewport.getExtentSize();
	    Dimension viewSize = viewport.getViewSize();
	    Point viewPosition = viewport.getViewPosition();

	    if (vsb != null) {
		int extent = extentSize.height;
		int max = viewSize.height;
		int value = Math.max(0, Math.min(viewPosition.y, max - extent));
		vsb.setValues(value, extent, 0, max);
	    }

	    if (hsb != null) {
		int extent = extentSize.width;
		int max = viewSize.width;
		int value;

		if (ltr) {
		    value = Math.max(0, Math.min(viewPosition.x, max - extent));
		} else {
		    int currentValue = hsb.getValue();

		    /* Use a particular formula to calculate "value"
		     * until effective x coordinate is calculated.
		     */
		    if (setValueCalled && ((max - currentValue) == viewPosition.x)) {
			value = Math.max(0, Math.min(max - extent, currentValue));
			/* After "extent" is set, turn setValueCalled flag off.
			 */
			if (extent != 0) {
			    setValueCalled = false;
			}
		    } else {
			if (extent > max) {
			    viewPosition.x = max - extent;
			    viewport.setViewPosition(viewPosition);
			    value = 0;
			} else {
			   /* The following line can't handle a small value of
			    * viewPosition.x like Integer.MIN_VALUE correctly
			    * because (max - extent - viewPositoiin.x) causes
			    * an overflow. As a result, value becomes zero.
			    * (e.g. setViewPosition(Integer.MAX_VALUE, ...)
			    *       in a user program causes a overflow.
			    *       Its expected value is (max - extent).)
			    * However, this seems a trivial bug and adding a
			    * fix makes this often-called method slow, so I'll
			    * leave it until someone claims.
			    */
			    value = Math.max(0, Math.min(max - extent, max - extent - viewPosition.x));
			}
		    }
		}
		hsb.setValues(value, extent, 0, max);
	    }

	    if (rowHead != null) {
		Point p = rowHead.getViewPosition();
		p.y = viewport.getViewPosition().y;
                p.x = 0;
		rowHead.setViewPosition(p);
	    }

	    if (colHead != null) {
		Point p = colHead.getViewPosition();
		if (ltr) {
		    p.x = viewport.getViewPosition().x;
		} else {
		    p.x = Math.max(0, viewport.getViewPosition().x);
		}
                p.y = 0;
		colHead.setViewPosition(p);
	    }
	}
    
protected voiduninstallDefaults(javax.swing.JScrollPane c)

	LookAndFeel.uninstallBorder(scrollpane);

        if (scrollpane.getViewportBorder() instanceof UIResource) {
            scrollpane.setViewportBorder(null);
        }
    
protected voiduninstallKeyboardActions(javax.swing.JScrollPane c)

	SwingUtilities.replaceUIActionMap(c, null);
	SwingUtilities.replaceUIInputMap(c, JComponent.
			   WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
    
protected voiduninstallListeners(javax.swing.JComponent c)

	JViewport viewport = scrollpane.getViewport();
	JScrollBar vsb = scrollpane.getVerticalScrollBar();
	JScrollBar hsb = scrollpane.getHorizontalScrollBar();

	if (viewport != null) {
	    viewport.removeChangeListener(viewportChangeListener);
	}
	if (vsb != null) {
	    vsb.getModel().removeChangeListener(vsbChangeListener);
            vsb.removePropertyChangeListener(vsbPropertyChangeListener);
	}
	if (hsb != null) {
	    hsb.getModel().removeChangeListener(hsbChangeListener);
            hsb.removePropertyChangeListener(hsbPropertyChangeListener);
	}

	scrollpane.removePropertyChangeListener(spPropertyChangeListener);

    if (mouseScrollListener != null) {
        scrollpane.removeMouseWheelListener(mouseScrollListener);
    }

	vsbChangeListener = null;
	hsbChangeListener = null;
	viewportChangeListener = null;
	spPropertyChangeListener = null;
        mouseScrollListener = null;
        handler = null;
    
public voiduninstallUI(javax.swing.JComponent c)

	uninstallDefaults(scrollpane);
	uninstallListeners(scrollpane);
	uninstallKeyboardActions(scrollpane);
	scrollpane = null;
    
protected voidupdateColumnHeader(java.beans.PropertyChangeEvent e)

	JViewport newColHead = (JViewport)(e.getNewValue());
	if (newColHead != null) {
	    JViewport viewport = scrollpane.getViewport();
	    Point p = newColHead.getViewPosition();
	    if (viewport == null) {
		p.x = 0;
	    } else {
		if (scrollpane.getComponentOrientation().isLeftToRight()) {
		    p.x = viewport.getViewPosition().x;
		} else {
		    p.x = Math.max(0, viewport.getViewPosition().x);
		}
	    }
	    newColHead.setViewPosition(p);
	    scrollpane.add(newColHead, COLUMN_HEADER);
	}
    
private voidupdateHorizontalScrollBar(java.beans.PropertyChangeEvent pce)

        updateScrollBar(pce, hsbChangeListener, hsbPropertyChangeListener);
    
protected voidupdateRowHeader(java.beans.PropertyChangeEvent e)

	JViewport newRowHead = (JViewport)(e.getNewValue());
	if (newRowHead != null) {
	    JViewport viewport = scrollpane.getViewport();
	    Point p = newRowHead.getViewPosition();
	    p.y = (viewport != null) ? viewport.getViewPosition().y : 0;
	    newRowHead.setViewPosition(p);
	}
    
private voidupdateScrollBar(java.beans.PropertyChangeEvent pce, javax.swing.event.ChangeListener cl, java.beans.PropertyChangeListener pcl)

        JScrollBar sb = (JScrollBar)pce.getOldValue();
        if (sb != null) {
            if (cl != null) {
                sb.getModel().removeChangeListener(cl);
            }
            if (pcl != null) {
                sb.removePropertyChangeListener(pcl);
            }
        }
        sb = (JScrollBar)pce.getNewValue();
        if (sb != null) {
            if (cl != null) {
                sb.getModel().addChangeListener(cl);
            }
            if (pcl != null) {
                sb.addPropertyChangeListener(pcl);
            }
        }
    
protected voidupdateScrollBarDisplayPolicy(java.beans.PropertyChangeEvent e)

	scrollpane.revalidate();
	scrollpane.repaint();
    
private voidupdateVerticalScrollBar(java.beans.PropertyChangeEvent pce)

        updateScrollBar(pce, vsbChangeListener, vsbPropertyChangeListener);
    
protected voidupdateViewport(java.beans.PropertyChangeEvent e)

	JViewport oldViewport = (JViewport)(e.getOldValue());
	JViewport newViewport = (JViewport)(e.getNewValue());

	if (oldViewport != null) {
	    oldViewport.removeChangeListener(viewportChangeListener);
	}
	
	if (newViewport != null) {
	    Point p = newViewport.getViewPosition();
	    if (scrollpane.getComponentOrientation().isLeftToRight()) {
		p.x = Math.max(p.x, 0);
	    } else {
		int max = newViewport.getViewSize().width;
		int extent = newViewport.getExtentSize().width;
		if (extent > max) {
		    p.x = max - extent;
		} else {
		    p.x = Math.max(0, Math.min(max - extent, p.x));
		}
	    }
	    p.y = Math.max(p.y, 0);
	    newViewport.setViewPosition(p);
	    newViewport.addChangeListener(viewportChangeListener);
	}