/*
* (c) Copyright 2004 by Heng Yuan
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* ITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
import java.awt.*;
import javax.swing.*;
/**
* This code is from <a href="http://java.sun.com/docs/books/tutorial/index.html">Java Tutorial</a>
* The source is at http://java.sun.com/docs/books/tutorial/uiswing/layout/example-1dot4/SpringUtilities.java.
* No copyright or license information was in the source file and it was from the tutorial. Thus
* assuming I could use it in this program. Below is the original file header. The file is
* not modified other than reformating white spaces.
* <p>
* A 1.4 file that provides utility methods for
* creating form- or grid-style layouts with SpringLayout.
* These utilities are used by several programs, such as
* SpringBox and SpringCompactGrid.
* </p>
* TODO: Although algorithm wise is correct, this class fails to address the problem of rounding
* errors. As the result, sometimes the last row can be mismatched with other rows. The solution
* to the problem is to force the alignment of edges.
*
* @see javax.swing.SpringLayout
* @see cookxml.cookswing.creator.SpringGridCreator
* @author Heng Yuan
* @version $Id: SpringLayoutUtilities.java 215 2007-06-06 03:59:41Z coconut $
* @since CookSwing 1.0
*/
public class SpringLayoutUtilities
{
/**
* A debugging utility that prints to stdout the component's
* minimum, preferred, and maximum sizes.
*/
public static void printSizes (Component c)
{
System.out.println ("minimumSize = " + c.getMinimumSize ());
System.out.println ("preferredSize = " + c.getPreferredSize ());
System.out.println ("maximumSize = " + c.getMaximumSize ());
}
/**
* Aligns the first <code>rows</code> * <code>cols</code>
* components of <code>parent</code> in
* a grid. Each component is as big as the maximum
* preferred width and height of the components.
* The parent is made just big enough to fit them all.
*
* @param rows number of rows
* @param cols number of columns
* @param initialX x location to start the grid at
* @param initialY y location to start the grid at
* @param xPad x padding between cells
* @param yPad y padding between cells
*/
public static void makeGrid (Container parent,
int rows, int cols,
int initialX, int initialY,
int xPad, int yPad)
{
SpringLayout layout;
try
{
layout = (SpringLayout)parent.getLayout ();
}
catch (ClassCastException exc)
{
System.err.println ("The first argument to makeGrid must use SpringLayout.");
return;
}
Spring xPadSpring = Spring.constant (xPad);
Spring yPadSpring = Spring.constant (yPad);
Spring initialXSpring = Spring.constant (initialX);
Spring initialYSpring = Spring.constant (initialY);
int max = rows * cols;
//Calculate Springs that are the max of the width/height so that all
//cells have the same size.
Spring maxWidthSpring = layout.getConstraints (parent.getComponent (0)).
getWidth ();
Spring maxHeightSpring = layout.getConstraints (parent.getComponent (0)).
getWidth ();
for (int i = 1; i < max; i++)
{
SpringLayout.Constraints cons = layout.getConstraints (parent.getComponent (i));
maxWidthSpring = Spring.max (maxWidthSpring, cons.getWidth ());
maxHeightSpring = Spring.max (maxHeightSpring, cons.getHeight ());
}
//Apply the new width/height Spring. This forces all the
//components to have the same size.
for (int i = 0; i < max; i++)
{
SpringLayout.Constraints cons = layout.getConstraints (parent.getComponent (i));
cons.setWidth (maxWidthSpring);
cons.setHeight (maxHeightSpring);
}
//Then adjust the x/y constraints of all the cells so that they
//are aligned in a grid.
SpringLayout.Constraints lastCons = null;
SpringLayout.Constraints lastRowCons = null;
for (int i = 0; i < max; i++)
{
SpringLayout.Constraints cons = layout.getConstraints (parent.getComponent (i));
if (i % cols == 0)
{ //start of new row
lastRowCons = lastCons;
cons.setX (initialXSpring);
}
else
{ //x position depends on previous component
cons.setX (Spring.sum (lastCons.getConstraint (SpringLayout.EAST),
xPadSpring));
}
if (i / cols == 0)
{ //first row
cons.setY (initialYSpring);
}
else
{ //y position depends on previous row
cons.setY (Spring.sum (lastRowCons.getConstraint (SpringLayout.SOUTH),
yPadSpring));
}
lastCons = cons;
}
//Set the parent's size.
SpringLayout.Constraints pCons = layout.getConstraints (parent);
pCons.setConstraint (SpringLayout.SOUTH,
Spring.sum (Spring.constant (yPad),
lastCons.getConstraint (SpringLayout.SOUTH)));
pCons.setConstraint (SpringLayout.EAST,
Spring.sum (Spring.constant (xPad),
lastCons.getConstraint (SpringLayout.EAST)));
}
/* Used by makeCompactGrid. */
private static SpringLayout.Constraints getConstraintsForCell (int row, int col,
Container parent,
int cols)
{
SpringLayout layout = (SpringLayout)parent.getLayout ();
Component c = parent.getComponent (row * cols + col);
return layout.getConstraints (c);
}
/**
* Aligns the first <code>rows</code> * <code>cols</code>
* components of <code>parent</code> in
* a grid. Each component in a column is as wide as the maximum
* preferred width of the components in that column;
* height is similarly determined for each row.
* The parent is made just big enough to fit them all.
*
* @param rows number of rows
* @param cols number of columns
* @param initialX x location to start the grid at
* @param initialY y location to start the grid at
* @param xPad x padding between cells
* @param yPad y padding between cells
*/
public static void makeCompactGrid (Container parent,
int rows, int cols,
int initialX, int initialY,
int xPad, int yPad)
{
SpringLayout layout;
try
{
layout = (SpringLayout)parent.getLayout ();
}
catch (ClassCastException exc)
{
System.err.println ("The first argument to makeCompactGrid must use SpringLayout.");
return;
}
//Align all cells in each column and make them the same width.
Spring x = Spring.constant (initialX);
for (int c = 0; c < cols; c++)
{
Spring width = Spring.constant (0);
for (int r = 0; r < rows; r++)
{
width = Spring.max (width,
getConstraintsForCell (r, c, parent, cols).
getWidth ());
}
for (int r = 0; r < rows; r++)
{
SpringLayout.Constraints constraints =
getConstraintsForCell (r, c, parent, cols);
constraints.setX (x);
constraints.setWidth (width);
}
x = Spring.sum (x, Spring.sum (width, Spring.constant (xPad)));
}
//Align all cells in each row and make them the same height.
Spring y = Spring.constant (initialY);
for (int r = 0; r < rows; r++)
{
Spring height = Spring.constant (0);
for (int c = 0; c < cols; c++)
{
height = Spring.max (height,
getConstraintsForCell (r, c, parent, cols).
getHeight ());
}
for (int c = 0; c < cols; c++)
{
SpringLayout.Constraints constraints =
getConstraintsForCell (r, c, parent, cols);
constraints.setY (y);
constraints.setHeight (height);
}
y = Spring.sum (y, Spring.sum (height, Spring.constant (yPad)));
}
//Set the parent's size.
SpringLayout.Constraints pCons = layout.getConstraints (parent);
pCons.setConstraint (SpringLayout.SOUTH, y);
pCons.setConstraint (SpringLayout.EAST, x);
}
}