- /*
 - * @(#)BasicScrollPaneUI.java 1.52 00/02/02
 - *
 - * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
 - *
 - * This software is the proprietary information of Sun Microsystems, Inc.
 - * Use is subject to license terms.
 - *
 - */
 - package javax.swing.plaf.basic;
 - import javax.swing.*;
 - import javax.swing.event.*;
 - import javax.swing.border.*;
 - import javax.swing.plaf.*;
 - import java.beans.PropertyChangeListener;
 - import java.beans.PropertyChangeEvent;
 - import java.awt.Component;
 - import java.awt.Container;
 - import java.awt.LayoutManager;
 - import java.awt.Rectangle;
 - import java.awt.Dimension;
 - import java.awt.Point;
 - import java.awt.Insets;
 - import java.awt.Graphics;
 - import java.awt.event.*;
 - import java.io.Serializable;
 - /**
 - * A default L&F implementation of ScrollPaneUI.
 - *
 - * @version 1.52 02/02/00
 - * @author Hans Muller
 - */
 - public class BasicScrollPaneUI
 - extends ScrollPaneUI implements ScrollPaneConstants
 - {
 - protected JScrollPane scrollpane;
 - protected ChangeListener vsbChangeListener;
 - protected ChangeListener hsbChangeListener;
 - protected ChangeListener viewportChangeListener;
 - protected PropertyChangeListener spPropertyChangeListener;
 - public static ComponentUI createUI(JComponent x) {
 - return new BasicScrollPaneUI();
 - }
 - public void paint(Graphics g, 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);
 - }
 - }
 - /**
 - * @return null which indicates that the LayoutManager will compute the value
 - * @see JComponent#getPreferredSize
 - */
 - public Dimension getPreferredSize(JComponent c) {
 - return null;
 - }
 - /**
 - * @return the preferred size
 - * @see #getPreferredSize
 - */
 - public Dimension getMinimumSize(JComponent c) {
 - return getPreferredSize(c);
 - }
 - /**
 - * @return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE)
 - */
 - public Dimension getMaximumSize(JComponent c) {
 - return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
 - }
 - protected void installDefaults(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);
 - }
 - }
 - protected void installListeners(JScrollPane c)
 - {
 - vsbChangeListener = createVSBChangeListener();
 - hsbChangeListener = createHSBChangeListener();
 - 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);
 - }
 - if (hsb != null) {
 - hsb.getModel().addChangeListener(hsbChangeListener);
 - }
 - scrollpane.addPropertyChangeListener(spPropertyChangeListener);
 - }
 - protected void installKeyboardActions(JScrollPane c) {
 - InputMap inputMap = getInputMap(JComponent.
 - WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
 - SwingUtilities.replaceUIInputMap(c, JComponent.
 - WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap);
 - ActionMap actionMap = getActionMap();
 - SwingUtilities.replaceUIActionMap(c, actionMap);
 - }
 - InputMap getInputMap(int condition) {
 - if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
 - return (InputMap)UIManager.get("ScrollPane.ancestorInputMap");
 - }
 - return null;
 - }
 - ActionMap getActionMap() {
 - ActionMap map = (ActionMap)UIManager.get("ScrollPane.actionMap");
 - if (map == null) {
 - map = createActionMap();
 - if (map != null) {
 - UIManager.put("ScrollPane.actionMap", map);
 - }
 - }
 - return map;
 - }
 - ActionMap createActionMap() {
 - ActionMap map = new ActionMapUIResource();
 - map.put("scrollUp", new ScrollAction("scrollUp", SwingConstants.
 - VERTICAL, -1, true));
 - map.put("scrollDown", new ScrollAction("scrollDown",
 - SwingConstants.VERTICAL, 1, true));
 - map.put("scrollLeft", new ScrollAction("scrollLeft",
 - SwingConstants.HORIZONTAL, -1, true));
 - map.put("scrollRight", new ScrollAction("ScrollRight",
 - SwingConstants.HORIZONTAL, 1, true));
 - map.put("scrollHome", new ScrollHomeAction("ScrollHome"));
 - map.put("scrollEnd", new ScrollEndAction("ScrollEnd"));
 - map.put("unitScrollRight", new ScrollAction
 - ("UnitScrollRight", SwingConstants.HORIZONTAL, 1, false));
 - map.put("unitScrollLeft", new ScrollAction
 - ("UnitScrollLeft", SwingConstants.HORIZONTAL, -1, false));
 - map.put("unitScrollUp", new ScrollAction
 - ("UnitScrollUp", SwingConstants.VERTICAL, -1,false));
 - map.put("unitScrollDown", new ScrollAction
 - ("UnitScrollDown", SwingConstants.VERTICAL, 1, false));
 - return map;
 - }
 - public void installUI(JComponent x) {
 - scrollpane = (JScrollPane)x;
 - installDefaults(scrollpane);
 - installListeners(scrollpane);
 - installKeyboardActions(scrollpane);
 - }
 - protected void uninstallDefaults(JScrollPane c) {
 - LookAndFeel.uninstallBorder(scrollpane);
 - if (scrollpane.getViewportBorder() instanceof UIResource) {
 - scrollpane.setViewportBorder(null);
 - }
 - }
 - protected void uninstallListeners(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);
 - }
 - if (hsb != null) {
 - hsb.getModel().removeChangeListener(hsbChangeListener);
 - }
 - scrollpane.removePropertyChangeListener(spPropertyChangeListener);
 - vsbChangeListener = null;
 - hsbChangeListener = null;
 - viewportChangeListener = null;
 - spPropertyChangeListener = null;
 - }
 - protected void uninstallKeyboardActions(JScrollPane c) {
 - SwingUtilities.replaceUIActionMap(c, null);
 - SwingUtilities.replaceUIInputMap(c, JComponent.
 - WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
 - }
 - public void uninstallUI(JComponent c) {
 - uninstallDefaults(scrollpane);
 - uninstallListeners(scrollpane);
 - uninstallKeyboardActions(scrollpane);
 - scrollpane = null;
 - }
 - protected void syncScrollPaneWithViewport()
 - {
 - JViewport viewport = scrollpane.getViewport();
 - JScrollBar vsb = scrollpane.getVerticalScrollBar();
 - JScrollBar hsb = scrollpane.getHorizontalScrollBar();
 - JViewport rowHead = scrollpane.getRowHeader();
 - JViewport colHead = scrollpane.getColumnHeader();
 - 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 = Math.max(0, Math.min(viewPosition.x, max - extent));
 - hsb.setValues(value, extent, 0, max);
 - }
 - if (rowHead != null) {
 - Point p = rowHead.getViewPosition();
 - p.y = viewport.getViewPosition().y;
 - rowHead.setViewPosition(p);
 - }
 - if (colHead != null) {
 - Point p = colHead.getViewPosition();
 - p.x = viewport.getViewPosition().x;
 - colHead.setViewPosition(p);
 - }
 - }
 - }
 - /**
 - * Listener for viewport events.
 - */
 - public class ViewportChangeHandler implements ChangeListener
 - {
 - public void stateChanged(ChangeEvent e) {
 - syncScrollPaneWithViewport();
 - }
 - }
 - protected ChangeListener createViewportChangeListener() {
 - return new ViewportChangeHandler();
 - }
 - /**
 - * Horizontal scrollbar listener.
 - */
 - public class HSBChangeListener implements ChangeListener
 - {
 - public void stateChanged(ChangeEvent e)
 - {
 - JViewport viewport = scrollpane.getViewport();
 - if (viewport != null) {
 - BoundedRangeModel model = (BoundedRangeModel)(e.getSource());
 - Point p = viewport.getViewPosition();
 - p.x = model.getValue();
 - viewport.setViewPosition(p);
 - }
 - }
 - }
 - protected ChangeListener createHSBChangeListener() {
 - return new HSBChangeListener();
 - }
 - /**
 - * Vertical scrollbar listener.
 - */
 - public class VSBChangeListener implements ChangeListener
 - {
 - public void stateChanged(ChangeEvent e)
 - {
 - JViewport viewport = scrollpane.getViewport();
 - if (viewport != null) {
 - BoundedRangeModel model = (BoundedRangeModel)(e.getSource());
 - Point p = viewport.getViewPosition();
 - p.y = model.getValue();
 - viewport.setViewPosition(p);
 - }
 - }
 - }
 - protected ChangeListener createVSBChangeListener() {
 - return new VSBChangeListener();
 - }
 - protected void updateScrollBarDisplayPolicy(PropertyChangeEvent e) {
 - scrollpane.revalidate();
 - scrollpane.repaint();
 - }
 - protected void updateViewport(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();
 - p.x = Math.max(p.x, 0);
 - p.y = Math.max(p.y, 0);
 - newViewport.setViewPosition(p);
 - newViewport.addChangeListener(viewportChangeListener);
 - }
 - }
 - protected void updateRowHeader(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);
 - }
 - }
 - protected void updateColumnHeader(PropertyChangeEvent e)
 - {
 - JViewport newColHead = (JViewport)(e.getNewValue());
 - if (newColHead != null) {
 - JViewport viewport = scrollpane.getViewport();
 - Point p = newColHead.getViewPosition();
 - p.x = (viewport != null) ? viewport.getViewPosition().x : 0;
 - newColHead.setViewPosition(p);
 - scrollpane.add(newColHead, COLUMN_HEADER);
 - }
 - }
 - private void updateHorizontalScrollBar(PropertyChangeEvent pce) {
 - updateScrollBar(pce, hsbChangeListener);
 - }
 - private void updateVerticalScrollBar(PropertyChangeEvent pce) {
 - updateScrollBar(pce, vsbChangeListener);
 - }
 - private void updateScrollBar(PropertyChangeEvent pce, ChangeListener cl) {
 - if (cl != null) {
 - JScrollBar sb = (JScrollBar)pce.getOldValue();
 - if (sb != null) {
 - sb.getModel().removeChangeListener(cl);
 - }
 - sb = (JScrollBar)pce.getNewValue();
 - if (sb != null) {
 - sb.getModel().addChangeListener(cl);
 - }
 - }
 - }
 - public class PropertyChangeHandler implements PropertyChangeListener
 - {
 - public void propertyChange(PropertyChangeEvent e)
 - {
 - String propertyName = e.getPropertyName();
 - if (propertyName.equals("verticalScrollBarDisplayPolicy")) {
 - updateScrollBarDisplayPolicy(e);
 - }
 - else if (propertyName.equals("horizontalScrollBarDisplayPolicy")) {
 - updateScrollBarDisplayPolicy(e);
 - }
 - else if (propertyName.equals("viewport")) {
 - updateViewport(e);
 - }
 - else if (propertyName.equals("rowHeader")) {
 - updateRowHeader(e);
 - }
 - else if (propertyName.equals("columnHeader")) {
 - updateColumnHeader(e);
 - }
 - else if (propertyName.equals("verticalScrollBar")) {
 - updateVerticalScrollBar(e);
 - }
 - else if (propertyName.equals("horizontalScrollBar")) {
 - updateHorizontalScrollBar(e);
 - }
 - }
 - }
 - /**
 - * 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.
 - * <pre>
 - * class MyScrollPaneUI extends BasicScrollPaneUI {
 - * protected PropertyChangeListener <b>createPropertyListener</b>() {
 - * return new MyPropertyListener();
 - * }
 - * public class MyPropertyListener extends PropertyListener {
 - * public void propertyChange(PropertyChangeEvent e) {
 - * if (e.getPropertyName().equals("viewport")) {
 - * // do some extra work when the viewport changes
 - * }
 - * super.propertyChange(e);
 - * }
 - * }
 - * }
 - * </pre>
 - *
 - * @see PropertyListener
 - * @see #installUI
 - */
 - protected PropertyChangeListener createPropertyChangeListener() {
 - return new PropertyChangeHandler();
 - }
 - /**
 - * Action to scroll left/right/up/down.
 - */
 - private static class ScrollAction extends AbstractAction {
 - /** Direction to scroll. */
 - protected int orientation;
 - /** 1 indicates scroll down, -1 up. */
 - protected int direction;
 - /** True indicates a block scroll, otherwise a unit scroll. */
 - private boolean block;
 - protected ScrollAction(String name, int orientation, int direction,
 - boolean block) {
 - super(name);
 - this.orientation = orientation;
 - this.direction = direction;
 - this.block = block;
 - }
 - public void actionPerformed(ActionEvent e) {
 - JScrollPane scrollpane = (JScrollPane)e.getSource();
 - JViewport vp = scrollpane.getViewport();
 - Component view;
 - if (vp != null && (view = vp.getView()) != null) {
 - Rectangle visRect = vp.getViewRect();
 - Dimension vSize = view.getSize();
 - int amount;
 - if (view instanceof Scrollable) {
 - if (block) {
 - amount = ((Scrollable)view).getScrollableBlockIncrement
 - (visRect, orientation, direction);
 - }
 - else {
 - amount = ((Scrollable)view).getScrollableUnitIncrement
 - (visRect, orientation, direction);
 - }
 - }
 - else {
 - if (block) {
 - if (orientation == SwingConstants.VERTICAL) {
 - amount = visRect.height;
 - }
 - else {
 - amount = visRect.width;
 - }
 - }
 - else {
 - amount = 10;
 - }
 - }
 - if (orientation == SwingConstants.VERTICAL) {
 - visRect.y += (amount * direction);
 - if ((visRect.y + visRect.height) > vSize.height) {
 - visRect.y = Math.max(0, vSize.height - visRect.height);
 - }
 - else if (visRect.y < 0) {
 - visRect.y = 0;
 - }
 - }
 - else {
 - visRect.x += (amount * direction);
 - if ((visRect.x + visRect.width) > vSize.width) {
 - visRect.x = Math.max(0, vSize.width - visRect.width);
 - }
 - else if (visRect.x < 0) {
 - visRect.x = 0;
 - }
 - }
 - vp.setViewPosition(visRect.getLocation());
 - }
 - }
 - }
 - /**
 - * Action to scroll to x,y location of 0,0.
 - */
 - private static class ScrollHomeAction extends AbstractAction {
 - protected ScrollHomeAction(String name) {
 - super(name);
 - }
 - public void actionPerformed(ActionEvent e) {
 - JScrollPane scrollpane = (JScrollPane)e.getSource();
 - JViewport vp = scrollpane.getViewport();
 - Component view;
 - if (vp != null && (view = vp.getView()) != null) {
 - vp.setViewPosition(new Point(0, 0));
 - }
 - }
 - }
 - /**
 - * Action to scroll to last visible location.
 - */
 - private static class ScrollEndAction extends AbstractAction {
 - protected ScrollEndAction(String name) {
 - super(name);
 - }
 - public void actionPerformed(ActionEvent e) {
 - JScrollPane scrollpane = (JScrollPane)e.getSource();
 - JViewport vp = scrollpane.getViewport();
 - Component view;
 - if (vp != null && (view = vp.getView()) != null) {
 - Rectangle visRect = vp.getViewRect();
 - Rectangle bounds = view.getBounds();
 - vp.setViewPosition(new Point(bounds.width - visRect.width,
 - bounds.height - visRect.height));
 - }
 - }
 - }
 - }