home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / awt / swing / JScrollPane.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  17.3 KB  |  576 lines

  1. /*
  2.  * @(#)JScrollPane.java    1.36 98/02/05
  3.  *
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  *
  19.  */
  20.  
  21. package java.awt.swing;
  22.  
  23. import java.awt.swing.plaf.*;
  24. import java.awt.swing.border.*;
  25. import java.awt.accessibility.*;
  26.  
  27. import java.awt.Component;
  28. import java.awt.Graphics;
  29. import java.awt.Rectangle;
  30. import java.awt.Color;
  31.  
  32. import java.awt.swing.event.ChangeListener;
  33. import java.awt.swing.event.ChangeEvent;
  34.  
  35. /**
  36.  * A specialized container that manages a viewport, optional
  37.  * vertical and horizontal scrollbars, and optional row and
  38.  * column heading viewports.
  39.  * <p>
  40.  * Warning: serialized objects of this class will not be compatible with
  41.  * future swing releases.  The current serialization support is appropriate
  42.  * for short term storage or RMI between Swing1.0 applications.  It will
  43.  * not be possible to load serialized Swing1.0 objects with future releases
  44.  * of Swing.  The JDK1.2 release of Swing will be the compatibility
  45.  * baseline for the serialized form of Swing objects.
  46.  *
  47.  * @see ScrollBar
  48.  * @beaninfo
  49.  *      attribute: isContainer false
  50.  *    description: A component that scrolls an inner viewport.
  51.  */
  52. public class JScrollPane extends JComponent implements ScrollPaneConstants, Accessible
  53. {
  54.     protected final static String[] cornerKeywords = {
  55.     LOWER_LEFT_CORNER,
  56.     LOWER_RIGHT_CORNER,
  57.     UPPER_LEFT_CORNER,
  58.     UPPER_RIGHT_CORNER
  59.     };
  60.  
  61.     private Border viewportBorder;
  62.  
  63.  
  64.     public JScrollPane(Component view, int vsbPolicy, int hsbPolicy) {
  65.  
  66.     /* The set methods that follow all delegate to the ScrollPaneUI
  67.      * object, so we initialize that first.
  68.      */
  69.     updateUI();
  70.  
  71.     setViewport(createViewport());
  72.     setViewportView(view);
  73.     setVerticalScrollBarPolicy(vsbPolicy);
  74.     setHorizontalScrollBarPolicy(hsbPolicy);
  75.     }
  76.  
  77.  
  78.     public JScrollPane(Component view) {
  79.     this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
  80.     }
  81.  
  82.     public JScrollPane(int vsbPolicy, int hsbPolicy) {
  83.     this(null, vsbPolicy, hsbPolicy);
  84.     }
  85.  
  86.     public JScrollPane() {
  87.     this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
  88.     }
  89.  
  90.  
  91.     public ScrollPaneUI getUI() {
  92.     return (ScrollPaneUI)ui;
  93.     }
  94.  
  95.     public void setUI(ScrollPaneUI ui) {
  96.     super.setUI(ui);
  97.     }
  98.  
  99.  
  100.     public void updateUI()
  101.     {
  102.     // PENDING(hmuller) this mess should go away; bound properties.
  103.  
  104.     /* The following properties are managed by the UI object.  Since the'll
  105.      * disappear when we replace the UI object we cache them here.  Note
  106.      * that one might set the UI to null and then later set it to a valid
  107.      * UI object, so we have to stash the property values until the UI
  108.      * is set to a non-null value.
  109.      */
  110.  
  111.     if (ui != null) {
  112.         JViewport viewport = getViewport();
  113.         JViewport rowHeader = getRowHeader();
  114.         JViewport columnHeader = getColumnHeader();
  115.  
  116.         if (viewport != null) putClientProperty(VIEWPORT, viewport);
  117.         if (rowHeader != null) putClientProperty(ROW_HEADER, rowHeader);
  118.         if (columnHeader != null) putClientProperty(COLUMN_HEADER, columnHeader);
  119.  
  120.         Integer vsbPolicy = new Integer(getVerticalScrollBarPolicy());
  121.         Integer hsbPolicy = new Integer(getHorizontalScrollBarPolicy());
  122.         putClientProperty(VERTICAL_SCROLLBAR_POLICY, vsbPolicy);
  123.         putClientProperty(HORIZONTAL_SCROLLBAR_POLICY, hsbPolicy);
  124.  
  125.         for(int i = 0; i < cornerKeywords.length; i++) {
  126.         Component corner = getCorner(cornerKeywords[i]);
  127.         if (corner != null) putClientProperty(cornerKeywords[i], corner);
  128.         }
  129.     }
  130.  
  131.     /* Reset the ScrollPaneUI property.
  132.      */
  133.  
  134.     setUI((ScrollPaneUI)UIManager.getUI(this));
  135.  
  136.     /* Restored the non-null cached values for the ScrollPaneUI
  137.      * properties.
  138.      */
  139.  
  140.     if (ui != null) {
  141.         JViewport viewport = (JViewport)getClientProperty(VIEWPORT);
  142.         JViewport rowHeader = (JViewport)getClientProperty(ROW_HEADER);
  143.         JViewport columnHeader = (JViewport)getClientProperty(COLUMN_HEADER);
  144.         Integer vsbPolicy = (Integer)getClientProperty(VERTICAL_SCROLLBAR_POLICY);
  145.         Integer hsbPolicy = (Integer)getClientProperty(HORIZONTAL_SCROLLBAR_POLICY);
  146.  
  147.         if (vsbPolicy != null) { setVerticalScrollBarPolicy(vsbPolicy.intValue()); }
  148.         if (hsbPolicy != null) { setHorizontalScrollBarPolicy(hsbPolicy.intValue()); }
  149.         if (viewport != null) { setViewport(viewport); }
  150.         if (rowHeader != null) { setRowHeader(rowHeader); }
  151.         if (columnHeader != null) { setColumnHeader(columnHeader); }
  152.  
  153.         for(int i = 0; i < cornerKeywords.length; i++) {
  154.         Component corner = (Component)getClientProperty(cornerKeywords[i]);
  155.         if (corner != null) {
  156.             setCorner(cornerKeywords[i], corner);
  157.         } else {
  158.             // PENDING(klobad) verify with Hans for this solution
  159.             setCorner(cornerKeywords[i], new JPanel() {
  160.             public void paint(Graphics g) {
  161.                 Color controlColor = UIManager.getColor("control");
  162.                 g.setColor(controlColor);
  163.                 g.fillRect(0, 0, _bounds.width, _bounds.height);
  164.             }
  165.             public boolean isOpaque() { return true; }
  166.         });
  167.  
  168.         }
  169.         }
  170.     }
  171.     }
  172.  
  173.  
  174.     /**
  175.      * @return "ScrollPaneUI"
  176.      * @see JComponent#getUIClassID
  177.      * @see UIDefaults#getUI
  178.      */
  179.     public String getUIClassID() {
  180.     return "ScrollPaneUI";
  181.     }
  182.  
  183.  
  184.     public int getVerticalScrollBarPolicy() {
  185.     return getUI().getVerticalScrollBarPolicy();
  186.     }
  187.  
  188.     /*
  189.      * Determines how the vertical scrollbar apears in the scrollpane.
  190.      *
  191.      * @see #getVerticalScrollBarPolicy
  192.      * @beaninfo
  193.      *   preferred: true
  194.      * description: The scrollpane scrollbar policy
  195.      *        enum: VERTICAL_SCROLLBAR_AS_NEEDED JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
  196.      *              VERTICAL_SCROLLBAR_NEVER JScrollPane.VERTICAL_SCROLLBAR_NEVER
  197.      *              VERTICAL_SCROLLBAR_ALWAYS JScrollPane.VERTICAL_SCROLLBAR_ALWAYS
  198.      */
  199.     public void setVerticalScrollBarPolicy(int x) {
  200.     if (x != getVerticalScrollBarPolicy()) {
  201.         getUI().setVerticalScrollBarPolicy(x);
  202.         invalidate();
  203.     }
  204.     }
  205.  
  206.     public int getHorizontalScrollBarPolicy() {
  207.     return getUI().getHorizontalScrollBarPolicy();
  208.     }
  209.  
  210.     /*
  211.      * Determines how the horizontal scrollbar apears in the scrollpane.
  212.      *
  213.      * @see #getHorizontalScrollBarPolicy
  214.      * @beaninfo
  215.      *   preferred: true
  216.      * description: The scrollpane scrollbar policy
  217.      *        enum: HORIZONTAL_SCROLLBAR_AS_NEEDED JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
  218.      *              HORIZONTAL_SCROLLBAR_NEVER JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
  219.      *              HORIZONTAL_SCROLLBAR_ALWAYS JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
  220.      */
  221.     public void setHorizontalScrollBarPolicy(int x) {
  222.     if (x != getHorizontalScrollBarPolicy()) {
  223.         getUI().setHorizontalScrollBarPolicy(x);
  224.         invalidate();
  225.     }
  226.     }
  227.  
  228.  
  229.     /**
  230.      * @return the value of the viewportBorder property.
  231.      * @see #setViewportBorder
  232.      */
  233.     public Border getViewportBorder() {
  234.     return viewportBorder;
  235.     }
  236.  
  237.  
  238.     /**
  239.      * Add a border around the viewport.  Note that the border isn't
  240.      * set on the viewport directly, JViewport doesn't support the
  241.      * JComponent border property.  Similarly setting the JScrollPanes
  242.      * viewport doesn't effect the viewportBorder property.
  243.      * <p>
  244.      * The default value of this property is computed by the look
  245.      * and feel implementation.
  246.      * <p>
  247.      * This is a JavaBeans bound property.
  248.      *
  249.      * @see #getViewportBorder
  250.      * @see #setViewport
  251.      *
  252.      * @beaninfo
  253.      *   preferred: true
  254.      *       bound: true
  255.      * description: The border around the viewport.
  256.      */
  257.     public void setViewportBorder(Border viewportBorder) {
  258.     Border oldValue = this.viewportBorder;
  259.     this.viewportBorder = viewportBorder;
  260.     firePropertyChange("viewportBorder", oldValue, viewportBorder);
  261.     }
  262.  
  263.  
  264.     /**
  265.      * By default JScrollPane creates scrollbars that are instances
  266.      * of this class.  Scrollbar overrides the getUnitIncrement
  267.      * and getBlockIncrement methods so that, if the viewports view is 
  268.      * a Scrollable, the view is asked to compute these values.
  269.      * <p>
  270.      * Warning: serialized objects of this class will not be compatible with
  271.      * future swing releases.  The current serialization support is appropriate
  272.      * for short term storage or RMI between Swing1.0 applications.  It will
  273.      * not be possible to load serialized Swing1.0 objects with future releases
  274.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  275.      * baseline for the serialized form of Swing objects.
  276.      *
  277.      * @see Scrollable
  278.      * @see #createVerticalScrollBar
  279.      * @see #createHorizontalScrollBar
  280.      */
  281.     protected class ScrollBar extends JScrollBar
  282.     {
  283.     public ScrollBar(int orientation) {
  284.         super(orientation);
  285.     }
  286.  
  287.     /**
  288.      * If the viewports view is a Scrollable then ask the view
  289.      * to compute the unit increment.  Otherwise return
  290.      * super.getUnitIncrement().
  291.      * 
  292.      * @see Scrollable#getScrollableUnitIncrement
  293.      */
  294.     public int getUnitIncrement(int direction) {
  295.         JViewport vp = getViewport();
  296.         if ((vp != null) && (vp.getView() instanceof Scrollable)) {
  297.         Scrollable view = (Scrollable)(vp.getView());
  298.         Rectangle vr = vp.getViewRect();
  299.         return view.getScrollableUnitIncrement(vr, getOrientation(), direction);
  300.         }
  301.         else {
  302.         return super.getUnitIncrement(direction);
  303.         }
  304.     }
  305.  
  306.     /**
  307.      * If the viewports view is a Scrollable then ask the
  308.      * view to compute the block increment.  Otherwise
  309.      * the blockIncrement equals the viewports width
  310.      * or height.  If there's no viewport reuurn 
  311.      * super.getBlockIncrement().
  312.      * 
  313.      * @see Scrollable#getScrollableBlockIncrement
  314.      */
  315.     public int getBlockIncrement(int direction) {
  316.         JViewport vp = getViewport();
  317.         if (vp == null) {
  318.         return super.getBlockIncrement(direction);
  319.         }
  320.         else if (vp.getView() instanceof Scrollable) {
  321.         Scrollable view = (Scrollable)(vp.getView());
  322.         Rectangle vr = vp.getViewRect();
  323.         return view.getScrollableBlockIncrement(vr, getOrientation(), direction);
  324.         }
  325.         else if (getOrientation() == VERTICAL) {
  326.         return vp.getExtentSize().width;
  327.         }
  328.         else {
  329.         return vp.getExtentSize().height;
  330.         }
  331.     }
  332.     }
  333.  
  334.  
  335.     /**
  336.      * Used by ScrollPaneUI implementations to create the horizontal
  337.      * scrollbar.  Returns a JScrollPane.ScrollBar by default.  Subclasses
  338.      * may override this method to force ScrollPaneUI implementations to
  339.      * use a JScrollBar subclass.
  340.      *
  341.      * @return The horizontal JScrollBar
  342.      * @see ScrollBar
  343.      */
  344.     public JScrollBar createHorizontalScrollBar() {
  345.     return new ScrollBar(JScrollBar.HORIZONTAL);
  346.     }
  347.  
  348.     /**
  349.      * Used by ScrollPaneUI implementations to create the vertical
  350.      * scrollbar.  Returns a JScrollPane.ScrollBar by default.  Subclasses
  351.      * may override this method to force ScrollPaneUI implementations to
  352.      * use a JScrollBar subclass.
  353.      *
  354.      * @return The vertical JScrollBar
  355.      * @see ScrollBar
  356.      */
  357.     public JScrollBar createVerticalScrollBar() {
  358.     return new ScrollBar(JScrollBar.VERTICAL);
  359.     }
  360.  
  361.  
  362.     public JScrollBar getHorizontalScrollBar() {
  363.     return getUI().getHorizontalScrollBar();
  364.     }
  365.  
  366.     public JScrollBar getVerticalScrollBar() {
  367.     return getUI().getVerticalScrollBar();
  368.     }
  369.  
  370.     /**
  371.      * Returns 'new JViewport()' by default.  Used to create the
  372.      * viewport (as needed) in setViewportView(), setRowHeaderView(),
  373.      * and setColumnHeaderView().  Subclasses my override this method
  374.      * to return a subclass of JViewport.
  375.      */
  376.  
  377.     protected JViewport createViewport() {
  378.     return new JViewport();
  379.     }
  380.  
  381.     public JViewport getViewport() {
  382.     return getUI().getViewport();
  383.     }
  384.  
  385.     public void setViewport(JViewport x) {
  386.     if (x != getViewport()) {
  387.         getUI().setViewport(x);
  388.         invalidate();
  389.         if (accessibleContext != null) {
  390.         ((AccessibleJScrollPane)accessibleContext).resetViewPort();
  391.         }
  392.     }
  393.     }
  394.  
  395.     /**
  396.      * Creates a viewport if neccessary and then sets its view.
  397.      */
  398.     public void setViewportView(Component view) {
  399.     if (getViewport() == null) {
  400.         setViewport(createViewport());
  401.     }
  402.     getViewport().setView(view);
  403.     }
  404.  
  405.  
  406.     public JViewport getRowHeader() {
  407.     return getUI().getRowHeader();
  408.     }
  409.  
  410.     /* Sets a header viewport
  411.      *
  412.      * @beaninfo
  413.      *   preferred: true
  414.      * description: The header viewport.
  415.      */
  416.     public void setRowHeader(JViewport x) {
  417.     if (x != getRowHeader()) {
  418.         getUI().setRowHeader(x);
  419.         invalidate();
  420.     }
  421.     }
  422.  
  423.     /**
  424.      * Creates a RowHeader viewport if neccessary and then sets
  425.      * its view.
  426.      */
  427.     public void setRowHeaderView(Component view) {
  428.     if (getRowHeader() == null) {
  429.         setRowHeader(createViewport());
  430.     }
  431.     getRowHeader().setView(view);
  432.     }
  433.  
  434.  
  435.     public JViewport getColumnHeader() {
  436.     return getUI().getColumnHeader();
  437.     }
  438.  
  439.     /* Sets a column viewport
  440.      *
  441.      * @beaninfo
  442.      *   preferred: true
  443.      * description: The column viewport.
  444.      */
  445.     public void setColumnHeader(JViewport x) {
  446.     if (x != getColumnHeader()) {
  447.         getUI().setColumnHeader(x);
  448.         invalidate();
  449.     }
  450.     }
  451.  
  452.     /**
  453.      * Creates a ColumnHeader viewport if neccessary and then sets
  454.      * its view.
  455.      */
  456.     public void setColumnHeaderView(Component view) {
  457.     if (getColumnHeader() == null) {
  458.         setColumnHeader(createViewport());
  459.     }
  460.     getColumnHeader().setView(view);
  461.     }
  462.  
  463.  
  464.     public Component getCorner(String key) {
  465.     return getUI().getCorner(key);
  466.     }
  467.  
  468.     public void setCorner(String key, Component x) {
  469.     if (x != getCorner(key)) {
  470.         getUI().setCorner(key, x);
  471.         invalidate();
  472.     }
  473.     }
  474.  
  475.  
  476.     public boolean isOpaque() {
  477.     JViewport viewport;
  478.     Component view;
  479.         if( (viewport = getViewport()) != null    && 
  480.             ((view = viewport.getView()) != null) &&
  481.             ((view instanceof JComponent) && ((JComponent)view).isOpaque())) {
  482.             if(((JComponent)view).getWidth()  >= viewport.getWidth() && 
  483.                ((JComponent)view).getHeight() >= viewport.getHeight())
  484.                 return true;
  485.         }
  486.         return false;
  487.     }
  488.  
  489.  
  490.     /** 
  491.      * Calls to revalidate() any descendant of this JScrollPane, e.g. 
  492.      * the viewports view, will cause a request to be queued that
  493.      * will validate this JScrollPane and all its descendants.
  494.      * 
  495.      * @return true
  496.      * @see revalidate
  497.      * @see java.awt.Component#invalidate
  498.      * @see java.awt.Container#validate
  499.      */
  500.     public boolean isValidateRoot() {
  501.     return true;
  502.     }
  503.  
  504.  
  505. /////////////////
  506. // Accessibility support
  507. ////////////////
  508.  
  509.     /**
  510.      * Get the AccessibleContext associated with this JComponent
  511.      *
  512.      * @return the AccessibleContext of this JComponent
  513.      */
  514.     public AccessibleContext getAccessibleContext() {
  515.     if (accessibleContext == null) {
  516.         accessibleContext = new AccessibleJScrollPane();
  517.     }
  518.         return accessibleContext;
  519.     }
  520.  
  521.     /**
  522.      * The class used to obtain the accessible role for this object.
  523.      * <p>
  524.      * Warning: serialized objects of this class will not be compatible with
  525.      * future swing releases.  The current serialization support is appropriate
  526.      * for short term storage or RMI between Swing1.0 applications.  It will
  527.      * not be possible to load serialized Swing1.0 objects with future releases
  528.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  529.      * baseline for the serialized form of Swing objects.
  530.      */
  531.     protected class AccessibleJScrollPane extends AccessibleJComponent 
  532.     implements ChangeListener {
  533.  
  534.     protected JViewport viewPort = null;
  535.  
  536.     public void resetViewPort() {
  537.         viewPort.removeChangeListener(this);
  538.         viewPort = JScrollPane.this.getViewport();
  539.         viewPort.addChangeListener(this);
  540.     }
  541.  
  542.     /**
  543.      * Constructor to set up listener on viewport
  544.      */
  545.     public AccessibleJScrollPane() {
  546.         super();
  547.         if (viewPort == null) {
  548.            viewPort = JScrollPane.this.getViewport();
  549.         }
  550.         viewPort.addChangeListener(this);
  551.     }
  552.  
  553.     /**
  554.      * Get the role of this object.
  555.      *
  556.      * @return an instance of AccessibleRole describing the role of the 
  557.       * object
  558.      * @see AccessibleRole
  559.      */
  560.     public AccessibleRole getAccessibleRole() {
  561.         return AccessibleRole.SCROLL_PANE;
  562.     }
  563.  
  564.         /**
  565.          * Supports the change listener interface and fires property change
  566.          */
  567.         public void stateChanged(ChangeEvent e) {
  568.             AccessibleContext ac = ((Accessible)JScrollPane.this).getAccessibleContext();
  569.             if (ac != null) {
  570.                 ac.firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, new Boolean(false), new Boolean(true));
  571.             }
  572.         }
  573.     }
  574. }
  575.  
  576.