import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * An example of using SpringLayout to create a forms-type layout. */ public class Form { public static void main(String[] args) { int numPairs = 5; JLabel[] labels = new JLabel[numPairs]; JTextField[] textFields = new JTextField[numPairs]; // Create the labels (first column). labels[0] = new JLabel("Name:"); labels[1] = new JLabel("Phone:"); labels[2] = new JLabel("Fax:"); labels[2].setFont(labels[2].getFont().deriveFont(Font.PLAIN, 24f)); labels[3] = new JLabel("Email:"); labels[4] = new JLabel("Address:"); // Create the text fields (second column). for (int i = 0; i < numPairs; i++) { textFields[i] = new JTextField(10); } // For accessibility's sake, associate each label with its text field. for (int i = 0; i < numPairs; i++) { labels[i].setLabelFor(textFields[i]); } // Call the method that does all the layout work. Container container = createForm(labels, textFields, 5, 5, 5, 5); // Set up the frame and show it. JFrame frame = new JFrame("Form"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setContentPane(container); frame.pack(); frame.setVisible(true); } /** * Creates a container that uses a SpringLayout to present * pairs of components. The resulting layout is similar to * that of a form. For example: *
     * LLLL  RRR
     * LL    RRR
     * L     RRR
     * LLLLL RRR
     * 
* where the max of the widths of the L (left) components dictates the * x location of the R (right) components. The width of the Rs is * locked to that of the container so that all extra space is given * to them. * * @param leftComponents the components in the left column * (the first item of each pair); * typically these are labels * * @param rightComponents the components in the right column * (the second item of each pair); * typically these are text fields * */ private static Container createForm(Component[] leftComponents, Component[] rightComponents, int initialX, int initialY, int xPad, int yPad) { SpringLayout layout = new SpringLayout(); int numRows = Math.max(leftComponents.length, rightComponents.length); // The constant springs we'll use to enforce spacing. Spring xSpring = Spring.constant(initialX); Spring ySpring = Spring.constant(initialY); Spring xPadSpring = Spring.constant(xPad); Spring yPadSpring = Spring.constant(yPad); Spring negXPadSpring = Spring.constant(-xPad); // Create the container and add the components to it. JPanel parent = new JPanel(layout); for (int i = 0; i < numRows; i++) { parent.add(leftComponents[i]); parent.add(rightComponents[i]); } // maxEastSpring will contain the highest min/pref/max values // for the right edges of the components in the first column // (i.e. the largest X coordinate in a first-column component). // We use layout.getConstraint instead of layout.getConstraints // (layout.getConstraints(comp).getConstraint("East")) // because we need a proxy -- not the current Spring. // Otherwise, it won't take the revised X position into account // for the initial layout. Spring maxEastSpring = layout.getConstraint("East", leftComponents[0]); for (int row = 1; row < numRows; row++) { maxEastSpring = Spring.max(maxEastSpring, layout.getConstraint("East", leftComponents[row])); } // Lay out each pair. The left column's x is constrained based on // the passed x location. The y for each component in the left column // is the max of the previous pair's height. In the right column, x is // constrained by the max width of the left column (maxEastSpring), // y is constrained as in the left column, and the width is // constrained to be the x location minus the width of the // parent container. This last constraint makes the right column fill // all extra horizontal space. SpringLayout.Constraints lastConsL = null; SpringLayout.Constraints lastConsR = null; Spring parentWidth = layout.getConstraint("East", parent); Spring rWidth = null; Spring maxHeightSpring = null; Spring rX = Spring.sum(maxEastSpring, xPadSpring); //right col location Spring negRX = Spring.minus(rX); //negative of rX for (int row = 0; row < numRows; row++) { SpringLayout.Constraints consL = layout.getConstraints( leftComponents[row]); SpringLayout.Constraints consR = layout.getConstraints( rightComponents[row]); consL.setX(xSpring); consR.setX(rX); rWidth = consR.getWidth(); //get the spring that tracks this //component's min/pref/max width after //setting the X spring but before //setting the width spring (to avoid //a circularity); we really only //need to do this once for the //textfield case, since they have the //same size info //XXX To account for other cases, //XXX we should probably take the max //XXX of the widths. //This is used to set the container's //width after this loop. consR.setWidth(Spring.sum(Spring.sum(parentWidth, negRX), negXPadSpring)); if (row == 0) { consL.setY(ySpring); consR.setY(ySpring); maxHeightSpring = Spring.sum(ySpring, Spring.max(consL.getHeight(), consR.getHeight())); } else { // row > 0 Spring y = Spring.sum(Spring.max( lastConsL.getConstraint("South"), lastConsR.getConstraint("South")), yPadSpring); consL.setY(y); consR.setY(y); maxHeightSpring = Spring.sum(yPadSpring, Spring.sum(maxHeightSpring, Spring.max( consL.getHeight(), consR.getHeight()))); } lastConsL = consL; lastConsR = consR; } // end of for loop // Wire up the east/south of the container so that the its preferred // size is valid. The east spring is the distance to the right // column (rX) + the right component's width (rWidth) + the final // padding (xPadSpring). // The south side is maxHeightSpring + the final padding (yPadSpring). SpringLayout.Constraints consParent = layout.getConstraints(parent); consParent.setConstraint("East", Spring.sum(rX, Spring.sum(rWidth, xPadSpring))); consParent.setConstraint("South", Spring.sum(maxHeightSpring, yPadSpring)); return parent; } }