001    /*
002     * Copyright 2002-2004 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy
006     * of the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations
014     * under the License.
015     */
016    package org.springframework.richclient.util;
017    
018    import java.awt.Component;
019    import java.awt.Container;
020    
021    import javax.swing.JPanel;
022    import javax.swing.Spring;
023    import javax.swing.SpringLayout;
024    
025    import org.springframework.richclient.core.UIConstants;
026    
027    /**
028     * A 1.4 file that provides utility methods for creating form- or grid-style
029     * layouts with SpringLayout. These utilities are used by several programs, such
030     * as SpringBox and SpringCompactGrid.
031     */
032    public class SpringLayoutUtils {
033    
034        /**
035         * A debugging utility that prints to stdout the component's minimum,
036         * preferred, and maximum sizes.
037         */
038        public static void printSizes(Component c) {
039            System.out.println("minimumSize = " + c.getMinimumSize());
040            System.out.println("preferredSize = " + c.getPreferredSize());
041            System.out.println("maximumSize = " + c.getMaximumSize());
042        }
043    
044        /**
045         * Aligns the first <code>rows</code>*<code>cols</code> components of
046         * <code>parent</code> in a grid. Each component is as big as the maximum
047         * preferred width and height of the components. The parent is made just big
048         * enough to fit them all.
049         * 
050         * @param rows
051         *            number of rows
052         * @param cols
053         *            number of columns
054         * @param initialX
055         *            x location to start the grid at
056         * @param initialY
057         *            y location to start the grid at
058         * @param xPad
059         *            x padding between cells
060         * @param yPad
061         *            y padding between cells
062         */
063        public static void makeGrid(Container parent, int rows, int cols, int initialX, int initialY, int xPad, int yPad) {
064    
065            SpringLayout layout;
066            try {
067                layout = (SpringLayout)parent.getLayout();
068            }
069            catch (ClassCastException exc) {
070                System.err.println("The first argument to makeGrid must use SpringLayout.");
071                return;
072            }
073    
074            Spring xPadSpring = Spring.constant(xPad);
075            Spring yPadSpring = Spring.constant(yPad);
076            Spring initialXSpring = Spring.constant(initialX);
077            Spring initialYSpring = Spring.constant(initialY);
078            int max = rows * cols;
079    
080            //Calculate Springs that are the max of the width/height so that all
081            //cells have the same size.
082            Spring maxWidthSpring = layout.getConstraints(parent.getComponent(0)).getWidth();
083            Spring maxHeightSpring = layout.getConstraints(parent.getComponent(0)).getWidth();
084            for (int i = 1; i < max; i++) {
085                SpringLayout.Constraints cons = layout.getConstraints(parent.getComponent(i));
086    
087                maxWidthSpring = Spring.max(maxWidthSpring, cons.getWidth());
088                maxHeightSpring = Spring.max(maxHeightSpring, cons.getHeight());
089            }
090    
091            //Apply the new width/height Spring. This forces all the
092            //components to have the same size.
093            for (int i = 0; i < max; i++) {
094                SpringLayout.Constraints cons = layout.getConstraints(parent.getComponent(i));
095    
096                cons.setWidth(maxWidthSpring);
097                cons.setHeight(maxHeightSpring);
098            }
099    
100            //Then adjust the x/y constraints of all the cells so that they
101            //are aligned in a grid.
102            SpringLayout.Constraints lastCons = null;
103            SpringLayout.Constraints lastRowCons = null;
104            for (int i = 0; i < max; i++) {
105                SpringLayout.Constraints cons = layout.getConstraints(parent.getComponent(i));
106                if (i % cols == 0) { //start of new row
107                    lastRowCons = lastCons;
108                    cons.setX(initialXSpring);
109                }
110                else { //x position depends on previous component
111                    cons.setX(Spring.sum(lastCons.getConstraint(SpringLayout.EAST), xPadSpring));
112                }
113    
114                if (i / cols == 0) { //first row
115                    cons.setY(initialYSpring);
116                }
117                else { //y position depends on previous row
118                    cons.setY(Spring.sum(lastRowCons.getConstraint(SpringLayout.SOUTH), yPadSpring));
119                }
120                lastCons = cons;
121            }
122    
123            //Set the parent's size.
124            SpringLayout.Constraints pCons = layout.getConstraints(parent);
125            pCons.setConstraint(SpringLayout.SOUTH, Spring.sum(Spring.constant(yPad), lastCons
126                    .getConstraint(SpringLayout.SOUTH)));
127            pCons.setConstraint(SpringLayout.EAST, Spring.sum(Spring.constant(xPad), lastCons
128                    .getConstraint(SpringLayout.EAST)));
129        }
130    
131        /* Used by makeCompactGrid. */
132        private static SpringLayout.Constraints getConstraintsForCell(int row, int col, Container parent, int cols) {
133            SpringLayout layout = (SpringLayout)parent.getLayout();
134            Component c = parent.getComponent(row * cols + col);
135            return layout.getConstraints(c);
136        }
137    
138        /**
139         * Aligns the first <code>rows</code>*<code>cols</code> components of
140         * <code>parent</code> in a grid. Each component in a column is as wide as
141         * the maximum preferred width of the components in that column; height is
142         * similarly determined for each row. The parent is made just big enough to
143         * fit them all.
144         * 
145         * @param rows
146         *            number of rows
147         * @param cols
148         *            number of columns
149         * @param initialX
150         *            x location to start the grid at
151         * @param initialY
152         *            y location to start the grid at
153         * @param xPad
154         *            x padding between cells
155         * @param yPad
156         *            y padding between cells
157         */
158        public static void makeCompactGrid(Container parent, int rows, int cols, int initialX, int initialY, int xPad,
159                int yPad) {
160            SpringLayout layout;
161            try {
162                layout = (SpringLayout)parent.getLayout();
163            }
164            catch (ClassCastException exc) {
165                System.err.println("The first argument to makeCompactGrid must use SpringLayout.");
166                return;
167            }
168    
169            //Align all cells in each column and make them the same width.
170            Spring x = Spring.constant(initialX);
171            for (int c = 0; c < cols; c++) {
172                Spring width = Spring.constant(0);
173                for (int r = 0; r < rows; r++) {
174                    width = Spring.max(width, getConstraintsForCell(r, c, parent, cols).getWidth());
175                }
176                for (int r = 0; r < rows; r++) {
177                    SpringLayout.Constraints constraints = getConstraintsForCell(r, c, parent, cols);
178                    constraints.setX(x);
179                    constraints.setWidth(width);
180                }
181                x = Spring.sum(x, Spring.sum(width, Spring.constant(xPad)));
182            }
183    
184            //Align all cells in each row and make them the same height.
185            Spring y = Spring.constant(initialY);
186            for (int r = 0; r < rows; r++) {
187                Spring height = Spring.constant(0);
188                for (int c = 0; c < cols; c++) {
189                    height = Spring.max(height, getConstraintsForCell(r, c, parent, cols).getHeight());
190                }
191                for (int c = 0; c < cols; c++) {
192                    SpringLayout.Constraints constraints = getConstraintsForCell(r, c, parent, cols);
193                    constraints.setY(y);
194                    constraints.setHeight(height);
195                }
196                y = Spring.sum(y, Spring.sum(height, Spring.constant(yPad)));
197            }
198    
199            //Set the parent's size.
200            SpringLayout.Constraints pCons = layout.getConstraints(parent);
201            pCons.setConstraint(SpringLayout.SOUTH, y);
202            pCons.setConstraint(SpringLayout.EAST, x);
203        }
204    
205        /**
206         * %DOC one sentence summary caption%.
207         * 
208         * %long description%.
209         * 
210         * @param contentPane
211         * @param i
212         * @param j
213         */
214        public static void makeCompactGridWithStandardBorder(JPanel contentPane, int rows, int cols) {
215            makeCompactGrid(contentPane, rows, cols, UIConstants.ONE_SPACE, UIConstants.ONE_SPACE, UIConstants.ONE_SPACE,
216                    UIConstants.ONE_SPACE);
217    
218        }
219    }