View Javadoc
1   package se.perfectfools.localizer.gui;
2   
3   import java.awt.Component;
4   import java.awt.Container;
5   
6   import javax.swing.Spring;
7   import javax.swing.SpringLayout;
8   
9   /***
10   * A 1.4 file that provides utility methods for creating form- or grid-style
11   * layouts with SpringLayout. These utilities are used by several programs, such
12   * as SpringBox and SpringCompactGrid.
13   */
14  public class SpringUtilities {
15  	/***
16  	 * A debugging utility that prints to stdout the component's minimum,
17  	 * preferred, and maximum sizes.
18  	 */
19  	public static void printSizes(Component c) {
20  		System.out.println("minimumSize = " + c.getMinimumSize());
21  		System.out.println("preferredSize = " + c.getPreferredSize());
22  		System.out.println("maximumSize = " + c.getMaximumSize());
23  	}
24  
25  	/***
26  	 * Aligns the first <code>rows</code>*<code>cols</code> components of
27  	 * <code>parent</code> in a grid. Each component is as big as the maximum
28  	 * preferred width and height of the components. The parent is made just big
29  	 * enough to fit them all.
30  	 * 
31  	 * @param rows
32  	 *            number of rows
33  	 * @param cols
34  	 *            number of columns
35  	 * @param initialX
36  	 *            x location to start the grid at
37  	 * @param initialY
38  	 *            y location to start the grid at
39  	 * @param xPad
40  	 *            x padding between cells
41  	 * @param yPad
42  	 *            y padding between cells
43  	 */
44  	public static void makeGrid(Container parent, int rows, int cols,
45  			int initialX, int initialY, int xPad, int yPad) {
46  		SpringLayout layout;
47  		try {
48  			layout = (SpringLayout) parent.getLayout();
49  		} catch (ClassCastException exc) {
50  			System.err
51  					.println("The first argument to makeGrid must use SpringLayout.");
52  			return;
53  		}
54  
55  		Spring xPadSpring = Spring.constant(xPad);
56  		Spring yPadSpring = Spring.constant(yPad);
57  		Spring initialXSpring = Spring.constant(initialX);
58  		Spring initialYSpring = Spring.constant(initialY);
59  		int max = rows * cols;
60  
61  		//Calculate Springs that are the max of the width/height so that all
62  		//cells have the same size.
63  		Spring maxWidthSpring = layout.getConstraints(parent.getComponent(0))
64  				.getWidth();
65  		Spring maxHeightSpring = layout.getConstraints(parent.getComponent(0))
66  				.getWidth();
67  		for (int i = 1; i < max; i++) {
68  			SpringLayout.Constraints cons = layout.getConstraints(parent
69  					.getComponent(i));
70  
71  			maxWidthSpring = Spring.max(maxWidthSpring, cons.getWidth());
72  			maxHeightSpring = Spring.max(maxHeightSpring, cons.getHeight());
73  		}
74  
75  		//Apply the new width/height Spring. This forces all the
76  		//components to have the same size.
77  		for (int i = 0; i < max; i++) {
78  			SpringLayout.Constraints cons = layout.getConstraints(parent
79  					.getComponent(i));
80  
81  			cons.setWidth(maxWidthSpring);
82  			cons.setHeight(maxHeightSpring);
83  		}
84  
85  		//Then adjust the x/y constraints of all the cells so that they
86  		//are aligned in a grid.
87  		SpringLayout.Constraints lastCons = null;
88  		SpringLayout.Constraints lastRowCons = null;
89  		for (int i = 0; i < max; i++) {
90  			SpringLayout.Constraints cons = layout.getConstraints(parent
91  					.getComponent(i));
92  			if (i % cols == 0) { //start of new row
93  				lastRowCons = lastCons;
94  				cons.setX(initialXSpring);
95  			} else { //x position depends on previous component
96  				cons.setX(Spring.sum(lastCons.getConstraint(SpringLayout.EAST),
97  						xPadSpring));
98  			}
99  
100 			if (i / cols == 0) { //first row
101 				cons.setY(initialYSpring);
102 			} else { //y position depends on previous row
103 				cons.setY(Spring.sum(lastRowCons
104 						.getConstraint(SpringLayout.SOUTH), yPadSpring));
105 			}
106 			lastCons = cons;
107 		}
108 
109 		//Set the parent's size.
110 		SpringLayout.Constraints pCons = layout.getConstraints(parent);
111 		pCons.setConstraint(SpringLayout.SOUTH, Spring.sum(Spring
112 				.constant(yPad), lastCons.getConstraint(SpringLayout.SOUTH)));
113 		pCons.setConstraint(SpringLayout.EAST, Spring.sum(
114 				Spring.constant(xPad), lastCons
115 						.getConstraint(SpringLayout.EAST)));
116 	}
117 
118 	/* Used by makeCompactGrid. */
119 	private static SpringLayout.Constraints getConstraintsForCell(int row,
120 			int col, Container parent, int cols) {
121 		SpringLayout layout = (SpringLayout) parent.getLayout();
122 		Component c = parent.getComponent(row * cols + col);
123 		return layout.getConstraints(c);
124 	}
125 
126 	/***
127 	 * Aligns the first <code>rows</code>*<code>cols</code> components of
128 	 * <code>parent</code> in a grid. Each component in a column is as wide as
129 	 * the maximum preferred width of the components in that column; height is
130 	 * similarly determined for each row. The parent is made just big enough to
131 	 * fit them all.
132 	 * 
133 	 * @param rows
134 	 *            number of rows
135 	 * @param cols
136 	 *            number of columns
137 	 * @param initialX
138 	 *            x location to start the grid at
139 	 * @param initialY
140 	 *            y location to start the grid at
141 	 * @param xPad
142 	 *            x padding between cells
143 	 * @param yPad
144 	 *            y padding between cells
145 	 */
146 	public static void makeCompactGrid(Container parent, int rows, int cols,
147 			int initialX, int initialY, int xPad, int yPad) {
148 		SpringLayout layout;
149 		try {
150 			layout = (SpringLayout) parent.getLayout();
151 		} catch (ClassCastException exc) {
152 			System.err
153 					.println("The first argument to makeCompactGrid must use SpringLayout.");
154 			return;
155 		}
156 
157 		//Align all cells in each column and make them the same width.
158 		Spring x = Spring.constant(initialX);
159 		for (int c = 0; c < cols; c++) {
160 			Spring width = Spring.constant(0);
161 			for (int r = 0; r < rows; r++) {
162 				width = Spring.max(width, getConstraintsForCell(r, c, parent,
163 						cols).getWidth());
164 			}
165 			for (int r = 0; r < rows; r++) {
166 				SpringLayout.Constraints constraints = getConstraintsForCell(r,
167 						c, parent, cols);
168 				constraints.setX(x);
169 				constraints.setWidth(width);
170 			}
171 			x = Spring.sum(x, Spring.sum(width, Spring.constant(xPad)));
172 		}
173 
174 		//Align all cells in each row and make them the same height.
175 		Spring y = Spring.constant(initialY);
176 		for (int r = 0; r < rows; r++) {
177 			Spring height = Spring.constant(0);
178 			for (int c = 0; c < cols; c++) {
179 				height = Spring.max(height, getConstraintsForCell(r, c, parent,
180 						cols).getHeight());
181 			}
182 			for (int c = 0; c < cols; c++) {
183 				SpringLayout.Constraints constraints = getConstraintsForCell(r,
184 						c, parent, cols);
185 				constraints.setY(y);
186 				constraints.setHeight(height);
187 			}
188 			y = Spring.sum(y, Spring.sum(height, Spring.constant(yPad)));
189 		}
190 
191 		//Set the parent's size.
192 		SpringLayout.Constraints pCons = layout.getConstraints(parent);
193 		pCons.setConstraint(SpringLayout.SOUTH, y);
194 		pCons.setConstraint(SpringLayout.EAST, x);
195 	}
196 }