home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-03-20 | 17.3 KB | 576 lines |
- /*
- * @(#)JScrollPane.java 1.36 98/02/05
- *
- * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
- *
- * This software is the confidential and proprietary information of Sun
- * Microsystems, Inc. ("Confidential Information"). You shall not
- * disclose such Confidential Information and shall use it only in
- * accordance with the terms of the license agreement you entered into
- * with Sun.
- *
- * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
- * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
- * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
- * THIS SOFTWARE OR ITS DERIVATIVES.
- *
- */
-
- package java.awt.swing;
-
- import java.awt.swing.plaf.*;
- import java.awt.swing.border.*;
- import java.awt.accessibility.*;
-
- import java.awt.Component;
- import java.awt.Graphics;
- import java.awt.Rectangle;
- import java.awt.Color;
-
- import java.awt.swing.event.ChangeListener;
- import java.awt.swing.event.ChangeEvent;
-
- /**
- * A specialized container that manages a viewport, optional
- * vertical and horizontal scrollbars, and optional row and
- * column heading viewports.
- * <p>
- * Warning: serialized objects of this class will not be compatible with
- * future swing releases. The current serialization support is appropriate
- * for short term storage or RMI between Swing1.0 applications. It will
- * not be possible to load serialized Swing1.0 objects with future releases
- * of Swing. The JDK1.2 release of Swing will be the compatibility
- * baseline for the serialized form of Swing objects.
- *
- * @see ScrollBar
- * @beaninfo
- * attribute: isContainer false
- * description: A component that scrolls an inner viewport.
- */
- public class JScrollPane extends JComponent implements ScrollPaneConstants, Accessible
- {
- protected final static String[] cornerKeywords = {
- LOWER_LEFT_CORNER,
- LOWER_RIGHT_CORNER,
- UPPER_LEFT_CORNER,
- UPPER_RIGHT_CORNER
- };
-
- private Border viewportBorder;
-
-
- public JScrollPane(Component view, int vsbPolicy, int hsbPolicy) {
-
- /* The set methods that follow all delegate to the ScrollPaneUI
- * object, so we initialize that first.
- */
- updateUI();
-
- setViewport(createViewport());
- setViewportView(view);
- setVerticalScrollBarPolicy(vsbPolicy);
- setHorizontalScrollBarPolicy(hsbPolicy);
- }
-
-
- public JScrollPane(Component view) {
- this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
- }
-
- public JScrollPane(int vsbPolicy, int hsbPolicy) {
- this(null, vsbPolicy, hsbPolicy);
- }
-
- public JScrollPane() {
- this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
- }
-
-
- public ScrollPaneUI getUI() {
- return (ScrollPaneUI)ui;
- }
-
- public void setUI(ScrollPaneUI ui) {
- super.setUI(ui);
- }
-
-
- public void updateUI()
- {
- // PENDING(hmuller) this mess should go away; bound properties.
-
- /* The following properties are managed by the UI object. Since the'll
- * disappear when we replace the UI object we cache them here. Note
- * that one might set the UI to null and then later set it to a valid
- * UI object, so we have to stash the property values until the UI
- * is set to a non-null value.
- */
-
- if (ui != null) {
- JViewport viewport = getViewport();
- JViewport rowHeader = getRowHeader();
- JViewport columnHeader = getColumnHeader();
-
- if (viewport != null) putClientProperty(VIEWPORT, viewport);
- if (rowHeader != null) putClientProperty(ROW_HEADER, rowHeader);
- if (columnHeader != null) putClientProperty(COLUMN_HEADER, columnHeader);
-
- Integer vsbPolicy = new Integer(getVerticalScrollBarPolicy());
- Integer hsbPolicy = new Integer(getHorizontalScrollBarPolicy());
- putClientProperty(VERTICAL_SCROLLBAR_POLICY, vsbPolicy);
- putClientProperty(HORIZONTAL_SCROLLBAR_POLICY, hsbPolicy);
-
- for(int i = 0; i < cornerKeywords.length; i++) {
- Component corner = getCorner(cornerKeywords[i]);
- if (corner != null) putClientProperty(cornerKeywords[i], corner);
- }
- }
-
- /* Reset the ScrollPaneUI property.
- */
-
- setUI((ScrollPaneUI)UIManager.getUI(this));
-
- /* Restored the non-null cached values for the ScrollPaneUI
- * properties.
- */
-
- if (ui != null) {
- JViewport viewport = (JViewport)getClientProperty(VIEWPORT);
- JViewport rowHeader = (JViewport)getClientProperty(ROW_HEADER);
- JViewport columnHeader = (JViewport)getClientProperty(COLUMN_HEADER);
- Integer vsbPolicy = (Integer)getClientProperty(VERTICAL_SCROLLBAR_POLICY);
- Integer hsbPolicy = (Integer)getClientProperty(HORIZONTAL_SCROLLBAR_POLICY);
-
- if (vsbPolicy != null) { setVerticalScrollBarPolicy(vsbPolicy.intValue()); }
- if (hsbPolicy != null) { setHorizontalScrollBarPolicy(hsbPolicy.intValue()); }
- if (viewport != null) { setViewport(viewport); }
- if (rowHeader != null) { setRowHeader(rowHeader); }
- if (columnHeader != null) { setColumnHeader(columnHeader); }
-
- for(int i = 0; i < cornerKeywords.length; i++) {
- Component corner = (Component)getClientProperty(cornerKeywords[i]);
- if (corner != null) {
- setCorner(cornerKeywords[i], corner);
- } else {
- // PENDING(klobad) verify with Hans for this solution
- setCorner(cornerKeywords[i], new JPanel() {
- public void paint(Graphics g) {
- Color controlColor = UIManager.getColor("control");
- g.setColor(controlColor);
- g.fillRect(0, 0, _bounds.width, _bounds.height);
- }
- public boolean isOpaque() { return true; }
- });
-
- }
- }
- }
- }
-
-
- /**
- * @return "ScrollPaneUI"
- * @see JComponent#getUIClassID
- * @see UIDefaults#getUI
- */
- public String getUIClassID() {
- return "ScrollPaneUI";
- }
-
-
- public int getVerticalScrollBarPolicy() {
- return getUI().getVerticalScrollBarPolicy();
- }
-
- /*
- * Determines how the vertical scrollbar apears in the scrollpane.
- *
- * @see #getVerticalScrollBarPolicy
- * @beaninfo
- * preferred: true
- * description: The scrollpane scrollbar policy
- * enum: VERTICAL_SCROLLBAR_AS_NEEDED JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
- * VERTICAL_SCROLLBAR_NEVER JScrollPane.VERTICAL_SCROLLBAR_NEVER
- * VERTICAL_SCROLLBAR_ALWAYS JScrollPane.VERTICAL_SCROLLBAR_ALWAYS
- */
- public void setVerticalScrollBarPolicy(int x) {
- if (x != getVerticalScrollBarPolicy()) {
- getUI().setVerticalScrollBarPolicy(x);
- invalidate();
- }
- }
-
- public int getHorizontalScrollBarPolicy() {
- return getUI().getHorizontalScrollBarPolicy();
- }
-
- /*
- * Determines how the horizontal scrollbar apears in the scrollpane.
- *
- * @see #getHorizontalScrollBarPolicy
- * @beaninfo
- * preferred: true
- * description: The scrollpane scrollbar policy
- * enum: HORIZONTAL_SCROLLBAR_AS_NEEDED JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
- * HORIZONTAL_SCROLLBAR_NEVER JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
- * HORIZONTAL_SCROLLBAR_ALWAYS JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
- */
- public void setHorizontalScrollBarPolicy(int x) {
- if (x != getHorizontalScrollBarPolicy()) {
- getUI().setHorizontalScrollBarPolicy(x);
- invalidate();
- }
- }
-
-
- /**
- * @return the value of the viewportBorder property.
- * @see #setViewportBorder
- */
- public Border getViewportBorder() {
- return viewportBorder;
- }
-
-
- /**
- * Add a border around the viewport. Note that the border isn't
- * set on the viewport directly, JViewport doesn't support the
- * JComponent border property. Similarly setting the JScrollPanes
- * viewport doesn't effect the viewportBorder property.
- * <p>
- * The default value of this property is computed by the look
- * and feel implementation.
- * <p>
- * This is a JavaBeans bound property.
- *
- * @see #getViewportBorder
- * @see #setViewport
- *
- * @beaninfo
- * preferred: true
- * bound: true
- * description: The border around the viewport.
- */
- public void setViewportBorder(Border viewportBorder) {
- Border oldValue = this.viewportBorder;
- this.viewportBorder = viewportBorder;
- firePropertyChange("viewportBorder", oldValue, viewportBorder);
- }
-
-
- /**
- * By default JScrollPane creates scrollbars that are instances
- * of this class. Scrollbar overrides the getUnitIncrement
- * and getBlockIncrement methods so that, if the viewports view is
- * a Scrollable, the view is asked to compute these values.
- * <p>
- * Warning: serialized objects of this class will not be compatible with
- * future swing releases. The current serialization support is appropriate
- * for short term storage or RMI between Swing1.0 applications. It will
- * not be possible to load serialized Swing1.0 objects with future releases
- * of Swing. The JDK1.2 release of Swing will be the compatibility
- * baseline for the serialized form of Swing objects.
- *
- * @see Scrollable
- * @see #createVerticalScrollBar
- * @see #createHorizontalScrollBar
- */
- protected class ScrollBar extends JScrollBar
- {
- public ScrollBar(int orientation) {
- super(orientation);
- }
-
- /**
- * If the viewports view is a Scrollable then ask the view
- * to compute the unit increment. Otherwise return
- * super.getUnitIncrement().
- *
- * @see Scrollable#getScrollableUnitIncrement
- */
- public int getUnitIncrement(int direction) {
- JViewport vp = getViewport();
- if ((vp != null) && (vp.getView() instanceof Scrollable)) {
- Scrollable view = (Scrollable)(vp.getView());
- Rectangle vr = vp.getViewRect();
- return view.getScrollableUnitIncrement(vr, getOrientation(), direction);
- }
- else {
- return super.getUnitIncrement(direction);
- }
- }
-
- /**
- * If the viewports view is a Scrollable then ask the
- * view to compute the block increment. Otherwise
- * the blockIncrement equals the viewports width
- * or height. If there's no viewport reuurn
- * super.getBlockIncrement().
- *
- * @see Scrollable#getScrollableBlockIncrement
- */
- public int getBlockIncrement(int direction) {
- JViewport vp = getViewport();
- if (vp == null) {
- return super.getBlockIncrement(direction);
- }
- else if (vp.getView() instanceof Scrollable) {
- Scrollable view = (Scrollable)(vp.getView());
- Rectangle vr = vp.getViewRect();
- return view.getScrollableBlockIncrement(vr, getOrientation(), direction);
- }
- else if (getOrientation() == VERTICAL) {
- return vp.getExtentSize().width;
- }
- else {
- return vp.getExtentSize().height;
- }
- }
- }
-
-
- /**
- * Used by ScrollPaneUI implementations to create the horizontal
- * scrollbar. Returns a JScrollPane.ScrollBar by default. Subclasses
- * may override this method to force ScrollPaneUI implementations to
- * use a JScrollBar subclass.
- *
- * @return The horizontal JScrollBar
- * @see ScrollBar
- */
- public JScrollBar createHorizontalScrollBar() {
- return new ScrollBar(JScrollBar.HORIZONTAL);
- }
-
- /**
- * Used by ScrollPaneUI implementations to create the vertical
- * scrollbar. Returns a JScrollPane.ScrollBar by default. Subclasses
- * may override this method to force ScrollPaneUI implementations to
- * use a JScrollBar subclass.
- *
- * @return The vertical JScrollBar
- * @see ScrollBar
- */
- public JScrollBar createVerticalScrollBar() {
- return new ScrollBar(JScrollBar.VERTICAL);
- }
-
-
- public JScrollBar getHorizontalScrollBar() {
- return getUI().getHorizontalScrollBar();
- }
-
- public JScrollBar getVerticalScrollBar() {
- return getUI().getVerticalScrollBar();
- }
-
- /**
- * Returns 'new JViewport()' by default. Used to create the
- * viewport (as needed) in setViewportView(), setRowHeaderView(),
- * and setColumnHeaderView(). Subclasses my override this method
- * to return a subclass of JViewport.
- */
-
- protected JViewport createViewport() {
- return new JViewport();
- }
-
- public JViewport getViewport() {
- return getUI().getViewport();
- }
-
- public void setViewport(JViewport x) {
- if (x != getViewport()) {
- getUI().setViewport(x);
- invalidate();
- if (accessibleContext != null) {
- ((AccessibleJScrollPane)accessibleContext).resetViewPort();
- }
- }
- }
-
- /**
- * Creates a viewport if neccessary and then sets its view.
- */
- public void setViewportView(Component view) {
- if (getViewport() == null) {
- setViewport(createViewport());
- }
- getViewport().setView(view);
- }
-
-
- public JViewport getRowHeader() {
- return getUI().getRowHeader();
- }
-
- /* Sets a header viewport
- *
- * @beaninfo
- * preferred: true
- * description: The header viewport.
- */
- public void setRowHeader(JViewport x) {
- if (x != getRowHeader()) {
- getUI().setRowHeader(x);
- invalidate();
- }
- }
-
- /**
- * Creates a RowHeader viewport if neccessary and then sets
- * its view.
- */
- public void setRowHeaderView(Component view) {
- if (getRowHeader() == null) {
- setRowHeader(createViewport());
- }
- getRowHeader().setView(view);
- }
-
-
- public JViewport getColumnHeader() {
- return getUI().getColumnHeader();
- }
-
- /* Sets a column viewport
- *
- * @beaninfo
- * preferred: true
- * description: The column viewport.
- */
- public void setColumnHeader(JViewport x) {
- if (x != getColumnHeader()) {
- getUI().setColumnHeader(x);
- invalidate();
- }
- }
-
- /**
- * Creates a ColumnHeader viewport if neccessary and then sets
- * its view.
- */
- public void setColumnHeaderView(Component view) {
- if (getColumnHeader() == null) {
- setColumnHeader(createViewport());
- }
- getColumnHeader().setView(view);
- }
-
-
- public Component getCorner(String key) {
- return getUI().getCorner(key);
- }
-
- public void setCorner(String key, Component x) {
- if (x != getCorner(key)) {
- getUI().setCorner(key, x);
- invalidate();
- }
- }
-
-
- public boolean isOpaque() {
- JViewport viewport;
- Component view;
- if( (viewport = getViewport()) != null &&
- ((view = viewport.getView()) != null) &&
- ((view instanceof JComponent) && ((JComponent)view).isOpaque())) {
- if(((JComponent)view).getWidth() >= viewport.getWidth() &&
- ((JComponent)view).getHeight() >= viewport.getHeight())
- return true;
- }
- return false;
- }
-
-
- /**
- * Calls to revalidate() any descendant of this JScrollPane, e.g.
- * the viewports view, will cause a request to be queued that
- * will validate this JScrollPane and all its descendants.
- *
- * @return true
- * @see revalidate
- * @see java.awt.Component#invalidate
- * @see java.awt.Container#validate
- */
- public boolean isValidateRoot() {
- return true;
- }
-
-
- /////////////////
- // Accessibility support
- ////////////////
-
- /**
- * Get the AccessibleContext associated with this JComponent
- *
- * @return the AccessibleContext of this JComponent
- */
- public AccessibleContext getAccessibleContext() {
- if (accessibleContext == null) {
- accessibleContext = new AccessibleJScrollPane();
- }
- return accessibleContext;
- }
-
- /**
- * The class used to obtain the accessible role for this object.
- * <p>
- * Warning: serialized objects of this class will not be compatible with
- * future swing releases. The current serialization support is appropriate
- * for short term storage or RMI between Swing1.0 applications. It will
- * not be possible to load serialized Swing1.0 objects with future releases
- * of Swing. The JDK1.2 release of Swing will be the compatibility
- * baseline for the serialized form of Swing objects.
- */
- protected class AccessibleJScrollPane extends AccessibleJComponent
- implements ChangeListener {
-
- protected JViewport viewPort = null;
-
- public void resetViewPort() {
- viewPort.removeChangeListener(this);
- viewPort = JScrollPane.this.getViewport();
- viewPort.addChangeListener(this);
- }
-
- /**
- * Constructor to set up listener on viewport
- */
- public AccessibleJScrollPane() {
- super();
- if (viewPort == null) {
- viewPort = JScrollPane.this.getViewport();
- }
- viewPort.addChangeListener(this);
- }
-
- /**
- * Get the role of this object.
- *
- * @return an instance of AccessibleRole describing the role of the
- * object
- * @see AccessibleRole
- */
- public AccessibleRole getAccessibleRole() {
- return AccessibleRole.SCROLL_PANE;
- }
-
- /**
- * Supports the change listener interface and fires property change
- */
- public void stateChanged(ChangeEvent e) {
- AccessibleContext ac = ((Accessible)JScrollPane.this).getAccessibleContext();
- if (ac != null) {
- ac.firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, new Boolean(false), new Boolean(true));
- }
- }
- }
- }
-
-