home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / jfc.bin / ScrollPaneLayout.java < prev    next >
Text File  |  1998-02-26  |  20KB  |  685 lines

  1. /*
  2.  * @(#)ScrollPaneLayout.java    1.20 98/02/02
  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 com.sun.java.swing;
  22.  
  23.  
  24. import com.sun.java.swing.border.*;
  25.  
  26. import java.awt.LayoutManager;
  27. import java.awt.Component;
  28. import java.awt.Container;
  29. import java.awt.Rectangle;
  30. import java.awt.Dimension;
  31. import java.awt.Insets;
  32. import java.io.Serializable;
  33.  
  34.  
  35. /**
  36.  * The layout manager used by JScrollPane.  JScrollPaneLayout is
  37.  * responsible for nine components: a viewport, two scrollbars,
  38.  * a row header, a column header, and four "corner" components.
  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.  * @version 1.20 02/02/98
  48.  * @author unknown
  49.  */
  50. public class ScrollPaneLayout
  51.     implements LayoutManager, ScrollPaneConstants, Serializable
  52. {
  53.     protected JViewport viewport;
  54.     protected JScrollBar vsb;
  55.     protected JScrollBar hsb;
  56.     protected JViewport rowHead;
  57.     protected JViewport colHead;
  58.     protected Component lowerLeft;
  59.     protected Component lowerRight;
  60.     protected Component upperLeft;
  61.     protected Component upperRight;
  62.  
  63.     protected int vsbPolicy = VERTICAL_SCROLLBAR_AS_NEEDED;
  64.     protected int hsbPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED;
  65.  
  66.  
  67.     /** 
  68.      * Only one of these is allowed, remove the old one if neccessary.
  69.      */
  70.     protected Component addSingletonComponent(Component oldC, Component newC)
  71.     {
  72.     if ((oldC != null) && (oldC != newC)) {
  73.         oldC.getParent().remove(oldC);
  74.     }
  75.     return newC;
  76.     }
  77.  
  78.  
  79.     public void addLayoutComponent(String s, Component c) 
  80.     {
  81.     if (s.equals(VIEWPORT)) {
  82.         viewport = (JViewport)addSingletonComponent(viewport, c);
  83.     }
  84.     else if (s.equals(VERTICAL_SCROLLBAR)) {
  85.         vsb = (JScrollBar)addSingletonComponent(vsb, c);
  86.     }
  87.     else if (s.equals(HORIZONTAL_SCROLLBAR)) {
  88.         hsb = (JScrollBar)addSingletonComponent(hsb, c);
  89.     }
  90.     else if (s.equals(ROW_HEADER)) {
  91.         rowHead = (JViewport)addSingletonComponent(rowHead, c);
  92.     }
  93.     else if (s.equals(COLUMN_HEADER)) {
  94.         colHead = (JViewport)addSingletonComponent(colHead, c);
  95.     }
  96.     else if (s.equals(LOWER_LEFT_CORNER)) {
  97.         lowerLeft = addSingletonComponent(lowerLeft, c);
  98.     }
  99.     else if (s.equals(LOWER_RIGHT_CORNER)) {
  100.         lowerRight = addSingletonComponent(lowerRight, c);
  101.     }
  102.     else if (s.equals(UPPER_LEFT_CORNER)) {
  103.         upperLeft = addSingletonComponent(upperLeft, c);
  104.     }
  105.     else if (s.equals(UPPER_RIGHT_CORNER)) {
  106.         upperRight = addSingletonComponent(upperRight, c);
  107.     }
  108.     else {
  109.         throw new IllegalArgumentException("invalid layout key " + s);
  110.     }
  111.     }
  112.  
  113.  
  114.     public void removeLayoutComponent(Component c) 
  115.     {
  116.     if (c == viewport) {
  117.         viewport = null;
  118.     }
  119.     else if (c == vsb) {
  120.         vsb = null;
  121.     }
  122.     else if (c == hsb) {
  123.         hsb = null;
  124.     }
  125.     else if (c == rowHead) {
  126.         rowHead = null;
  127.     }
  128.     else if (c == colHead) {
  129.         colHead = null;
  130.     }
  131.     else if (c == lowerLeft) {
  132.         lowerLeft = null;
  133.     }
  134.     else if (c == upperLeft) {
  135.         upperLeft = null;
  136.     }
  137.     else if (c == upperRight) {
  138.         upperRight = null;
  139.     }
  140.     }
  141.  
  142.  
  143.     public int getVerticalScrollBarPolicy() {
  144.     return vsbPolicy;
  145.     }
  146.  
  147.     public void setVerticalScrollBarPolicy(int x) {
  148.     switch (x) {
  149.     case VERTICAL_SCROLLBAR_AS_NEEDED:
  150.     case VERTICAL_SCROLLBAR_NEVER:
  151.     case VERTICAL_SCROLLBAR_ALWAYS:
  152.             vsbPolicy = x;
  153.         break;
  154.     default:
  155.         throw new IllegalArgumentException("invalid verticalScrollBarPolicy");
  156.     }
  157.     }
  158.  
  159.  
  160.     public int getHorizontalScrollBarPolicy() {
  161.     return hsbPolicy;
  162.     }
  163.  
  164.     public void setHorizontalScrollBarPolicy(int x) {
  165.     switch (x) {
  166.     case HORIZONTAL_SCROLLBAR_AS_NEEDED:
  167.     case HORIZONTAL_SCROLLBAR_NEVER:
  168.     case HORIZONTAL_SCROLLBAR_ALWAYS:
  169.             hsbPolicy = x;
  170.         break;
  171.     default:
  172.         throw new IllegalArgumentException("invalid horizontalScrollBarPolicy");
  173.     }
  174.     }
  175.  
  176.  
  177.     public JViewport getViewport() {
  178.     return viewport;
  179.     }
  180.  
  181.  
  182.     public JScrollBar getHorizontalScrollBar() {
  183.     return hsb;
  184.     }
  185.  
  186.     public JScrollBar getVerticalScrollBar() {
  187.     return vsb;
  188.     }
  189.  
  190.  
  191.     public JViewport getRowHeader() {
  192.     return rowHead;
  193.     }
  194.  
  195.     public JViewport getColumnHeader() {
  196.     return colHead;
  197.     }
  198.  
  199.  
  200.     public Component getCorner(String key) {
  201.     if (key.equals(LOWER_LEFT_CORNER)) {
  202.         return lowerLeft;
  203.     }
  204.     else if (key.equals(LOWER_RIGHT_CORNER)) {
  205.         return lowerRight;
  206.     }
  207.     else if (key.equals(UPPER_LEFT_CORNER)) {
  208.         return upperLeft;
  209.     }
  210.     else if (key.equals(UPPER_RIGHT_CORNER)) {
  211.         return upperRight;
  212.     }
  213.     else {
  214.         return null;
  215.     }
  216.     }
  217.  
  218.  
  219.     /** 
  220.      * The preferred size of a ScrollPane is the size of the insets
  221.      * plus preferred size of the viewport plus the preferred size of 
  222.      * the visible headers, plus the preferred size of the scrollbars
  223.      * that will appear given the current view and the current
  224.      * scrollbar displayPolicies.  
  225.      * 
  226.      * @return The preferred size of the viewport and any scrollbars.
  227.      * @see ViewportLayout
  228.      * @see LayoutManager
  229.      */
  230.  
  231.     public Dimension preferredLayoutSize(Container parent) 
  232.     {
  233.     Insets insets = parent.getInsets();
  234.     int prefWidth = insets.left + insets.right;
  235.     int prefHeight = insets.top + insets.bottom;
  236.  
  237.     /* Note that viewport.getViewSize() is equivalent to 
  238.      * viewport.getView().getPreferredSize() modulo a null
  239.      * view or a view whose size was explicitly set.
  240.      */
  241.  
  242.     Dimension extentSize = null;
  243.     Dimension viewSize = null;
  244.     Component view = null;
  245.  
  246.     if (viewport !=  null) {
  247.         extentSize = viewport.getPreferredSize();
  248.         viewSize = viewport.getViewSize();
  249.         view = viewport.getView();
  250.     }
  251.  
  252.     /* If there's a viewport add its preferredSize.
  253.      */
  254.  
  255.     if (extentSize != null) {
  256.         prefWidth += extentSize.width;
  257.         prefHeight += extentSize.height;
  258.     }
  259.  
  260.     /* If there's a JScrollPane.viewportBorder, add its insets.
  261.      */
  262.  
  263.     Border viewportBorder = ((JScrollPane)parent).getViewportBorder();
  264.     if (viewportBorder != null) {
  265.         Insets vpbInsets = viewportBorder.getBorderInsets(parent);
  266.         prefWidth += vpbInsets.left + vpbInsets.right;
  267.         prefHeight += vpbInsets.top + vpbInsets.bottom;
  268.     }
  269.  
  270.     /* If a header exists and it's visible, factor its
  271.      * preferred size in.
  272.      */
  273.  
  274.     if ((rowHead != null) && rowHead.isVisible()) {
  275.         prefWidth += rowHead.getPreferredSize().width;
  276.     }
  277.  
  278.     if ((colHead != null) && colHead.isVisible()) {
  279.         prefHeight += colHead.getPreferredSize().height;
  280.     }
  281.  
  282.     /* If a scrollbar is going to appear, factor its preferred size in.
  283.      * If the scrollbars policy is AS_NEEDED, this can be a little
  284.      * tricky:
  285.      * 
  286.      * - If the view is a Scrollable then scrollableTracksViewportWidth
  287.      * and scrollableTracksViewportHeight can be used to effectively 
  288.      * disable scrolling (if they're true) in their respective dimensions.
  289.      * 
  290.      * - Assuming that a scrollbar hasn't been disabled by the 
  291.      * previous constraint, we need to decide if the scrollbar is going 
  292.      * to appear to correctly compute the JScrollPanes preferred size.
  293.      * To do this we compare the preferredSize of the viewport (the 
  294.      * extentSize) to the preferredSize of the view.  Although we're
  295.      * not responsible for laying out the view we'll assume that the 
  296.      * JViewport will always give it its preferredSize.
  297.      */
  298.  
  299.     if ((vsb != null) && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
  300.         if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
  301.         prefWidth += vsb.getPreferredSize().width;
  302.         }
  303.         else if ((viewSize != null) && (extentSize != null)) {
  304.         boolean canScroll = true;
  305.         if (view instanceof Scrollable) {
  306.             canScroll = !((Scrollable)view).getScrollableTracksViewportHeight();
  307.         }
  308.         if (canScroll && (viewSize.height > extentSize.height)) {
  309.             prefWidth += vsb.getPreferredSize().width;
  310.         }
  311.         }
  312.     }
  313.  
  314.     if ((hsb != null) && (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)) {
  315.         if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
  316.         prefHeight += hsb.getPreferredSize().height;
  317.         }
  318.         else if ((viewSize != null) && (extentSize != null)) {
  319.         boolean canScroll = true;
  320.         if (view instanceof Scrollable) {
  321.             canScroll = !((Scrollable)view).getScrollableTracksViewportWidth();
  322.         }
  323.         if (canScroll && (viewSize.width > extentSize.width)) {
  324.             prefHeight += hsb.getPreferredSize().height;
  325.         }
  326.         }
  327.     }
  328.  
  329.     return new Dimension(prefWidth, prefHeight);
  330.     }
  331.  
  332.  
  333.     /** 
  334.      * The minimum size of a ScrollPane is the size of the insets 
  335.      * plus minimum size of the viewport, plus the scrollpanes
  336.      * viewportBorder insets, plus the minimum size 
  337.      * of the visible headers, plus the minimum size of the 
  338.      * scrollbars whose displayPolicy isn't NEVER.
  339.      */
  340.  
  341.     public Dimension minimumLayoutSize(Container parent) 
  342.     {
  343.     Insets insets = parent.getInsets();
  344.     int minWidth = insets.left + insets.right;
  345.     int minHeight = insets.top + insets.bottom;
  346.     
  347.     /* If there's a viewport add its minimumSize.
  348.      */
  349.     
  350.     if (viewport != null) {
  351.         Dimension size = viewport.getMinimumSize();
  352.         minWidth += size.width;
  353.         minHeight += size.height;
  354.     }
  355.  
  356.     /* If there's a JScrollPane.viewportBorder, add its insets.
  357.      */
  358.  
  359.     Border viewportBorder = ((JScrollPane)parent).getViewportBorder();
  360.     if (viewportBorder != null) {
  361.         Insets vpbInsets = viewportBorder.getBorderInsets(parent);
  362.         minWidth += vpbInsets.left + vpbInsets.right;
  363.         minHeight += vpbInsets.top + vpbInsets.bottom;
  364.     }
  365.  
  366.     /* If a header exists and it's visible, factor its
  367.      * minimum size in.
  368.      */
  369.  
  370.     if ((rowHead != null) && rowHead.isVisible()) {
  371.         Dimension size = rowHead.getMinimumSize();
  372.         minWidth += size.width;
  373.         minHeight = Math.max(minHeight, size.height);
  374.     }
  375.  
  376.     if ((colHead != null) && colHead.isVisible()) {
  377.         Dimension size = colHead.getMinimumSize();
  378.         minWidth = Math.max(minWidth, size.width);
  379.         minHeight += size.height;
  380.     }
  381.  
  382.     /* If a scrollbar might appear, factor its minimum
  383.      * size in.
  384.      */
  385.  
  386.     if ((vsb != null) && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
  387.         Dimension size = vsb.getMinimumSize();
  388.         minWidth += size.width;
  389.         minHeight = Math.max(minHeight, size.height);
  390.     }
  391.  
  392.     if ((hsb != null) && (hsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
  393.         Dimension size = hsb.getMinimumSize();
  394.         minWidth = Math.max(minWidth, size.width);
  395.         minHeight += size.height;
  396.     }
  397.  
  398.     return new Dimension(minWidth, minHeight);
  399.     }
  400.  
  401.  
  402.     /** 
  403.      * Layout the scrollpane according to the following constraints:
  404.      * <ul>
  405.      * <li> The row header, if present and visible, gets its preferred
  406.      * height and the viewports width.
  407.      * 
  408.      * <li> The column header, if present and visible, gets its preferred
  409.      * width and the viewports height.
  410.      * 
  411.      * <li> If a vertical scrollbar is needed, i.e. if the viewports extent
  412.      * height is smaller than its view height or if the displayPolicy
  413.      * is ALWAYS, it's treated like the row header wrt it's dimensions and
  414.      * it's made visible.
  415.      * 
  416.      * <li> If a horizontal scrollbar is needed it's treated like the
  417.      * column header (and see the vertical scrollbar item).
  418.      * 
  419.      * <li> If the scrollpane has a non-null viewportBorder, then space
  420.      * is allocated for that.
  421.      * 
  422.      * <li> The viewport gets the space available after accounting for
  423.      * the previous constraints.
  424.      * 
  425.      * <li> The corner components, if provided, are aligned with the 
  426.      * ends of the scrollbars and headers. If there's a vertical
  427.      * scrollbar the right corners appear, if there's a horizontal
  428.      * scrollbar the lower corners appear, a row header gets left
  429.      * corners and a column header gets upper corners.
  430.      * </ul>
  431.      */
  432.  
  433.     public void layoutContainer(Container parent) 
  434.     {
  435.     Rectangle availR = new Rectangle(parent.getSize());
  436.  
  437.     Insets insets = parent.getInsets();
  438.     availR.x = insets.left;
  439.     availR.y = insets.top;
  440.     availR.width -= insets.left + insets.right;
  441.     availR.height -= insets.top + insets.bottom;
  442.  
  443.  
  444.     /* If there's a visible column header remove the space it 
  445.      * needs from the top of availR.  The column header is treated 
  446.      * as if it were fixed height, arbitrary width.
  447.      */
  448.  
  449.     Rectangle colHeadR = new Rectangle(0, availR.y, 0, 0);
  450.  
  451.     if ((colHead != null) && (colHead.isVisible())) {
  452.         int colHeadHeight = colHead.getPreferredSize().height;
  453.         colHeadR.height = colHeadHeight; 
  454.         availR.y += colHeadHeight;
  455.         availR.height -= colHeadHeight;
  456.     }
  457.  
  458.     /* If there's a visible row header remove the space it needs
  459.      * from the left of availR.  The row header is treated 
  460.      * as if it were fixed width, arbitrary height.
  461.      */
  462.  
  463.     Rectangle rowHeadR = new Rectangle(availR.x, 0, 0, 0);
  464.     
  465.     if ((rowHead != null) && (rowHead.isVisible())) {
  466.         int rowHeadWidth = rowHead.getPreferredSize().width;
  467.         rowHeadR.width = rowHeadWidth;
  468.         availR.x += rowHeadWidth;
  469.         availR.width -= rowHeadWidth;
  470.     }
  471.  
  472.     /* If there's a JScrollPane.viewportBorder, remove the
  473.      * space it occupies for availR.
  474.      */
  475.  
  476.     Border viewportBorder = ((JScrollPane)parent).getViewportBorder();
  477.     Insets vpbInsets;
  478.     if (viewportBorder != null) {
  479.         vpbInsets = viewportBorder.getBorderInsets(parent);
  480.         availR.x += vpbInsets.left;
  481.         availR.y += vpbInsets.top;
  482.         availR.width -= vpbInsets.left + vpbInsets.right;
  483.         availR.height -= vpbInsets.top + vpbInsets.bottom;
  484.     }
  485.     else {
  486.         vpbInsets = new Insets(0,0,0,0);
  487.     }
  488.  
  489.     colHeadR.x = availR.x;
  490.     rowHeadR.y = availR.y;
  491.  
  492.     /* At this point availR is the space available for the viewport
  493.      * and scrollbars and the rowHeadR colHeadR rectangles are correct
  494.      * except for their width and height respectively.  Once we're 
  495.      * through computing the dimensions  of these three parts we can 
  496.      * go back and set the dimensions of rowHeadR.width, colHeadR.height, 
  497.      * and the bounds for the corners.
  498.      * 
  499.          * We'll decide about putting up scrollbars by comparing the 
  500.          * viewport views preferred size with the viewports extent
  501.      * size (generally just its size).  Using the preferredSize is
  502.      * reasonable because layout proceeds top down - so we expect
  503.      * the viewport to be layed out next.  And it will change the
  504.      * resize the view to its preferred size or bigger.  It's potentially 
  505.      * bigger if the views Scrollable.getViewTracksViewport{Width,Height}
  506.      * returns true.
  507.      */
  508.  
  509.     Component view = (viewport != null) ? viewport.getView() : null;
  510.     Dimension viewSize =  
  511.         (view != null) ? view.getPreferredSize() 
  512.                            : new Dimension(0,0);
  513.  
  514.     Dimension extentSize = 
  515.         (viewport != null) ? viewport.toViewCoordinates(availR.getSize()) 
  516.                            : new Dimension(0,0);
  517.  
  518.     /* If there's a vertical scrollbar and we need one, allocate
  519.      * space for it (we'll make it visible later). A vertical 
  520.      * scrollbar is considered to be fixed width, arbitrary height.
  521.      */
  522.  
  523.     Rectangle vsbR = new Rectangle(0, availR.y - vpbInsets.top, 0, 0);
  524.     boolean vsbNeeded = 
  525.         (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) ||
  526.         ((viewSize.height > extentSize.height) && 
  527.          (vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED));
  528.  
  529.     if ((vsb != null) && vsbNeeded) {
  530.         int vsbWidth = vsb.getPreferredSize().width;
  531.         availR.width -= vsbWidth;
  532.         vsbR.x = availR.x + availR.width + vpbInsets.right;
  533.         vsbR.width = vsbWidth;
  534.     }
  535.     
  536.     /* If there's a horizontal scrollbar and we need one, allocate
  537.      * space for it (we'll make it visible later). A horizontal 
  538.      * scrollbar is considered to be fixed height, arbitrary width.
  539.      */
  540.  
  541.     Rectangle hsbR = new Rectangle(availR.x - vpbInsets.left, 0, 0, 0);
  542.     boolean hsbNeeded = 
  543.         (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) || 
  544.         ((viewSize.width > extentSize.width) && 
  545.          (hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED));
  546.  
  547.     if ((hsb != null) && hsbNeeded) {
  548.         int hsbHeight = hsb.getPreferredSize().height;
  549.         availR.height -= hsbHeight;
  550.         hsbR.y = availR.y + availR.height + vpbInsets.bottom;
  551.         hsbR.height = hsbHeight;
  552.     
  553.         /* If we added the horizontal scrollbar then we've implicitly 
  554.          * reduced  the vertical space available to the viewport. 
  555.          * As a consequence we may have to add the vertical scrollbar, 
  556.          * if that hasn't been done so already.  Ofcourse we
  557.          * don't bother with any of this if the vsbPolicy is NEVER.
  558.          */
  559.         if ((vsb != null) && !vsbNeeded && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
  560.         extentSize = viewport.toViewCoordinates(availR.getSize());
  561.         vsbNeeded = viewSize.height > extentSize.height;
  562.  
  563.         if (vsbNeeded) {
  564.             int vsbWidth = vsb.getPreferredSize().width;
  565.             availR.width -= vsbWidth;
  566.             vsbR.x = availR.x + availR.width + vpbInsets.right;
  567.             vsbR.width = vsbWidth;
  568.         }
  569.         }
  570.     }
  571.  
  572.     /* We now have the final size of the viewport: availR.
  573.      * Now fixup the header and scrollbar widths/heights.
  574.      */
  575.     
  576.     vsbR.height = availR.height + vpbInsets.top + vpbInsets.bottom;
  577.     hsbR.width = availR.width + vpbInsets.left + vpbInsets.right;
  578.     rowHeadR.height = availR.height;
  579.     colHeadR.width = availR.width;
  580.  
  581.     /* Set the bounds of all nine components.  The scrollbars
  582.      * are made invisible if they're not needed.
  583.      */
  584.     
  585.     if (viewport != null) {
  586.         viewport.setBounds(availR);
  587.     }
  588.  
  589.     if (rowHead != null) {
  590.         rowHead.setBounds(rowHeadR);
  591.     }
  592.  
  593.     if (colHead != null) {
  594.         colHead.setBounds(colHeadR);
  595.     }
  596.  
  597.     if (vsb != null) {
  598.         if (vsbNeeded) {
  599.         vsb.setVisible(true);
  600.         vsb.setBounds(vsbR);
  601.         }
  602.         else {
  603.         vsb.setVisible(false);
  604.         }
  605.     }
  606.  
  607.     if (hsb != null) {
  608.         if (hsbNeeded) {
  609.         hsb.setVisible(true);
  610.         hsb.setBounds(hsbR);
  611.         }
  612.         else {
  613.         hsb.setVisible(false);
  614.         }
  615.     }
  616.  
  617.     if (lowerLeft != null) {
  618.         lowerLeft.setBounds(rowHeadR.x, hsbR.y, rowHeadR.width, hsbR.height);
  619.     }
  620.  
  621.     if (lowerRight != null) {
  622.         lowerRight.setBounds(vsbR.x, hsbR.y, vsbR.width, hsbR.height);
  623.     }
  624.  
  625.     if (upperLeft != null) {
  626.         upperLeft.setBounds(rowHeadR.x, colHeadR.y, rowHeadR.width, colHeadR.height);
  627.     }
  628.  
  629.     if (upperRight != null) {
  630.         upperRight.setBounds(vsbR.x, colHeadR.y, vsbR.width, colHeadR.height);
  631.     }
  632.     }
  633.     
  634.  
  635.     public Rectangle getViewportBorderBounds(JScrollPane sp)
  636.     {
  637.     Rectangle borderR = new Rectangle(sp.getSize());
  638.  
  639.     Insets insets = sp.getInsets();
  640.     borderR.x = insets.left;
  641.     borderR.y = insets.top;
  642.     borderR.width -= insets.left + insets.right;
  643.     borderR.height -= insets.top + insets.bottom;
  644.  
  645.  
  646.     /* If there's a visible column header remove the space it 
  647.      * needs from the top of borderR.  
  648.      */
  649.  
  650.     if ((colHead != null) && (colHead.isVisible())) {
  651.         int colHeadHeight = colHead.getHeight();
  652.         borderR.y += colHeadHeight;
  653.         borderR.height -= colHeadHeight;
  654.     }
  655.  
  656.     /* If there's a visible row header remove the space it needs
  657.      * from the left of borderR.  
  658.      */
  659.  
  660.     if ((rowHead != null) && (rowHead.isVisible())) {
  661.         int rowHeadWidth = rowHead.getWidth();
  662.         borderR.x += rowHeadWidth;
  663.         borderR.width -= rowHeadWidth;
  664.     }
  665.  
  666.     /* If there's a visible vertical scrollbar remove the space it needs
  667.      * from the width of borderR.  
  668.      */
  669.  
  670.     if ((vsb != null) && (vsb.isVisible())) {
  671.         borderR.width -= vsb.getWidth();
  672.     }
  673.  
  674.     /* If there's a visible horizontal scrollbar remove the space it needs
  675.      * from the height of borderR.  
  676.      */
  677.  
  678.     if ((hsb != null) && (hsb.isVisible())) {
  679.         borderR.height -= hsb.getHeight();
  680.     }
  681.  
  682.     return borderR;
  683.     }
  684. }
  685.