View Javadoc

1   /*
2    * Created on Oct 24, 2004 
3    * Original filename was FlowLayoutVertical.java
4    * 
5    *   Magic-Project is a turn based strategy simulator
6    *   Copyright (C) 2003-2007 Fabrice Daugan
7    *
8    *   This program is free software; you can redistribute it and/or modify it 
9    * under the terms of the GNU General Public License as published by the Free 
10   * Software Foundation; either version 2 of the License, or (at your option) any
11   * later version.
12   *
13   *   This program is distributed in the hope that it will be useful, but WITHOUT 
14   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
16   * details.
17   *
18   *   You should have received a copy of the GNU General Public License along  
19   * with this program; if not, write to the Free Software Foundation, Inc., 
20   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21   * 
22   */
23  package net.sf.magicproject.ui.layout;
24  
25  import java.awt.Component;
26  import java.awt.Container;
27  import java.awt.Dimension;
28  import java.awt.Insets;
29  import java.awt.LayoutManager;
30  
31  /***
32   * A flow layout arranges components in a directional flow, much like lines of
33   * text in a paragraph. The flow direction is determined by the container's
34   * <code>componentOrientation</code> property and may be one of two values:
35   * <ul>
36   * <li><code>ComponentOrientation.LEFT_TO_RIGHT</code>
37   * <li><code>ComponentOrientation.RIGHT_TO_LEFT</code>
38   * </ul>
39   * Flow layouts are typically used to arrange buttons in a panel. It arranges
40   * buttons horizontally until no more buttons fit on the same line.
41   * <p>
42   * A flow layout lets each component assume its natural (preferred) size.
43   * 
44   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
45   * @since 0.80
46   */
47  public class FlowLayoutVertical implements LayoutManager {
48  
49  	/***
50  	 * Constructs a new <code>FlowLayout</code> with a centered alignment and a
51  	 * default 5-unit horizontal and vertical gap.
52  	 * 
53  	 * @param preferredHeight
54  	 *          the preferred height of this layout.
55  	 */
56  	public FlowLayoutVertical(int preferredHeight) {
57  		this(5, 5, preferredHeight);
58  	}
59  
60  	/***
61  	 * Constructs a new <code>FlowLayout</code> with a centered alignment and a
62  	 * default 5-unit horizontal and vertical gap.
63  	 */
64  	public FlowLayoutVertical() {
65  		this(5, 5, 0);
66  	}
67  
68  	/***
69  	 * Creates a new flow layout manager with the indicated horizontal and
70  	 * vertical gaps.
71  	 * <p>
72  	 * 
73  	 * @param hgap
74  	 *          the horizontal gap between components and between the components
75  	 *          and the borders of the <code>Container</code>
76  	 * @param vgap
77  	 *          the vertical gap between components and between the components and
78  	 *          the borders of the <code>Container</code>
79  	 * @param preferredHeight
80  	 *          the preferred height of this layout.
81  	 */
82  	public FlowLayoutVertical(int hgap, int vgap, int preferredHeight) {
83  		this.hgap = hgap;
84  		this.vgap = vgap;
85  		// this.preferredHeight = preferredHeight;
86  	}
87  
88  	public void addLayoutComponent(String name, Component comp) {
89  		// Ignore this event
90  	}
91  
92  	public void removeLayoutComponent(Component comp) {
93  		// Ignore this event
94  	}
95  
96  	public Dimension preferredLayoutSize(Container target) {
97  		synchronized (target.getTreeLock()) {
98  			// Dimension dim = new Dimension(hgap * 2, preferredHeight);
99  			Dimension dim = new Dimension(hgap * 2, target.getSize().height);
100 			int nmembers = target.getComponentCount();
101 			int height = 0;
102 			int maxheight = target.getHeight() - vgap * 2;
103 			int tmpMaxWidth = 0;
104 
105 			for (int i = 0; i < nmembers; i++) {
106 				Component m = target.getComponent(i);
107 				if (m.isVisible()) {
108 					Dimension d = m.getPreferredSize();
109 					height += d.height;
110 					if (height > maxheight) {
111 						height = d.height;
112 						dim.width += tmpMaxWidth + vgap;
113 						tmpMaxWidth = 0;
114 					}
115 					tmpMaxWidth = Math.max(tmpMaxWidth, d.width);
116 					height += vgap;
117 				}
118 			}
119 			dim.width += tmpMaxWidth;
120 			return dim;
121 		}
122 	}
123 
124 	public Dimension minimumLayoutSize(Container target) {
125 		synchronized (target.getTreeLock()) {
126 			Insets insets = target.getInsets();
127 			Dimension dim = new Dimension(insets.left + insets.right + hgap * 2,
128 					insets.top + insets.bottom + vgap * 2);
129 			int nmembers = target.getComponentCount();
130 			int tmpMaxHeight = 0;
131 			int tmpMaxwidth = 0;
132 
133 			for (int i = 0; i < nmembers; i++) {
134 				Component m = target.getComponent(i);
135 				if (m.isVisible()) {
136 					Dimension d = m.getMinimumSize();
137 					tmpMaxHeight = Math.max(tmpMaxHeight, d.height);
138 					tmpMaxwidth += d.width + hgap;
139 				}
140 			}
141 			dim.height += tmpMaxHeight;
142 			dim.width += tmpMaxwidth;
143 			return dim;
144 		}
145 	}
146 
147 	public void layoutContainer(Container target) {
148 		synchronized (target.getTreeLock()) {
149 			Insets insets = target.getInsets();
150 			int maxheight = target.getHeight()
151 					- (insets.top + insets.bottom + vgap * 2);
152 			int nmembers = target.getComponentCount();
153 			int x = 0;
154 			int y = 0;
155 			int roww = 0;
156 
157 			for (int i = 0; i < nmembers; i++) {
158 				Component m = target.getComponent(i);
159 				if (m.isVisible()) {
160 					Dimension d = m.getPreferredSize();
161 					m.setSize(d.width, d.height);
162 
163 					if (y + d.height <= maxheight || y == 0) {
164 						m.setLocation(x, y);
165 						y += d.height + vgap;
166 						roww = Math.max(roww, d.width);
167 					} else {
168 						x += hgap + roww;
169 						m.setLocation(x, 0);
170 						y = d.height + vgap;
171 						roww = d.width;
172 					}
173 				}
174 			}
175 		}
176 	}
177 
178 	/***
179 	 * The flow layout manager allows a seperation of components with gaps. The
180 	 * horizontal gap will specify the space between components and between the
181 	 * components and the borders of the <code>Container</code>.
182 	 * 
183 	 * @serial
184 	 */
185 	protected int hgap;
186 
187 	/***
188 	 * The flow layout manager allows a seperation of components with gaps. The
189 	 * vertical gap will specify the space between rows and between the the rows
190 	 * and the borders of the <code>Container</code>.
191 	 * 
192 	 * @serial
193 	 */
194 	protected int vgap;
195 
196 }