001    /* ========================================================================
002     * JCommon : a free general purpose class library for the Java(tm) platform
003     * ========================================================================
004     *
005     * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006     * 
007     * Project Info:  http://www.jfree.org/jcommon/index.html
008     *
009     * This library is free software; you can redistribute it and/or modify it 
010     * under the terms of the GNU Lesser General Public License as published by 
011     * the Free Software Foundation; either version 2.1 of the License, or 
012     * (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but 
015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
017     * License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
022     * USA.  
023     *
024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
025     * in the United States and other countries.]
026     *
027     * -------------------
028     * VerticalLayout.java
029     * -------------------
030     * (C)opyright 2003, by Thomas Morgner and Contributors.
031     *
032     * Original Author:  Thomas Morgner;
033     * Contributor(s):   David Gilbert (for Simba Management Limited);
034     *
035     * $Id: VerticalLayout.java,v 1.2 2005/10/18 13:23:37 mungady Exp $
036     *
037     * Changes 
038     * -------------------------
039     * 31.08.2003 : Initial version
040     *  
041     */
042    
043    package org.jfree.ui.tabbedui;
044    
045    import java.awt.Component;
046    import java.awt.Container;
047    import java.awt.Dimension;
048    import java.awt.Insets;
049    import java.awt.LayoutManager;
050    import java.awt.Rectangle;
051    
052    /**
053     * A simple layout manager, which aligns all components in a vertical
054     * flow layout.
055     * 
056     * @author Thomas Morgner
057     */
058    public class VerticalLayout implements LayoutManager {
059        
060        /**
061         * Defines, whether to use the parents size or whether to compute
062         * the size from the parent's childs during the layouting.
063         */
064        private final boolean useSizeFromParent;
065    
066        /**
067         * DefaultConstructor.
068         */
069        public VerticalLayout() {
070            this(true);
071        }
072    
073        /**
074         * Creates a new vertical layout. If useParent is set to true,
075         * the parents size will be used when performing the layouting,
076         * else only the parents childs are used to compute the layout.
077         *
078         * @param useParent defines, whether the parent's size is used.
079         */
080        public VerticalLayout(final boolean useParent) {
081            this.useSizeFromParent = useParent;
082        }
083    
084        /**
085         * Adds the specified component with the specified name to
086         * the layout.
087         *
088         * @param name the component name
089         * @param comp the component to be added
090         */
091        public void addLayoutComponent(final String name, final Component comp) {
092            // ignored
093        }
094    
095        /**
096         * Removes the specified component from the layout.
097         *
098         * @param comp the component to be removed
099         */
100        public void removeLayoutComponent(final Component comp) {
101            // ignored
102        }
103    
104        /**
105         * Calculates the preferred size dimensions for the specified
106         * panel given the components in the specified parent container.
107         *
108         * @param parent the component to be laid out
109         * @return the preferred layout size
110         * @see #minimumLayoutSize
111         */
112        public Dimension preferredLayoutSize(final Container parent) {
113            synchronized (parent.getTreeLock()) {
114                final Insets ins = parent.getInsets();
115                final Component[] comps = parent.getComponents();
116                int height = ins.top + ins.bottom;
117                int width = ins.left + ins.right;
118                for (int i = 0; i < comps.length; i++) {
119                    if (comps[i].isVisible() == false) {
120                        continue;
121                    }
122                    final Dimension pref = comps[i].getPreferredSize();
123                    height += pref.height;
124                    if (pref.width > width) {
125                        width = pref.width;
126                    }
127                }
128    
129                return new Dimension(width + ins.left + ins.right,
130                    height + ins.top + ins.bottom);
131            }
132        }
133    
134        /**
135         * Calculates the minimum size dimensions for the specified
136         * panel given the components in the specified parent container.
137         *
138         * @param parent the component to be laid out
139         * @return the minimul layoutsize
140         * @see #preferredLayoutSize
141         */
142        public Dimension minimumLayoutSize(final Container parent) {
143            synchronized (parent.getTreeLock()) {
144                final Insets ins = parent.getInsets();
145                final Component[] comps = parent.getComponents();
146                int height = ins.top + ins.bottom;
147                int width = ins.left + ins.right;
148                for (int i = 0; i < comps.length; i++) {
149                    if (comps[i].isVisible() == false) {
150                        continue;
151                    }
152                    final Dimension min = comps[i].getMinimumSize();
153                    height += min.height;
154                    if (min.width > width) {
155                        width = min.width;
156                    }
157                }
158                return new Dimension(width + ins.left + ins.right,
159                    height + ins.top + ins.bottom);
160            }
161        }
162    
163        /**
164         * Returns, whether the parent's defined size is used during the layouting,
165         * or whether the childs are used to compute the size.
166         *
167         * @return true, if the parent's size is used, false otherwise.
168         */
169        public boolean isUseSizeFromParent() {
170            return this.useSizeFromParent;
171        }
172    
173        /**
174         * Lays out the container in the specified panel.
175         *
176         * @param parent the component which needs to be laid out
177         */
178        public void layoutContainer(final Container parent) {
179            synchronized (parent.getTreeLock()) {
180                final Insets ins = parent.getInsets();
181                final int insHorizontal = ins.left + ins.right;
182    
183                final int width;
184                if (isUseSizeFromParent()) {
185                    final Rectangle bounds = parent.getBounds();
186                    width = bounds.width - insHorizontal;
187                }
188                else {
189                    width = preferredLayoutSize(parent).width - insHorizontal;
190                }
191                final Component[] comps = parent.getComponents();
192    
193                int y = ins.top;
194                for (int i = 0; i < comps.length; i++) {
195                    final Component c = comps[i];
196                    if (c.isVisible() == false) {
197                        continue;
198                    }
199                    final Dimension dim = c.getPreferredSize();
200                    c.setBounds(ins.left, y, width, dim.height);
201                    y += dim.height;
202                }
203            }
204        }
205    }