Source Code Cross Referenced for ScrollPaneLayout.java in  » 6.0-JDK-Core » swing » javax » swing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package javax.swing;
0027
0028        import javax.swing.border.*;
0029
0030        import java.awt.LayoutManager;
0031        import java.awt.Component;
0032        import java.awt.Container;
0033        import java.awt.Rectangle;
0034        import java.awt.Dimension;
0035        import java.awt.Insets;
0036        import java.io.Serializable;
0037
0038        /**
0039         * The layout manager used by <code>JScrollPane</code>.  
0040         * <code>JScrollPaneLayout</code> is
0041         * responsible for nine components: a viewport, two scrollbars,
0042         * a row header, a column header, and four "corner" components.
0043         * <p>
0044         * <strong>Warning:</strong>
0045         * Serialized objects of this class will not be compatible with
0046         * future Swing releases. The current serialization support is
0047         * appropriate for short term storage or RMI between applications running
0048         * the same version of Swing.  As of 1.4, support for long term storage
0049         * of all JavaBeans<sup><font size="-2">TM</font></sup>
0050         * has been added to the <code>java.beans</code> package.
0051         * Please see {@link java.beans.XMLEncoder}.
0052         *
0053         * @see JScrollPane
0054         * @see JViewport
0055         *
0056         * @version 1.70 05/05/07
0057         * @author Hans Muller
0058         */
0059        public class ScrollPaneLayout implements  LayoutManager,
0060                ScrollPaneConstants, Serializable {
0061
0062            /** 
0063             * The scrollpane's viewport child.  
0064             * Default is an empty <code>JViewport</code>.
0065             * @see JScrollPane#setViewport
0066             */
0067            protected JViewport viewport;
0068
0069            /**
0070             * The scrollpane's vertical scrollbar child.  
0071             * Default is a <code>JScrollBar</code>.
0072             * @see JScrollPane#setVerticalScrollBar
0073             */
0074            protected JScrollBar vsb;
0075
0076            /**
0077             * The scrollpane's horizontal scrollbar child.  
0078             * Default is a <code>JScrollBar</code>.
0079             * @see JScrollPane#setHorizontalScrollBar
0080             */
0081            protected JScrollBar hsb;
0082
0083            /** 
0084             * The row header child.  Default is <code>null</code>.
0085             * @see JScrollPane#setRowHeader
0086             */
0087            protected JViewport rowHead;
0088
0089            /** 
0090             * The column header child.  Default is <code>null</code>.
0091             * @see JScrollPane#setColumnHeader
0092             */
0093            protected JViewport colHead;
0094
0095            /**
0096             * The component to display in the lower left corner. 
0097             * Default is <code>null</code>.
0098             * @see JScrollPane#setCorner
0099             */
0100            protected Component lowerLeft;
0101
0102            /**
0103             * The component to display in the lower right corner. 
0104             * Default is <code>null</code>.
0105             * @see JScrollPane#setCorner
0106             */
0107            protected Component lowerRight;
0108
0109            /**
0110             * The component to display in the upper left corner. 
0111             * Default is <code>null</code>.
0112             * @see JScrollPane#setCorner
0113             */
0114            protected Component upperLeft;
0115
0116            /**
0117             * The component to display in the upper right corner. 
0118             * Default is <code>null</code>.
0119             * @see JScrollPane#setCorner
0120             */
0121            protected Component upperRight;
0122
0123            /** 
0124             * The display policy for the vertical scrollbar.
0125             * The default is <code>ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED</code>.  
0126             * <p>
0127             * This field is obsolete, please use the <code>JScrollPane</code> field instead.
0128             * 
0129             * @see JScrollPane#setVerticalScrollBarPolicy
0130             */
0131            protected int vsbPolicy = VERTICAL_SCROLLBAR_AS_NEEDED;
0132
0133            /**
0134             * The display policy for the horizontal scrollbar.
0135             * The default is <code>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED</code>.
0136             * <p>
0137             * This field is obsolete, please use the <code>JScrollPane</code> field instead.
0138             * 
0139             * @see JScrollPane#setHorizontalScrollBarPolicy
0140             */
0141            protected int hsbPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED;
0142
0143            /**
0144             * This method is invoked after the ScrollPaneLayout is set as the
0145             * LayoutManager of a <code>JScrollPane</code>.
0146             * It initializes all of the internal fields that
0147             * are ordinarily set by <code>addLayoutComponent</code>.  For example:
0148             * <pre>
0149             * ScrollPaneLayout mySPLayout = new ScrollPanelLayout() {
0150             *     public void layoutContainer(Container p) {
0151             *         super.layoutContainer(p);
0152             *         // do some extra work here ...
0153             *     }
0154             * };
0155             * scrollpane.setLayout(mySPLayout):
0156             * </pre>
0157             */
0158            public void syncWithScrollPane(JScrollPane sp) {
0159                viewport = sp.getViewport();
0160                vsb = sp.getVerticalScrollBar();
0161                hsb = sp.getHorizontalScrollBar();
0162                rowHead = sp.getRowHeader();
0163                colHead = sp.getColumnHeader();
0164                lowerLeft = sp.getCorner(LOWER_LEFT_CORNER);
0165                lowerRight = sp.getCorner(LOWER_RIGHT_CORNER);
0166                upperLeft = sp.getCorner(UPPER_LEFT_CORNER);
0167                upperRight = sp.getCorner(UPPER_RIGHT_CORNER);
0168                vsbPolicy = sp.getVerticalScrollBarPolicy();
0169                hsbPolicy = sp.getHorizontalScrollBarPolicy();
0170            }
0171
0172            /** 
0173             * Removes an existing component.  When a new component, such as
0174             * the left corner, or vertical scrollbar, is added, the old one,
0175             * if it exists, must be removed.
0176             * <p>
0177             * This method returns <code>newC</code>. If <code>oldC</code> is
0178             * not equal to <code>newC</code> and is non-<code>null</code>,
0179             * it will be removed from its parent.
0180             * 
0181             * @param oldC the <code>Component</code> to replace
0182             * @param newC the <code>Component</code> to add
0183             * @return the <code>newC</code>
0184             */
0185            protected Component addSingletonComponent(Component oldC,
0186                    Component newC) {
0187                if ((oldC != null) && (oldC != newC)) {
0188                    oldC.getParent().remove(oldC);
0189                }
0190                return newC;
0191            }
0192
0193            /**
0194             * Adds the specified component to the layout. The layout is
0195             * identified using one of:
0196             * <ul>
0197             * <li>ScrollPaneConstants.VIEWPORT
0198             * <li>ScrollPaneConstants.VERTICAL_SCROLLBAR
0199             * <li>ScrollPaneConstants.HORIZONTAL_SCROLLBAR
0200             * <li>ScrollPaneConstants.ROW_HEADER
0201             * <li>ScrollPaneConstants.COLUMN_HEADER
0202             * <li>ScrollPaneConstants.LOWER_LEFT_CORNER
0203             * <li>ScrollPaneConstants.LOWER_RIGHT_CORNER
0204             * <li>ScrollPaneConstants.UPPER_LEFT_CORNER
0205             * <li>ScrollPaneConstants.UPPER_RIGHT_CORNER
0206             * </ul>
0207             *
0208             * @param s the component identifier
0209             * @param c the the component to be added
0210             * @exception IllegalArgumentException if <code>s</code> is an invalid key
0211             */
0212            public void addLayoutComponent(String s, Component c) {
0213                if (s.equals(VIEWPORT)) {
0214                    viewport = (JViewport) addSingletonComponent(viewport, c);
0215                } else if (s.equals(VERTICAL_SCROLLBAR)) {
0216                    vsb = (JScrollBar) addSingletonComponent(vsb, c);
0217                } else if (s.equals(HORIZONTAL_SCROLLBAR)) {
0218                    hsb = (JScrollBar) addSingletonComponent(hsb, c);
0219                } else if (s.equals(ROW_HEADER)) {
0220                    rowHead = (JViewport) addSingletonComponent(rowHead, c);
0221                } else if (s.equals(COLUMN_HEADER)) {
0222                    colHead = (JViewport) addSingletonComponent(colHead, c);
0223                } else if (s.equals(LOWER_LEFT_CORNER)) {
0224                    lowerLeft = addSingletonComponent(lowerLeft, c);
0225                } else if (s.equals(LOWER_RIGHT_CORNER)) {
0226                    lowerRight = addSingletonComponent(lowerRight, c);
0227                } else if (s.equals(UPPER_LEFT_CORNER)) {
0228                    upperLeft = addSingletonComponent(upperLeft, c);
0229                } else if (s.equals(UPPER_RIGHT_CORNER)) {
0230                    upperRight = addSingletonComponent(upperRight, c);
0231                } else {
0232                    throw new IllegalArgumentException("invalid layout key "
0233                            + s);
0234                }
0235            }
0236
0237            /**
0238             * Removes the specified component from the layout.
0239             *   
0240             * @param c the component to remove
0241             */
0242            public void removeLayoutComponent(Component c) {
0243                if (c == viewport) {
0244                    viewport = null;
0245                } else if (c == vsb) {
0246                    vsb = null;
0247                } else if (c == hsb) {
0248                    hsb = null;
0249                } else if (c == rowHead) {
0250                    rowHead = null;
0251                } else if (c == colHead) {
0252                    colHead = null;
0253                } else if (c == lowerLeft) {
0254                    lowerLeft = null;
0255                } else if (c == lowerRight) {
0256                    lowerRight = null;
0257                } else if (c == upperLeft) {
0258                    upperLeft = null;
0259                } else if (c == upperRight) {
0260                    upperRight = null;
0261                }
0262            }
0263
0264            /**
0265             * Returns the vertical scrollbar-display policy.
0266             *
0267             * @return an integer giving the display policy
0268             * @see #setVerticalScrollBarPolicy
0269             */
0270            public int getVerticalScrollBarPolicy() {
0271                return vsbPolicy;
0272            }
0273
0274            /**
0275             * Sets the vertical scrollbar-display policy. The options
0276             * are:
0277             * <ul>
0278             * <li>ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED
0279             * <li>ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER
0280             * <li>ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS
0281             * </ul>
0282             * Note: Applications should use the <code>JScrollPane</code> version
0283             * of this method.  It only exists for backwards compatibility
0284             * with the Swing 1.0.2 (and earlier) versions of this class.
0285             *
0286             * @param x an integer giving the display policy
0287             * @exception IllegalArgumentException if <code>x</code> is an invalid
0288             *		vertical scroll bar policy, as listed above
0289             */
0290            public void setVerticalScrollBarPolicy(int x) {
0291                switch (x) {
0292                case VERTICAL_SCROLLBAR_AS_NEEDED:
0293                case VERTICAL_SCROLLBAR_NEVER:
0294                case VERTICAL_SCROLLBAR_ALWAYS:
0295                    vsbPolicy = x;
0296                    break;
0297                default:
0298                    throw new IllegalArgumentException(
0299                            "invalid verticalScrollBarPolicy");
0300                }
0301            }
0302
0303            /**
0304             * Returns the horizontal scrollbar-display policy.
0305             *
0306             * @return an integer giving the display policy
0307             * @see #setHorizontalScrollBarPolicy
0308             */
0309            public int getHorizontalScrollBarPolicy() {
0310                return hsbPolicy;
0311            }
0312
0313            /**
0314             * Sets the horizontal scrollbar-display policy.
0315             * The options are:<ul>
0316             * <li>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED
0317             * <li>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
0318             * <li>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS
0319             * </ul>
0320             * Note: Applications should use the <code>JScrollPane</code> version
0321             * of this method.  It only exists for backwards compatibility
0322             * with the Swing 1.0.2 (and earlier) versions of this class.
0323             *
0324             * @param x an int giving the display policy
0325             * @exception IllegalArgumentException if <code>x</code> is not a valid
0326             *		horizontal scrollbar policy, as listed above
0327             */
0328            public void setHorizontalScrollBarPolicy(int x) {
0329                switch (x) {
0330                case HORIZONTAL_SCROLLBAR_AS_NEEDED:
0331                case HORIZONTAL_SCROLLBAR_NEVER:
0332                case HORIZONTAL_SCROLLBAR_ALWAYS:
0333                    hsbPolicy = x;
0334                    break;
0335                default:
0336                    throw new IllegalArgumentException(
0337                            "invalid horizontalScrollBarPolicy");
0338                }
0339            }
0340
0341            /**
0342             * Returns the <code>JViewport</code> object that displays the
0343             * scrollable contents.
0344             * @return the <code>JViewport</code> object that displays the scrollable contents
0345             * @see JScrollPane#getViewport
0346             */
0347            public JViewport getViewport() {
0348                return viewport;
0349            }
0350
0351            /**
0352             * Returns the <code>JScrollBar</code> object that handles horizontal scrolling.
0353             * @return the <code>JScrollBar</code> object that handles horizontal scrolling
0354             * @see JScrollPane#getHorizontalScrollBar
0355             */
0356            public JScrollBar getHorizontalScrollBar() {
0357                return hsb;
0358            }
0359
0360            /**
0361             * Returns the <code>JScrollBar</code> object that handles vertical scrolling.
0362             * @return the <code>JScrollBar</code> object that handles vertical scrolling
0363             * @see JScrollPane#getVerticalScrollBar
0364             */
0365            public JScrollBar getVerticalScrollBar() {
0366                return vsb;
0367            }
0368
0369            /**
0370             * Returns the <code>JViewport</code> object that is the row header.
0371             * @return the <code>JViewport</code> object that is the row header
0372             * @see JScrollPane#getRowHeader
0373             */
0374            public JViewport getRowHeader() {
0375                return rowHead;
0376            }
0377
0378            /**
0379             * Returns the <code>JViewport</code> object that is the column header.
0380             * @return the <code>JViewport</code> object that is the column header
0381             * @see JScrollPane#getColumnHeader
0382             */
0383            public JViewport getColumnHeader() {
0384                return colHead;
0385            }
0386
0387            /**
0388             * Returns the <code>Component</code> at the specified corner.
0389             * @param key the <code>String</code> specifying the corner
0390             * @return the <code>Component</code> at the specified corner, as defined in
0391             *         {@link ScrollPaneConstants}; if <code>key</code> is not one of the
0392             *		four corners, <code>null</code> is returned
0393             * @see JScrollPane#getCorner
0394             */
0395            public Component getCorner(String key) {
0396                if (key.equals(LOWER_LEFT_CORNER)) {
0397                    return lowerLeft;
0398                } else if (key.equals(LOWER_RIGHT_CORNER)) {
0399                    return lowerRight;
0400                } else if (key.equals(UPPER_LEFT_CORNER)) {
0401                    return upperLeft;
0402                } else if (key.equals(UPPER_RIGHT_CORNER)) {
0403                    return upperRight;
0404                } else {
0405                    return null;
0406                }
0407            }
0408
0409            /** 
0410             * The preferred size of a <code>ScrollPane</code> is the size of the insets,
0411             * plus the preferred size of the viewport, plus the preferred size of 
0412             * the visible headers, plus the preferred size of the scrollbars
0413             * that will appear given the current view and the current
0414             * scrollbar displayPolicies.  
0415             * <p>Note that the rowHeader is calculated as part of the preferred width
0416             * and the colHeader is calculated as part of the preferred size.
0417             * 
0418             * @param parent the <code>Container</code> that will be laid out
0419             * @return a <code>Dimension</code> object specifying the preferred size of the 
0420             *         viewport and any scrollbars
0421             * @see ViewportLayout
0422             * @see LayoutManager
0423             */
0424            public Dimension preferredLayoutSize(Container parent) {
0425                /* Sync the (now obsolete) policy fields with the
0426                 * JScrollPane.
0427                 */
0428                JScrollPane scrollPane = (JScrollPane) parent;
0429                vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
0430                hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
0431
0432                Insets insets = parent.getInsets();
0433                int prefWidth = insets.left + insets.right;
0434                int prefHeight = insets.top + insets.bottom;
0435
0436                /* Note that viewport.getViewSize() is equivalent to 
0437                 * viewport.getView().getPreferredSize() modulo a null
0438                 * view or a view whose size was explicitly set.
0439                 */
0440
0441                Dimension extentSize = null;
0442                Dimension viewSize = null;
0443                Component view = null;
0444
0445                if (viewport != null) {
0446                    extentSize = viewport.getPreferredSize();
0447                    viewSize = viewport.getViewSize();
0448                    view = viewport.getView();
0449                }
0450
0451                /* If there's a viewport add its preferredSize.
0452                 */
0453
0454                if (extentSize != null) {
0455                    prefWidth += extentSize.width;
0456                    prefHeight += extentSize.height;
0457                }
0458
0459                /* If there's a JScrollPane.viewportBorder, add its insets.
0460                 */
0461
0462                Border viewportBorder = scrollPane.getViewportBorder();
0463                if (viewportBorder != null) {
0464                    Insets vpbInsets = viewportBorder.getBorderInsets(parent);
0465                    prefWidth += vpbInsets.left + vpbInsets.right;
0466                    prefHeight += vpbInsets.top + vpbInsets.bottom;
0467                }
0468
0469                /* If a header exists and it's visible, factor its
0470                 * preferred size in.
0471                 */
0472
0473                if ((rowHead != null) && rowHead.isVisible()) {
0474                    prefWidth += rowHead.getPreferredSize().width;
0475                }
0476
0477                if ((colHead != null) && colHead.isVisible()) {
0478                    prefHeight += colHead.getPreferredSize().height;
0479                }
0480
0481                /* If a scrollbar is going to appear, factor its preferred size in.
0482                 * If the scrollbars policy is AS_NEEDED, this can be a little
0483                 * tricky:
0484                 * 
0485                 * - If the view is a Scrollable then scrollableTracksViewportWidth
0486                 * and scrollableTracksViewportHeight can be used to effectively 
0487                 * disable scrolling (if they're true) in their respective dimensions.
0488                 * 
0489                 * - Assuming that a scrollbar hasn't been disabled by the 
0490                 * previous constraint, we need to decide if the scrollbar is going 
0491                 * to appear to correctly compute the JScrollPanes preferred size.
0492                 * To do this we compare the preferredSize of the viewport (the 
0493                 * extentSize) to the preferredSize of the view.  Although we're
0494                 * not responsible for laying out the view we'll assume that the 
0495                 * JViewport will always give it its preferredSize.
0496                 */
0497
0498                if ((vsb != null) && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
0499                    if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
0500                        prefWidth += vsb.getPreferredSize().width;
0501                    } else if ((viewSize != null) && (extentSize != null)) {
0502                        boolean canScroll = true;
0503                        if (view instanceof  Scrollable) {
0504                            canScroll = !((Scrollable) view)
0505                                    .getScrollableTracksViewportHeight();
0506                        }
0507                        if (canScroll && (viewSize.height > extentSize.height)) {
0508                            prefWidth += vsb.getPreferredSize().width;
0509                        }
0510                    }
0511                }
0512
0513                if ((hsb != null) && (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)) {
0514                    if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
0515                        prefHeight += hsb.getPreferredSize().height;
0516                    } else if ((viewSize != null) && (extentSize != null)) {
0517                        boolean canScroll = true;
0518                        if (view instanceof  Scrollable) {
0519                            canScroll = !((Scrollable) view)
0520                                    .getScrollableTracksViewportWidth();
0521                        }
0522                        if (canScroll && (viewSize.width > extentSize.width)) {
0523                            prefHeight += hsb.getPreferredSize().height;
0524                        }
0525                    }
0526                }
0527
0528                return new Dimension(prefWidth, prefHeight);
0529            }
0530
0531            /** 
0532             * The minimum size of a <code>ScrollPane</code> is the size of the insets 
0533             * plus minimum size of the viewport, plus the scrollpane's
0534             * viewportBorder insets, plus the minimum size 
0535             * of the visible headers, plus the minimum size of the 
0536             * scrollbars whose displayPolicy isn't NEVER.
0537             * 
0538             * @param parent the <code>Container</code> that will be laid out
0539             * @return a <code>Dimension</code> object specifying the minimum size
0540             */
0541            public Dimension minimumLayoutSize(Container parent) {
0542                /* Sync the (now obsolete) policy fields with the
0543                 * JScrollPane.
0544                 */
0545                JScrollPane scrollPane = (JScrollPane) parent;
0546                vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
0547                hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
0548
0549                Insets insets = parent.getInsets();
0550                int minWidth = insets.left + insets.right;
0551                int minHeight = insets.top + insets.bottom;
0552
0553                /* If there's a viewport add its minimumSize.
0554                 */
0555
0556                if (viewport != null) {
0557                    Dimension size = viewport.getMinimumSize();
0558                    minWidth += size.width;
0559                    minHeight += size.height;
0560                }
0561
0562                /* If there's a JScrollPane.viewportBorder, add its insets.
0563                 */
0564
0565                Border viewportBorder = scrollPane.getViewportBorder();
0566                if (viewportBorder != null) {
0567                    Insets vpbInsets = viewportBorder.getBorderInsets(parent);
0568                    minWidth += vpbInsets.left + vpbInsets.right;
0569                    minHeight += vpbInsets.top + vpbInsets.bottom;
0570                }
0571
0572                /* If a header exists and it's visible, factor its
0573                 * minimum size in.
0574                 */
0575
0576                if ((rowHead != null) && rowHead.isVisible()) {
0577                    Dimension size = rowHead.getMinimumSize();
0578                    minWidth += size.width;
0579                    minHeight = Math.max(minHeight, size.height);
0580                }
0581
0582                if ((colHead != null) && colHead.isVisible()) {
0583                    Dimension size = colHead.getMinimumSize();
0584                    minWidth = Math.max(minWidth, size.width);
0585                    minHeight += size.height;
0586                }
0587
0588                /* If a scrollbar might appear, factor its minimum
0589                 * size in.
0590                 */
0591
0592                if ((vsb != null) && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
0593                    Dimension size = vsb.getMinimumSize();
0594                    minWidth += size.width;
0595                    minHeight = Math.max(minHeight, size.height);
0596                }
0597
0598                if ((hsb != null) && (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)) {
0599                    Dimension size = hsb.getMinimumSize();
0600                    minWidth = Math.max(minWidth, size.width);
0601                    minHeight += size.height;
0602                }
0603
0604                return new Dimension(minWidth, minHeight);
0605            }
0606
0607            /** 
0608             * Lays out the scrollpane. The positioning of components depends on
0609             * the following constraints:
0610             * <ul>
0611             * <li> The row header, if present and visible, gets its preferred
0612             * width and the viewport's height.
0613             * 
0614             * <li> The column header, if present and visible, gets its preferred
0615             * height and the viewport's width.
0616             * 
0617             * <li> If a vertical scrollbar is needed, i.e. if the viewport's extent
0618             * height is smaller than its view height or if the <code>displayPolicy</code>
0619             * is ALWAYS, it's treated like the row header with respect to its
0620             * dimensions and is made visible.
0621             * 
0622             * <li> If a horizontal scrollbar is needed, it is treated like the
0623             * column header (see the paragraph above regarding the vertical scrollbar).
0624             * 
0625             * <li> If the scrollpane has a non-<code>null</code>
0626             * <code>viewportBorder</code>, then space is allocated for that.
0627             * 
0628             * <li> The viewport gets the space available after accounting for
0629             * the previous constraints.
0630             * 
0631             * <li> The corner components, if provided, are aligned with the 
0632             * ends of the scrollbars and headers. If there is a vertical
0633             * scrollbar, the right corners appear; if there is a horizontal
0634             * scrollbar, the lower corners appear; a row header gets left
0635             * corners, and a column header gets upper corners.
0636             * </ul>
0637             *
0638             * @param parent the <code>Container</code> to lay out
0639             */
0640            public void layoutContainer(Container parent) {
0641                /* Sync the (now obsolete) policy fields with the
0642                 * JScrollPane.
0643                 */
0644                JScrollPane scrollPane = (JScrollPane) parent;
0645                vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
0646                hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
0647
0648                Rectangle availR = scrollPane.getBounds();
0649                availR.x = availR.y = 0;
0650
0651                Insets insets = parent.getInsets();
0652                availR.x = insets.left;
0653                availR.y = insets.top;
0654                availR.width -= insets.left + insets.right;
0655                availR.height -= insets.top + insets.bottom;
0656
0657                /* Get the scrollPane's orientation.
0658                 */
0659                boolean leftToRight = SwingUtilities.isLeftToRight(scrollPane);
0660
0661                /* If there's a visible column header remove the space it 
0662                 * needs from the top of availR.  The column header is treated 
0663                 * as if it were fixed height, arbitrary width.
0664                 */
0665
0666                Rectangle colHeadR = new Rectangle(0, availR.y, 0, 0);
0667
0668                if ((colHead != null) && (colHead.isVisible())) {
0669                    int colHeadHeight = Math.min(availR.height, colHead
0670                            .getPreferredSize().height);
0671                    colHeadR.height = colHeadHeight;
0672                    availR.y += colHeadHeight;
0673                    availR.height -= colHeadHeight;
0674                }
0675
0676                /* If there's a visible row header remove the space it needs
0677                 * from the left or right of availR.  The row header is treated 
0678                 * as if it were fixed width, arbitrary height.
0679                 */
0680
0681                Rectangle rowHeadR = new Rectangle(0, 0, 0, 0);
0682
0683                if ((rowHead != null) && (rowHead.isVisible())) {
0684                    int rowHeadWidth = Math.min(availR.width, rowHead
0685                            .getPreferredSize().width);
0686                    rowHeadR.width = rowHeadWidth;
0687                    availR.width -= rowHeadWidth;
0688                    if (leftToRight) {
0689                        rowHeadR.x = availR.x;
0690                        availR.x += rowHeadWidth;
0691                    } else {
0692                        rowHeadR.x = availR.x + availR.width;
0693                    }
0694                }
0695
0696                /* If there's a JScrollPane.viewportBorder, remove the
0697                 * space it occupies for availR.
0698                 */
0699
0700                Border viewportBorder = scrollPane.getViewportBorder();
0701                Insets vpbInsets;
0702                if (viewportBorder != null) {
0703                    vpbInsets = viewportBorder.getBorderInsets(parent);
0704                    availR.x += vpbInsets.left;
0705                    availR.y += vpbInsets.top;
0706                    availR.width -= vpbInsets.left + vpbInsets.right;
0707                    availR.height -= vpbInsets.top + vpbInsets.bottom;
0708                } else {
0709                    vpbInsets = new Insets(0, 0, 0, 0);
0710                }
0711
0712                /* At this point availR is the space available for the viewport
0713                 * and scrollbars. rowHeadR is correct except for its height and y
0714                 * and colHeadR is correct except for its width and x.  Once we're 
0715                 * through computing the dimensions  of these three parts we can 
0716                 * go back and set the dimensions of rowHeadR.height, rowHeadR.y,
0717                 * colHeadR.width, colHeadR.x and the bounds for the corners.
0718                 * 
0719                 * We'll decide about putting up scrollbars by comparing the 
0720                 * viewport views preferred size with the viewports extent
0721                 * size (generally just its size).  Using the preferredSize is
0722                 * reasonable because layout proceeds top down - so we expect
0723                 * the viewport to be laid out next.  And we assume that the
0724                 * viewports layout manager will give the view it's preferred
0725                 * size.  One exception to this is when the view implements 
0726                 * Scrollable and Scrollable.getViewTracksViewport{Width,Height}
0727                 * methods return true.  If the view is tracking the viewports
0728                 * width we don't bother with a horizontal scrollbar, similarly
0729                 * if view.getViewTracksViewport(Height) is true we don't bother
0730                 * with a vertical scrollbar.
0731                 */
0732
0733                Component view = (viewport != null) ? viewport.getView() : null;
0734                Dimension viewPrefSize = (view != null) ? view
0735                        .getPreferredSize() : new Dimension(0, 0);
0736
0737                Dimension extentSize = (viewport != null) ? viewport
0738                        .toViewCoordinates(availR.getSize()) : new Dimension(0,
0739                        0);
0740
0741                boolean viewTracksViewportWidth = false;
0742                boolean viewTracksViewportHeight = false;
0743                boolean isEmpty = (availR.width < 0 || availR.height < 0);
0744                Scrollable sv;
0745                // Don't bother checking the Scrollable methods if there is no room
0746                // for the viewport, we aren't going to show any scrollbars in this
0747                // case anyway.
0748                if (!isEmpty && view instanceof  Scrollable) {
0749                    sv = (Scrollable) view;
0750                    viewTracksViewportWidth = sv
0751                            .getScrollableTracksViewportWidth();
0752                    viewTracksViewportHeight = sv
0753                            .getScrollableTracksViewportHeight();
0754                } else {
0755                    sv = null;
0756                }
0757
0758                /* If there's a vertical scrollbar and we need one, allocate
0759                 * space for it (we'll make it visible later). A vertical 
0760                 * scrollbar is considered to be fixed width, arbitrary height.
0761                 */
0762
0763                Rectangle vsbR = new Rectangle(0, availR.y - vpbInsets.top, 0,
0764                        0);
0765
0766                boolean vsbNeeded;
0767                if (isEmpty) {
0768                    vsbNeeded = false;
0769                } else if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
0770                    vsbNeeded = true;
0771                } else if (vsbPolicy == VERTICAL_SCROLLBAR_NEVER) {
0772                    vsbNeeded = false;
0773                } else { // vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED
0774                    vsbNeeded = !viewTracksViewportHeight
0775                            && (viewPrefSize.height > extentSize.height);
0776                }
0777
0778                if ((vsb != null) && vsbNeeded) {
0779                    adjustForVSB(true, availR, vsbR, vpbInsets, leftToRight);
0780                    extentSize = viewport.toViewCoordinates(availR.getSize());
0781                }
0782
0783                /* If there's a horizontal scrollbar and we need one, allocate
0784                 * space for it (we'll make it visible later). A horizontal 
0785                 * scrollbar is considered to be fixed height, arbitrary width.
0786                 */
0787
0788                Rectangle hsbR = new Rectangle(availR.x - vpbInsets.left, 0, 0,
0789                        0);
0790                boolean hsbNeeded;
0791                if (isEmpty) {
0792                    hsbNeeded = false;
0793                } else if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
0794                    hsbNeeded = true;
0795                } else if (hsbPolicy == HORIZONTAL_SCROLLBAR_NEVER) {
0796                    hsbNeeded = false;
0797                } else { // hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED
0798                    hsbNeeded = !viewTracksViewportWidth
0799                            && (viewPrefSize.width > extentSize.width);
0800                }
0801
0802                if ((hsb != null) && hsbNeeded) {
0803                    adjustForHSB(true, availR, hsbR, vpbInsets);
0804
0805                    /* If we added the horizontal scrollbar then we've implicitly 
0806                     * reduced  the vertical space available to the viewport. 
0807                     * As a consequence we may have to add the vertical scrollbar, 
0808                     * if that hasn't been done so already.  Of course we
0809                     * don't bother with any of this if the vsbPolicy is NEVER.
0810                     */
0811                    if ((vsb != null) && !vsbNeeded
0812                            && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
0813
0814                        extentSize = viewport.toViewCoordinates(availR
0815                                .getSize());
0816                        vsbNeeded = viewPrefSize.height > extentSize.height;
0817
0818                        if (vsbNeeded) {
0819                            adjustForVSB(true, availR, vsbR, vpbInsets,
0820                                    leftToRight);
0821                        }
0822                    }
0823                }
0824
0825                /* Set the size of the viewport first, and then recheck the Scrollable
0826                 * methods. Some components base their return values for the Scrollable
0827                 * methods on the size of the Viewport, so that if we don't
0828                 * ask after resetting the bounds we may have gotten the wrong
0829                 * answer.
0830                 */
0831
0832                if (viewport != null) {
0833                    viewport.setBounds(availR);
0834
0835                    if (sv != null) {
0836                        extentSize = viewport.toViewCoordinates(availR
0837                                .getSize());
0838
0839                        boolean oldHSBNeeded = hsbNeeded;
0840                        boolean oldVSBNeeded = vsbNeeded;
0841                        viewTracksViewportWidth = sv
0842                                .getScrollableTracksViewportWidth();
0843                        viewTracksViewportHeight = sv
0844                                .getScrollableTracksViewportHeight();
0845                        if (vsb != null
0846                                && vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED) {
0847                            boolean newVSBNeeded = !viewTracksViewportHeight
0848                                    && (viewPrefSize.height > extentSize.height);
0849                            if (newVSBNeeded != vsbNeeded) {
0850                                vsbNeeded = newVSBNeeded;
0851                                adjustForVSB(vsbNeeded, availR, vsbR,
0852                                        vpbInsets, leftToRight);
0853                                extentSize = viewport.toViewCoordinates(availR
0854                                        .getSize());
0855                            }
0856                        }
0857                        if (hsb != null
0858                                && hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED) {
0859                            boolean newHSBbNeeded = !viewTracksViewportWidth
0860                                    && (viewPrefSize.width > extentSize.width);
0861                            if (newHSBbNeeded != hsbNeeded) {
0862                                hsbNeeded = newHSBbNeeded;
0863                                adjustForHSB(hsbNeeded, availR, hsbR, vpbInsets);
0864                                if ((vsb != null)
0865                                        && !vsbNeeded
0866                                        && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
0867
0868                                    extentSize = viewport
0869                                            .toViewCoordinates(availR.getSize());
0870                                    vsbNeeded = viewPrefSize.height > extentSize.height;
0871
0872                                    if (vsbNeeded) {
0873                                        adjustForVSB(true, availR, vsbR,
0874                                                vpbInsets, leftToRight);
0875                                    }
0876                                }
0877                            }
0878                        }
0879                        if (oldHSBNeeded != hsbNeeded
0880                                || oldVSBNeeded != vsbNeeded) {
0881                            viewport.setBounds(availR);
0882                            // You could argue that we should recheck the
0883                            // Scrollable methods again until they stop changing,
0884                            // but they might never stop changing, so we stop here
0885                            // and don't do any additional checks.
0886                        }
0887                    }
0888                }
0889
0890                /* We now have the final size of the viewport: availR.
0891                 * Now fixup the header and scrollbar widths/heights.
0892                 */
0893                vsbR.height = availR.height + vpbInsets.top + vpbInsets.bottom;
0894                hsbR.width = availR.width + vpbInsets.left + vpbInsets.right;
0895                rowHeadR.height = availR.height + vpbInsets.top
0896                        + vpbInsets.bottom;
0897                rowHeadR.y = availR.y - vpbInsets.top;
0898                colHeadR.width = availR.width + vpbInsets.left
0899                        + vpbInsets.right;
0900                colHeadR.x = availR.x - vpbInsets.left;
0901
0902                /* Set the bounds of the remaining components.  The scrollbars
0903                 * are made invisible if they're not needed.
0904                 */
0905
0906                if (rowHead != null) {
0907                    rowHead.setBounds(rowHeadR);
0908                }
0909
0910                if (colHead != null) {
0911                    colHead.setBounds(colHeadR);
0912                }
0913
0914                if (vsb != null) {
0915                    if (vsbNeeded) {
0916                        if (colHead != null
0917                                && UIManager
0918                                        .getBoolean("ScrollPane.fillUpperCorner")) {
0919                            if ((leftToRight && upperRight == null)
0920                                    || (!leftToRight && upperLeft == null)) {
0921                                // This is used primarily for GTK L&F, which needs to
0922                                // extend the vertical scrollbar to fill the upper
0923                                // corner near the column header.  Note that we skip
0924                                // this step (and use the default behavior) if the
0925                                // user has set a custom corner component.
0926                                vsbR.y = colHeadR.y;
0927                                vsbR.height += colHeadR.height;
0928                            }
0929                        }
0930                        vsb.setVisible(true);
0931                        vsb.setBounds(vsbR);
0932                    } else {
0933                        vsb.setVisible(false);
0934                    }
0935                }
0936
0937                if (hsb != null) {
0938                    if (hsbNeeded) {
0939                        if (rowHead != null
0940                                && UIManager
0941                                        .getBoolean("ScrollPane.fillLowerCorner")) {
0942                            if ((leftToRight && lowerLeft == null)
0943                                    || (!leftToRight && lowerRight == null)) {
0944                                // This is used primarily for GTK L&F, which needs to
0945                                // extend the horizontal scrollbar to fill the lower
0946                                // corner near the row header.  Note that we skip
0947                                // this step (and use the default behavior) if the
0948                                // user has set a custom corner component.
0949                                if (leftToRight) {
0950                                    hsbR.x = rowHeadR.x;
0951                                }
0952                                hsbR.width += rowHeadR.width;
0953                            }
0954                        }
0955                        hsb.setVisible(true);
0956                        hsb.setBounds(hsbR);
0957                    } else {
0958                        hsb.setVisible(false);
0959                    }
0960                }
0961
0962                if (lowerLeft != null) {
0963                    lowerLeft.setBounds(leftToRight ? rowHeadR.x : vsbR.x,
0964                            hsbR.y, leftToRight ? rowHeadR.width : vsbR.width,
0965                            hsbR.height);
0966                }
0967
0968                if (lowerRight != null) {
0969                    lowerRight.setBounds(leftToRight ? vsbR.x : rowHeadR.x,
0970                            hsbR.y, leftToRight ? vsbR.width : rowHeadR.width,
0971                            hsbR.height);
0972                }
0973
0974                if (upperLeft != null) {
0975                    upperLeft.setBounds(leftToRight ? rowHeadR.x : vsbR.x,
0976                            colHeadR.y, leftToRight ? rowHeadR.width
0977                                    : vsbR.width, colHeadR.height);
0978                }
0979
0980                if (upperRight != null) {
0981                    upperRight.setBounds(leftToRight ? vsbR.x : rowHeadR.x,
0982                            colHeadR.y, leftToRight ? vsbR.width
0983                                    : rowHeadR.width, colHeadR.height);
0984                }
0985            }
0986
0987            /**
0988             * Adjusts the <code>Rectangle</code> <code>available</code> based on if
0989             * the vertical scrollbar is needed (<code>wantsVSB</code>).
0990             * The location of the vsb is updated in <code>vsbR</code>, and
0991             * the viewport border insets (<code>vpbInsets</code>) are used to offset
0992             * the vsb. This is only called when <code>wantsVSB</code> has
0993             * changed, eg you shouldn't invoke adjustForVSB(true) twice.
0994             */
0995            private void adjustForVSB(boolean wantsVSB, Rectangle available,
0996                    Rectangle vsbR, Insets vpbInsets, boolean leftToRight) {
0997                int oldWidth = vsbR.width;
0998                if (wantsVSB) {
0999                    int vsbWidth = Math.max(0, Math.min(
1000                            vsb.getPreferredSize().width, available.width));
1001
1002                    available.width -= vsbWidth;
1003                    vsbR.width = vsbWidth;
1004
1005                    if (leftToRight) {
1006                        vsbR.x = available.x + available.width
1007                                + vpbInsets.right;
1008                    } else {
1009                        vsbR.x = available.x - vpbInsets.left;
1010                        available.x += vsbWidth;
1011                    }
1012                } else {
1013                    available.width += oldWidth;
1014                }
1015            }
1016
1017            /**
1018             * Adjusts the <code>Rectangle</code> <code>available</code> based on if
1019             * the horizontal scrollbar is needed (<code>wantsHSB</code>).
1020             * The location of the hsb is updated in <code>hsbR</code>, and
1021             * the viewport border insets (<code>vpbInsets</code>) are used to offset
1022             * the hsb.  This is only called when <code>wantsHSB</code> has
1023             * changed, eg you shouldn't invoked adjustForHSB(true) twice.
1024             */
1025            private void adjustForHSB(boolean wantsHSB, Rectangle available,
1026                    Rectangle hsbR, Insets vpbInsets) {
1027                int oldHeight = hsbR.height;
1028                if (wantsHSB) {
1029                    int hsbHeight = Math.max(0, Math.min(available.height, hsb
1030                            .getPreferredSize().height));
1031
1032                    available.height -= hsbHeight;
1033                    hsbR.y = available.y + available.height + vpbInsets.bottom;
1034                    hsbR.height = hsbHeight;
1035                } else {
1036                    available.height += oldHeight;
1037                }
1038            }
1039
1040            /** 
1041             * Returns the bounds of the border around the specified scroll pane's 
1042             * viewport.
1043             *
1044             * @return the size and position of the viewport border
1045             * @deprecated As of JDK version Swing1.1
1046             *    replaced by <code>JScrollPane.getViewportBorderBounds()</code>.
1047             */
1048            @Deprecated
1049            public Rectangle getViewportBorderBounds(JScrollPane scrollpane) {
1050                return scrollpane.getViewportBorderBounds();
1051            }
1052
1053            /**
1054             * The UI resource version of <code>ScrollPaneLayout</code>.
1055             */
1056            public static class UIResource extends ScrollPaneLayout implements 
1057                    javax.swing.plaf.UIResource {
1058            }
1059        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.