JFC Swing: The SpringLayout Classby Marc Loy, coauthor of Java Swing, 2nd Edition
With SDK 1.4, a new -- but not really new -- layout manager was added. The
SpringLayout manager uses the notion of springs and struts to keep everything in place. A version of
SpringLayout existed in the early alpha and betas of the Swing package, but it was not included because the Swing team felt it still needed too much work. While it still needs a bit of work, it has come a long way; its inclusion in SDK 1.4 is a testament to that progress. The class diagram for
SpringLayout and its helpers is shown in Figure 1.
Before you dive too deeply into this layout manager, you should know that its purpose in life is to aid GUI builders and other code-generating tools. It can certainly be hand-coded -- and we have the examples to prove it -- but you'll often leave this layout manager to the aforementioned tools. If you want a flexible replacement for the
GridBagLayout, you might want to take a look at the
RelativeLayout manager written by Jim Elliott. The complete package, with docs, tutorial, and source code, can be found on the Java Swing, 2nd Edition book Web page.
Figure 1. The SpringLayout manager classes.
The source files for this article, FractionSpring.java and CompassButtons.java are available in this zip file.
Springs and Struts
Now that you're here for the long haul, let's look at the core of the
SpringLayout manager's approach to component layout: springs and struts.
- A spring is effectively a triplet representing a range of values. It contains its minimum, preferred, and maximum lengths.
- A strut is a spring with all of the spring removed -- its minimum, preferred, and maximum lengths are identical.
SpringLayout at the helm, you use springs and struts to specify the bounds (x, y, width, height) of all of your components. (You could mimic the null layout manager by using only struts.)
The not-so-obvious big win in this layout manager is that springs can be anchored between the edges of components and will maintain their relationship even when the container is resized. This makes it possible to create layouts that would be difficult in other managers. While you could probably use a grand
GridBagLayout to do the trick,
SpringLayout should provide better performance once it's all fixed up and finalized.
Figure 2 shows a simple application that uses
SpringLayout. We position directional buttons over a large picture for navigation. Notice how the North button stays horizontally centered and anchored to the top edge of the application after we resize the frame. The other buttons behave similarly. Just to reiterate, you could certainly accomplish this with nested containers or a properly constructed
SpringLayout should simply prove to be the most maintainable over the long haul. We'll look at the source code for this example after we examine the API in more detail.
Figure 2. A SpringLayout managed container at two different sizes.
SpringLayout class thinks of components in terms of their edges. Several constants have been defined for the edges, as shown in Table 1.
Table 1. SpringLayout Constants.
||String||The top edge of the component. Corresponds to the y value of the component's bounding box.|
||String||The bottom edge of the component. Corresponds to the y value of the bounding box plus the height of the component.|
||String||The left edge of the component. Corresponds to the x value of the component's bounding box.|
||String||The right edge of the component. Corresponds to the x value of the bounding box plus the width of the component.|