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
043package org.jfree.ui.tabbedui;
044
045import java.awt.Component;
046import java.awt.Container;
047import java.awt.Dimension;
048import java.awt.Insets;
049import java.awt.LayoutManager;
050import 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 */
058public 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}