The newest addition on the Java layout manager front is the SpringLayout manager, added with the Java 1.4 release. This layout manager allows you to attach "springs" to components so that they can be laid out relative to other components. For instance, with SpringLayout, you can say that a button appears attached to the right border, no matter what size a user makes the screen.
Getting started with SpringLayout
Like all layout managers, the SpringLayout manager is responsible for positioning components. Component positions are controlled by associating constraints to them. For SpringLayout-controlled components, there is one constraint with four settings -- one for each edge of the component. The SpringLayout manager relies on a SpringLayout.Constraints object for these component constraints. This works similar to the GridBagConstraints class that complements the GridBagLayout manager: Each component added to the container can have an attached SpringLayout.Constraints object. This, however, is where the similarities end.
While with GridBagLayout, you typically add the component to the container with the constraints, in the case of the SpringLayout manager, you usually don't have to add the component with the constraints. Instead, you can add the component and then attach the constraints separately. There is nothing stopping you from adding the constraints with the component, but SpringLayout.Constraints is not a simple class. It is a collection of Spring objects (for each edge), each being a different constraint on the component. When you use it, you need to add each Spring constraint separately to SpringLayout.Constraints. You "add" constraints to SpringLayout.Constraints by setting specific constraints on an edge of the component. Using the four SpringLayout constants of EAST, WEST, NORTH, and SOUTH, you call the setContraints(String edge, Spring spring) method of SpringLayout.Constraints, where String is one of the constants. For instance, if you wanted to add a component in the top-left of a container, you could set up two springs of constant size, combine them together, and add the component to the container with the combined set, as shown here in Listing 1:
Listing 1. Working with SpringLayout
Component left = ...; SpringLayout layout = new SpringLayout(); JPanel panel = new JPanel(layout); Spring xPad = Spring.constant(5); Spring yPad = Spring.constant(25); SpringLayout.Constraints constraint = new SpringLayout.Constraints(); constraint.setConstraint(SpringLayout.WEST, xPad); constraint.setConstraint(SpringLayout.NORTH, yPad); contentPane.add(left, constraint); |
That may not look particularly difficult, but it gets harder when you need to add the next component, either to the right of the first or below it. You can't just add the component n pixels over; you actually must add the padding to the edge of the earlier component. To find the edge of the earlier component, you ask the layout manager with getConstraint(), passing in the edge you want and the component, as in layout.getConstraint(SpringLayout.EAST, left), to get the location of the right edge of the first component. From that, you can add in the necessary padding and attach it to the edge of the other component, as shown in Listing 2:
Listing 2. Adding the second component with SpringLayout
Component right = ...; Spring rightSideOfLeft = layout.getConstraint(SpringLayout.EAST, left); Spring pad = Spring.constant(20); Spring leftEdgeOfRight = Spring.sum(rightSideOfLeft, pad); constraint = new SpringLayout.Constraints(); constraint.setConstraint(SpringLayout.WEST, leftEdgeOfRight); constraint.setConstraint(SpringLayout.NORTH, yPad); contentPane.add(right, constraint); |
Using putConstraint() with SpringLayout
This approach works perfectly well, but gets tedious as the number of components increases. Instead, another way that sidesteps the in-between steps is to add the components without the constraints and then add each separately, using the putConstraint() method of SpringLayout to connect the components, as shown in Listing 3:
Listing 3. Adding the second component with SpringLayout
public void putConstraint(String e1, Component c1, int pad, String e2, Component c2) public void putConstraint(String e1, Component c1, Spring s, String e2, Component c2) |
Here, instead of asking for the edge and adding in the padding yourself, the putConstraint() call combines the tasks for you. To demonstrate, Listing 4 adds the same component constraints to the right component as Listing 3, but uses putConstraint() instead of SpringLayout.Constraints directly:
Listing 4. Using putConstraint() to add the second component
Component left = ...; Component right = ...; SpringLayout layout = new SpringLayout(); JPanel panel = new JPanel(layout); panel.add(left); panel.add(right); layout.putConstraint(SpringLayout.WEST, left, 5, SpringLayout.WEST, panel); layout.putConstraint(SpringLayout.NORTH, left, 25, SpringLayout.NORTH, panel); layout.putConstraint(SpringLayout.NORTH, right, 25, SpringLayout.NORTH, panel); layout.putConstraint(SpringLayout.WEST, right, 20, SpringLayout.EAST, left); |
The String arguments of putConstraint() are the four SpringLayout constants EAST, WEST, NORTH, and SOUTH.
When you use putConstraint(), be sure to specify the unknown component position first and connect it to something that can be calculated or is fixed, like the edge of the screen.
Trying out SpringLayout with BeanBuilder
To help you visualize the use of SpringLayout, Sun has a tool available called BeanBuilder (see Resources). The tool is meant more to be used when working with JavaBeans components, but it also offers an easy way to explore SpringLayout. Figure 1 shows what the tool looks like on startup:
Figure 1. BeanBuilder startup screen
While we're not going to talk about the specifics of the tool, one thing BeanBuilder does let you do is connect components with SpringLayout. Around the edges of each component are a set of four boxes, one each for north, south, east, and west. You can drag an arrow out of a box and connect it to any other box. If the tool were a little more sophisticated, it would permit you to specify gap sizes, but Figure 2 shows what a screen might look like during development:
Figure 2. BeanBuilder usage screen
As Figure 2 illustrates, you can visually connect the arrow to a specific putConstraint() call.
To demonstrate the use of SpringLayout, Listing 4 is the SpringFormTest program that connects the pieces explained using putConstraint(). (You can also download this code; see Resources.)
Listing 4. Complete SpringLayout example
import java.awt.*;
import javax.swing.*;
public class SpringFormTest {
public static void main(String args[]) {
JFrame frame = new JFrame("Spring Form");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = frame.getContentPane();
SpringLayout layout = new SpringLayout();
contentPane.setLayout(layout);
Component left = new JLabel("Left");
Component right = new JTextField(15);
contentPane.add(left);
contentPane.add(right);
layout.putConstraint(SpringLayout.WEST, left, 10,
SpringLayout.WEST, contentPane);
layout.putConstraint(SpringLayout.NORTH, left, 25,
SpringLayout.NORTH, contentPane);
layout.putConstraint(SpringLayout.NORTH, right, 25,
SpringLayout.NORTH, contentPane);
layout.putConstraint(SpringLayout.WEST, right, 20,
SpringLayout.EAST, left);
frame.setSize(300, 100);
frame.show();
}
}
|
Figure 3 shows the results:
Figure 3. SpringFormTest example screen
| Name | Size | Download method |
|---|---|---|
| j-mer09173.zip | 1KB | HTTP |
Information about download methods
- Read John Zukowski's complete collection of Magic with Merlin tips.
- The
BeanBuildertool lets you play withSpringLayoutwithout code. - Read the
SpringLayoutclass Javadoc. - Read the
GridBagLayoutclass Javadoc. - Try out the tutorial "Developing accessible GUIs with Swing" (developerWorks, December 2002) and learn how to design for Section 508 accessibility.
- Be sure to try out Sun's
SpringLayouttutorial, too. - You'll find hundreds of articles about every aspect of Java programming in the developerWorks Java technology zone.

John Zukowski conducts strategic Java consulting with JZ Ventures, Inc., offers technical support through AnswerSquad.com, and is working with SavaJe Technologies to develop a next-generation mobile phone platform. His latest books are Mastering Java 2, J2SE 1.4 (Sybex, April 2002) and Learn Java with JBuilder 6 (Apress, March 2002). Contact John at jaz@zukowski.net.





