home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / awt / ScrollPane.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  22.8 KB  |  768 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)ScrollPane.java    1.67 98/08/19
  3.  *
  4.  * Copyright 1996-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. import java.awt.peer.ScrollPanePeer;
  17. import java.awt.event.*;
  18. import java.io.Serializable;
  19.  
  20.  
  21. /**
  22.  * A container class which implements automatic horizontal and/or
  23.  * vertical scrolling for a single child component.  The display
  24.  * policy for the scrollbars can be set to:
  25.  * <OL>
  26.  * <LI>as needed: scrollbars created and shown only when needed by scrollpane
  27.  * <LI>always: scrollbars created and always shown by the scrollpane
  28.  * <LI>never: scrollbars never created or shown by the scrollpane
  29.  * </OL>
  30.  * <P>
  31.  * The state of the horizontal and vertical scrollbars is represented
  32.  * by two objects (one for each dimension) which implement the
  33.  * Adjustable interface.  The API provides methods to access those
  34.  * objects such that the attributes on the Adjustable object (such as unitIncrement,
  35.  * value, etc.) can be manipulated.
  36.  * <P>
  37.  * Certain adjustable properties (minimum, maximum, blockIncrement,
  38.  * and visibleAmount) are set internally by the scrollpane in accordance
  39.  * with the geometry of the scrollpane and its child and these should
  40.  * not be set by programs using the scrollpane.
  41.  * <P>
  42.  * If the scrollbar display policy is defined as "never", then the
  43.  * scrollpane can still be programmatically scrolled using the
  44.  * setScrollPosition() method and the scrollpane will move and clip
  45.  * the child's contents appropriately.  This policy is useful if the
  46.  * program needs to create and manage its own adjustable controls.
  47.  * <P>
  48.  * The placement of the scrollbars is controlled by platform-specific
  49.  * properties set by the user outside of the program.
  50.  * <P>
  51.  * The initial size of this container is set to 100x100, but can
  52.  * be reset using setSize().
  53.  * <P>
  54.  * Insets are used to define any space used by scrollbars and any
  55.  * borders created by the scroll pane. getInsets() can be used
  56.  * to get the current value for the insets.  If the value of
  57.  * scrollbarsAlwaysVisible is false, then the value of the insets
  58.  * will change dynamically depending on whether the scrollbars are
  59.  * currently visible or not.
  60.  *
  61.  * @version     1.67 08/19/98
  62.  * @author      Tom Ball
  63.  * @author      Amy Fowler
  64.  * @author      Tim Prinzing
  65.  */
  66. public class ScrollPane extends Container {
  67.  
  68.  
  69.     /**
  70.      * Initialize JNI field and method IDs
  71.      */
  72.     private static native void initIDs();
  73.  
  74.     static {
  75.         /* ensure that the necessary native libraries are loaded */
  76.     Toolkit.loadLibraries();
  77.         initIDs();
  78.     }
  79.  
  80.     /**
  81.      * Specifies that horizontal/vertical scrollbar should be shown
  82.      * only when the size of the child exceeds the size of the scrollpane
  83.      * in the horizontal/vertical dimension.
  84.      */
  85.     public static final int SCROLLBARS_AS_NEEDED = 0;
  86.  
  87.     /**
  88.      * Specifies that horizontal/vertical scrollbars should always be
  89.      * shown regardless of the respective sizes of the scrollpane and child.
  90.      */
  91.     public static final int SCROLLBARS_ALWAYS = 1;
  92.  
  93.     /**
  94.      * Specifies that horizontal/vertical scrollbars should never be shown
  95.      * regardless of the respective sizes of the scrollpane and child.
  96.      */
  97.     public static final int SCROLLBARS_NEVER = 2;
  98.     /**
  99.      * There are 3 ways in which a scroll bar can be displayed.
  100.      * This integer will represent one of these 3 displays -
  101.      * (SCROLLBARS_ALWAYS, SCROLLBARS_AS_NEEDED, SCROLLBARS_NEVER)
  102.      *
  103.      * @serial
  104.      * @see getScrollbarDisplayPolicy()
  105.      */
  106.     private int scrollbarDisplayPolicy;
  107.     /**
  108.      * An adjustable Vertical Scrollbar.
  109.      * It is important to not that you must NOT call 3 Adjustable methods
  110.      * ie : setMinimum(), setMaximum(), setVisibleAmount().
  111.      *
  112.      * @serial
  113.      * @see getVAdjustable()
  114.      * @see java.awt.Adjustable
  115.      */
  116.     private ScrollPaneAdjustable vAdjustable;
  117.     /**
  118.      * An adjustable Horizontal Scrollbar.
  119.      * It is important to not that you must NOT call 3 Adjustable method 
  120.      * ie : setMinimum(), setMaximum(), setVisibleAmount().
  121.      *
  122.      * @serial
  123.      * @see getHAdjustable()
  124.      * @see java.awt.Adjustable
  125.      */
  126.     private ScrollPaneAdjustable hAdjustable;
  127.  
  128.     private static final String base = "scrollpane";
  129.     private static int nameCounter = 0;
  130.  
  131.     /*
  132.      * JDK 1.1 serialVersionUID
  133.      */
  134.      private static final long serialVersionUID = 7956609840827222915L;
  135.  
  136.     /**
  137.      * Create a new scrollpane container with a scrollbar display policy of
  138.      * "as needed".
  139.      */
  140.     public ScrollPane() {
  141.     this(SCROLLBARS_AS_NEEDED);
  142.     }
  143.  
  144.     /**
  145.      * Create a new scrollpane container.
  146.      * @param scrollbarDisplayPolicy policy for when scrollbars should be shown
  147.      */
  148.     public ScrollPane(int scrollbarDisplayPolicy) {
  149.     this.layoutMgr = null;
  150.     this.width = 100;
  151.     this.height = 100;
  152.     switch (scrollbarDisplayPolicy) {
  153.         case SCROLLBARS_NEVER:
  154.         case SCROLLBARS_AS_NEEDED:
  155.         case SCROLLBARS_ALWAYS:
  156.         this.scrollbarDisplayPolicy = scrollbarDisplayPolicy;
  157.         break;
  158.         default:
  159.         throw new IllegalArgumentException("illegal scrollbar display policy");
  160.     }
  161.  
  162.     vAdjustable = new ScrollPaneAdjustable(this, new PeerFixer(this),
  163.                            Adjustable.VERTICAL);
  164.     hAdjustable = new ScrollPaneAdjustable(this, new PeerFixer(this),
  165.                            Adjustable.HORIZONTAL);
  166.     }
  167.  
  168.     /**
  169.      * Construct a name for this component.  Called by getName() when the
  170.      * name is null.
  171.      */
  172.     String constructComponentName() {
  173.         synchronized (getClass()) {
  174.         return base + nameCounter++;
  175.     }
  176.     }
  177.  
  178.     /**
  179.      * Adds the specified component to this scroll pane container.
  180.      * If the scroll pane has an existing child component, that
  181.      * component is removed and the new one is added.
  182.      * @param comp the component to be added
  183.      * @param constraints  not applicable
  184.      * @param index position of child component (must be <= 0)
  185.      */
  186.     protected final void addImpl(Component comp, Object constraints, int index) {
  187.         synchronized (getTreeLock()) {
  188.         if (getComponentCount() > 0) {
  189.         remove(0);
  190.         }
  191.         if (index > 0) {
  192.         throw new IllegalArgumentException("position greater than 0");
  193.         }
  194.  
  195.         super.addImpl(comp, constraints, index);
  196.     }
  197.     }
  198.  
  199.     /**
  200.      * Returns the display policy for the scrollbars.
  201.      * @return the display policy for the scrollbars
  202.      */
  203.     public int getScrollbarDisplayPolicy() {
  204.         return scrollbarDisplayPolicy;
  205.     }
  206.  
  207.     /**
  208.      * Returns the current size of the scroll pane's view port.
  209.      * @return the size of the view port in pixels
  210.      */
  211.     public Dimension getViewportSize() {
  212.     Insets i = getInsets();
  213.     return new Dimension(width - i.right - i.left,
  214.                  height - i.top - i.bottom);
  215.     }
  216.  
  217.     /**
  218.      * Returns the height that would be occupied by a horizontal
  219.      * scrollbar, which is independent of whether it is currently
  220.      * displayed by the scroll pane or not.
  221.      * @return the height of a horizontal scrollbar in pixels
  222.      */
  223.     public int getHScrollbarHeight() {
  224.     int h = 0;
  225.     if (scrollbarDisplayPolicy != SCROLLBARS_NEVER) {
  226.         ScrollPanePeer peer = (ScrollPanePeer)this.peer;
  227.         if (peer != null) {
  228.         h = peer.getHScrollbarHeight();
  229.         }
  230.     }
  231.     return h;
  232.     }
  233.  
  234.     /**
  235.      * Returns the width that would be occupied by a vertical
  236.      * scrollbar, which is independent of whether it is currently
  237.      * displayed by the scroll pane or not.
  238.      * @return the width of a vertical scrollbar in pixels
  239.      */
  240.     public int getVScrollbarWidth() {
  241.     int w = 0;
  242.     if (scrollbarDisplayPolicy != SCROLLBARS_NEVER) {
  243.         ScrollPanePeer peer = (ScrollPanePeer)this.peer;
  244.         if (peer != null) {
  245.         w = peer.getVScrollbarWidth();
  246.         }
  247.     }
  248.     return w;
  249.     }
  250.  
  251.     /**
  252.      * Returns the Adjustable object which represents the state of
  253.      * the vertical scrollbar.
  254.      */
  255.     public Adjustable getVAdjustable() {
  256.         return vAdjustable;
  257.     }
  258.  
  259.     /**
  260.      * Returns the Adjustable object which represents the state of
  261.      * the horizontal scrollbar.
  262.      */
  263.     public Adjustable getHAdjustable() {
  264.         return hAdjustable;
  265.     }
  266.  
  267.     /**
  268.      * Scrolls to the specified position within the child component.
  269.      * A call to this method is only valid if the scroll pane contains
  270.      * a child.  Specifying a position outside of the legal scrolling bounds
  271.      * of the child will scroll to the closest legal position.
  272.      * Legal bounds are defined to be the rectangle:
  273.      * x = 0, y = 0, width = (child width - view port width),
  274.      * height = (child height - view port height).
  275.      * This is a convenience method which interfaces with the Adjustable
  276.      * objects which represent the state of the scrollbars.
  277.      * @param x the x position to scroll to
  278.      * @param y the y position to scroll to
  279.      */
  280.     public void setScrollPosition(int x, int y) {
  281.         synchronized (getTreeLock()) {
  282.         if (ncomponents <= 0) {
  283.         throw new NullPointerException("child is null");
  284.         }
  285.         hAdjustable.setValue(x);
  286.         vAdjustable.setValue(y);
  287.     }
  288.     }
  289.  
  290.    /**
  291.      * Scrolls to the specified position within the child component.
  292.      * A call to this method is only valid if the scroll pane contains
  293.      * a child and the specified position is within legal scrolling bounds
  294.      * of the child.  Specifying a position outside of the legal scrolling
  295.      * bounds of the child will scroll to the closest legal position.
  296.      * Legal bounds are defined to be the rectangle:
  297.      * x = 0, y = 0, width = (child width - view port width),
  298.      * height = (child height - view port height).
  299.      * This is a convenience method which interfaces with the Adjustable
  300.      * objects which represent the state of the scrollbars.
  301.      * @param p the Point representing the position to scroll to
  302.      */
  303.     public void setScrollPosition(Point p) {
  304.         setScrollPosition(p.x, p.y);
  305.     }
  306.  
  307.     /**
  308.      * Returns the current x,y position within the child which is displayed
  309.      * at the 0,0 location of the scrolled panel's view port.
  310.      * This is a convenience method which interfaces with the adjustable
  311.      * objects which represent the state of the scrollbars.
  312.      * @return the coordinate position for the current scroll position
  313.      */
  314.     public Point getScrollPosition() {
  315.     if (ncomponents <= 0) {
  316.         throw new NullPointerException("child is null");
  317.     }
  318.     return new Point(hAdjustable.getValue(), vAdjustable.getValue());
  319.     }
  320.  
  321.     /**
  322.      * Sets the layout manager for this container.  This method is
  323.      * overridden to prevent the layout mgr from being set.
  324.      * @param mgr the specified layout manager
  325.      */
  326.     public final void setLayout(LayoutManager mgr) {
  327.     throw new AWTError("ScrollPane controls layout");
  328.     }
  329.  
  330.     /**
  331.      * Lays out this container by resizing its child to its preferred size.
  332.      * If the new preferred size of the child causes the current scroll
  333.      * position to be invalid, the scroll position is set to the closest
  334.      * valid position.
  335.      *
  336.      * @see Component#validate
  337.      */
  338.     public void doLayout() {
  339.     layout();
  340.     }
  341.  
  342.     /**
  343.      * Determine the size to allocate the child component.
  344.      * If the viewport area is bigger than the childs
  345.      * preferred size then the child is allocated enough
  346.      * to fill the viewport, otherwise the child is given
  347.      * it's preferred size.
  348.      */
  349.     Dimension calculateChildSize() {
  350.     //
  351.     // calculate the view size, accounting for border but not scrollbars
  352.     // - don't use right/bottom insets since they vary depending
  353.     //   on whether or not scrollbars were displayed on last resize
  354.     //
  355.     Dimension    size = getSize();
  356.     Insets        insets = getInsets();
  357.     int         viewWidth = size.width - insets.left*2;
  358.     int         viewHeight = size.height - insets.top*2;
  359.  
  360.     //
  361.     // determine whether or not horz or vert scrollbars will be displayed
  362.     //
  363.     boolean vbarOn;
  364.     boolean hbarOn;
  365.     Component child = getComponent(0);
  366.     Dimension childSize = new Dimension(child.getPreferredSize());
  367.  
  368.     if (scrollbarDisplayPolicy == SCROLLBARS_AS_NEEDED) {
  369.         vbarOn = childSize.height > viewHeight;
  370.         hbarOn = childSize.width  > viewWidth;
  371.     } else if (scrollbarDisplayPolicy == SCROLLBARS_ALWAYS) {
  372.         vbarOn = hbarOn = true;
  373.     } else { // SCROLLBARS_NEVER
  374.         vbarOn = hbarOn = false;
  375.     }
  376.     
  377.     //
  378.     // adjust predicted view size to account for scrollbars
  379.     //
  380.     int vbarWidth = getVScrollbarWidth(); 
  381.     int hbarHeight = getHScrollbarHeight();
  382.     if (vbarOn) {
  383.         viewWidth -= vbarWidth;
  384.     }
  385.     if(hbarOn) {
  386.         viewHeight -= hbarHeight;
  387.     }
  388.  
  389.     //
  390.     // if child is smaller than view, size it up
  391.     //
  392.     if (childSize.width < viewWidth) {
  393.         childSize.width = viewWidth;
  394.     }
  395.     if (childSize.height < viewHeight) {
  396.         childSize.height = viewHeight;
  397.     }
  398.  
  399.     return childSize;
  400.     }
  401.  
  402.     /**
  403.      * @deprecated As of JDK version 1.1,
  404.      * replaced by <code>doLayout()</code>.
  405.      */
  406.     public void layout() {
  407.     if (ncomponents > 0) {
  408.         Component c = getComponent(0);
  409.         Point p = getScrollPosition();
  410.         Dimension cs = calculateChildSize();
  411.         Dimension vs = getViewportSize();
  412.         Insets i = getInsets();
  413.  
  414.         c.reshape(i.left - p.x, i.top - p.y, cs.width, cs.height);
  415.         ScrollPanePeer peer = (ScrollPanePeer)this.peer;
  416.         if (peer != null) {
  417.             peer.childResized(cs.width, cs.height);
  418.         }
  419.  
  420.         // update adjustables... the viewport size may have changed
  421.         // with the scrollbars coming or going so the viewport size
  422.         // is updated before the adjustables.
  423.         vs = getViewportSize();
  424.         hAdjustable.setSpan(0, cs.width, vs.width);
  425.         vAdjustable.setSpan(0, cs.height, vs.height);
  426.     }
  427.     }
  428.  
  429.     /**
  430.      * Prints the component in this scroll pane.
  431.      * @param g the specified Graphics window
  432.      * @see Component#print
  433.      * @see Component#printAll
  434.      */
  435.     public void printComponents(Graphics g) {
  436.     if (ncomponents > 0) {
  437.         Component c = component[0];
  438.         Point p = c.getLocation();
  439.         Dimension vs = getViewportSize();
  440.         Insets i = getInsets();
  441.  
  442.         Graphics cg = g.create();
  443.         try {
  444.             cg.clipRect(i.left, i.top, vs.width, vs.height);
  445.             cg.translate(p.x, p.y);
  446.         c.printAll(cg);
  447.         } finally {
  448.         cg.dispose();
  449.         }
  450.     }
  451.     }
  452.  
  453.     /**
  454.      * Creates the scroll pane's peer.
  455.      */
  456.     public void addNotify() {
  457.         synchronized (getTreeLock()) {
  458.  
  459.             int vAdjustableValue = 0;
  460.             int hAdjustableValue = 0;
  461.  
  462.             // Bug 4124460. Save the current adjustable values,
  463.             // so they can be restored after addnotify. Set the
  464.             // adjustibles to 0, to prevent crashes for possible
  465.             // negative values.
  466.             if (getComponentCount() > 0) {
  467.                 vAdjustableValue = vAdjustable.getValue();
  468.                 hAdjustableValue = hAdjustable.getValue();
  469.                 vAdjustable.setValue(0);
  470.                 hAdjustable.setValue(0);
  471.             }
  472.  
  473.         if (peer == null)
  474.             peer = getToolkit().createScrollPane(this);
  475.         super.addNotify();
  476.  
  477.             // Bug 4124460. Restore the adjustable values.
  478.             if (getComponentCount() > 0) {
  479.                 vAdjustable.setValue(vAdjustableValue);
  480.                 hAdjustable.setValue(hAdjustableValue);
  481.             }
  482.  
  483.         if (getComponentCount() > 0) {
  484.             Component comp = getComponent(0);
  485.         if (comp.peer instanceof java.awt.peer.LightweightPeer) {
  486.             // The scrollpane won't work with a windowless child... it assumes
  487.             // it is moving a child window around so the windowless child is
  488.             // wrapped with a window.
  489.             remove(0);
  490.             Panel child = new Panel();
  491.             child.setLayout(new BorderLayout());
  492.             child.add(comp);
  493.             add(child);
  494.         }
  495.         }
  496.     }
  497.     }
  498.  
  499.     public String paramString() {
  500.     String sdpStr;
  501.     switch (scrollbarDisplayPolicy) {
  502.         case SCROLLBARS_AS_NEEDED:
  503.         sdpStr = "as-needed";
  504.         break;
  505.         case SCROLLBARS_ALWAYS:
  506.         sdpStr = "always";
  507.         break;
  508.         case SCROLLBARS_NEVER:
  509.         sdpStr = "never";
  510.         break;
  511.         default:
  512.         sdpStr = "invalid display policy";
  513.     }
  514.     Point p = ncomponents > 0? getScrollPosition() : new Point(0,0);
  515.     Insets i = getInsets();
  516.     return super.paramString()+",ScrollPosition=("+p.x+","+p.y+")"+
  517.         ",Insets=("+i.top+","+i.left+","+i.bottom+","+i.right+")"+
  518.         ",ScrollbarDisplayPolicy="+sdpStr;
  519.     }
  520.  
  521.     class PeerFixer implements AdjustmentListener, java.io.Serializable {
  522.  
  523.     PeerFixer(ScrollPane scroller) {
  524.         this.scroller = scroller;
  525.     }
  526.  
  527.     /**
  528.      * Invoked when the value of the adjustable has changed.
  529.      */
  530.         public void adjustmentValueChanged(AdjustmentEvent e) {
  531.         Adjustable adj = e.getAdjustable();
  532.         int value = e.getValue();
  533.         ScrollPanePeer peer = (ScrollPanePeer) scroller.peer;
  534.         if (peer != null) {
  535.         peer.setValue(adj, value);
  536.         }
  537.  
  538.         Component c = scroller.getComponent(0);
  539.         switch(adj.getOrientation()) {
  540.         case Adjustable.VERTICAL:
  541.         c.move(c.getLocation().x, -(value));
  542.         break;
  543.         case Adjustable.HORIZONTAL:
  544.         c.move(-(value), c.getLocation().y);
  545.         break;
  546.         default:
  547.         throw new IllegalArgumentException("Illegal adjustable orientation");
  548.         }
  549.     }
  550.  
  551.         private ScrollPane scroller;
  552.     }
  553. }
  554.  
  555. /*
  556.  * In JDK 1.1.1, the pkg private class java.awt.PeerFixer was moved to 
  557.  * become an inner class of ScrollPane, which broke serialization 
  558.  * for ScrollPane objects using JDK 1.1.
  559.  * Instead of moving it back out here, which would break all JDK 1.1.x
  560.  * releases, we keep PeerFixer in both places. Because of the scoping rules,
  561.  * the PeerFixer that is used in ScrollPane will be the one that is the
  562.  * inner class. This pkg private PeerFixer class below will only be used
  563.  * if JDK1.2 is used to deserialize ScrollPane objects that were serialized
  564.  * using JDK1.1
  565.  */
  566. class PeerFixer implements AdjustmentListener, java.io.Serializable {
  567.  
  568.     PeerFixer(ScrollPane scroller) {
  569.     this.scroller = scroller;
  570.     }
  571.  
  572.     /**
  573.      * Invoked when the value of the adjustable has changed.
  574.      */   
  575.     public void adjustmentValueChanged(AdjustmentEvent e) {
  576.     Adjustable adj = e.getAdjustable();
  577.     int value = e.getValue();
  578.     ScrollPanePeer peer = (ScrollPanePeer) scroller.peer;
  579.     if (peer != null) {
  580.         peer.setValue(adj, value);
  581.     }
  582.  
  583.     Component c = scroller.getComponent(0);
  584.         switch(adj.getOrientation()) {
  585.     case Adjustable.VERTICAL:
  586.         c.move(c.getLocation().x, -(value));
  587.         break;
  588.     case Adjustable.HORIZONTAL:
  589.         c.move(-(value), c.getLocation().y);
  590.         break;
  591.     default:
  592.         throw new IllegalArgumentException("Illegal adjustable orientation");
  593.     }
  594.     }
  595.  
  596.     private ScrollPane scroller;
  597. }
  598.  
  599.  
  600.  
  601. class ScrollPaneAdjustable implements Adjustable, java.io.Serializable {
  602.  
  603.     private ScrollPane sp;
  604.     private int orientation;
  605.     private int minimum;
  606.     private int maximum;
  607.     private int visibleAmount;
  608.     private int unitIncrement = 1;
  609.     private int blockIncrement = 1;
  610.     private int value;
  611.     private AdjustmentListener adjustmentListener;
  612.  
  613.     private static final String SCROLLPANE_ONLY =
  614.         "Can be set by scrollpane only";
  615.  
  616.     /**
  617.      * Initialize JNI field and method ids
  618.      */
  619.     private static native void initIDs();
  620.  
  621.     static {
  622.         Toolkit.loadLibraries();
  623.         initIDs();
  624.     }
  625.  
  626.     /*
  627.      * JDK 1.1 serialVersionUID
  628.      */
  629.     private static final long serialVersionUID = -3359745691033257079L;
  630.  
  631.     public ScrollPaneAdjustable(ScrollPane sp, AdjustmentListener l, int orientation) {
  632.         this.sp = sp;
  633.         this.orientation = orientation;
  634.     addAdjustmentListener(l);
  635.     }
  636.  
  637.     /**
  638.      * This is called by the scrollpane itself to update the
  639.      * min,max,visible values.  The scrollpane is the only one
  640.      * that should be changing these since it is the source of
  641.      * these values.
  642.      */
  643.     void setSpan(int min, int max, int visible) {
  644.     // adjust the values to be reasonable
  645.     minimum = min;
  646.     maximum = Math.max(max, minimum + 1);
  647.     visibleAmount = Math.min(visible, maximum - minimum);
  648.     visibleAmount = Math.max(visibleAmount, 1);
  649.         blockIncrement = Math.max((int)(visible * .90), 1);
  650.     setValue(value);
  651.     }
  652.  
  653.     public int getOrientation() {
  654.         return orientation;
  655.     }
  656.  
  657.     public void setMinimum(int min) {
  658.     throw new AWTError(SCROLLPANE_ONLY);
  659.     }
  660.  
  661.     public int getMinimum() {
  662.         return 0;
  663.     }
  664.  
  665.     public void setMaximum(int max) {
  666.     throw new AWTError(SCROLLPANE_ONLY);
  667.     }
  668.  
  669.     public int getMaximum() {
  670.         return maximum;
  671.     }
  672.  
  673.     public synchronized void setUnitIncrement(int u) {
  674.     if (u != unitIncrement) {
  675.         unitIncrement = u;
  676.         if (sp.peer != null) {
  677.         ScrollPanePeer peer = (ScrollPanePeer) sp.peer;
  678.         peer.setUnitIncrement(this, u);
  679.         }
  680.     }
  681.     }
  682.  
  683.     public int getUnitIncrement() {
  684.         return unitIncrement;
  685.     }
  686.  
  687.     public synchronized void setBlockIncrement(int b) {
  688.         blockIncrement = b;
  689.     }
  690.  
  691.     public int getBlockIncrement() {
  692.         return blockIncrement;
  693.     }
  694.  
  695.     public void setVisibleAmount(int v) {
  696.     throw new AWTError(SCROLLPANE_ONLY);
  697.     }
  698.  
  699.     public int getVisibleAmount() {
  700.         return visibleAmount;
  701.     }
  702.  
  703.     public void setValue(int v) {
  704.     // bounds check
  705.     v = Math.max(v, minimum);
  706.     v = Math.min(v, maximum - visibleAmount);
  707.  
  708.         if (v != value) {
  709.         value = v;
  710.         // Synchronously notify the listeners so that they are
  711.         // guaranteed to be up-to-date with the Adjustable before
  712.         // it is mutated again.
  713.         AdjustmentEvent e =
  714.         new AdjustmentEvent(this, AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
  715.                     AdjustmentEvent.TRACK, value);
  716.         adjustmentListener.adjustmentValueChanged(e);
  717.     }
  718.     }
  719.  
  720.     public int getValue() {
  721.         return value;
  722.     }
  723.  
  724.     /**
  725.      * Adds the specified adjustment listener to receive adjustment events 
  726.      * from this ScrollPane.
  727.      * If l is null, no exception is thrown and no action is performed.
  728.      *
  729.      * @param    l   the adjustment listener.
  730.      * @see      java.awt.event.AdjustmentListener
  731.      * @see      java.awt.ScrollPane#removeAdjustmentListener
  732.      */
  733.     public synchronized void addAdjustmentListener(AdjustmentListener l) {
  734.     if (l == null) {
  735.         return;
  736.     }
  737.     adjustmentListener = AWTEventMulticaster.add(adjustmentListener, l);
  738.     }
  739.  
  740.     /**
  741.      * Removes the specified adjustment listener so that it no longer
  742.      * receives adjustment events from this button. 
  743.      * If l is null, no exception is thrown and no action is performed.
  744.      *
  745.      * @param         l     the adjustment listener.
  746.      * @see           java.awt.event.AdjustmentListener
  747.      * @see           java.awt.Button#addAdjustmentListener
  748.      * @since         JDK1.1
  749.      */
  750.     public synchronized void removeAdjustmentListener(AdjustmentListener l){
  751.     if (l == null) {
  752.         return;
  753.     }
  754.     adjustmentListener = AWTEventMulticaster.remove(adjustmentListener, l);
  755.     }
  756.  
  757.     public String toString() {
  758.     return getClass().getName() + "[" + paramString() + "]";
  759.     }
  760.  
  761.     public String paramString() {
  762.         return ((orientation==Adjustable.VERTICAL?"vertical,":"horizontal,")+
  763.           "[0.."+maximum+"],"+"val="+value+",vis="+visibleAmount+
  764.                 ",unit="+unitIncrement+",block="+blockIncrement);
  765.     }
  766. }
  767.  
  768.