KappaLayout
Using KappaLayout and LambdaLayout in Conjunction with the Java Look and Feel Design Guidelines
Explanation of perfect and stretchable layouts.
User interfaces constructed with Java components can be classified into two varieties: perfect and stretchable.
Perfect layouts are those in which each component is always displayed at its preferred size, the containing window is sized precisely to be just the size to hold the components, and the containing window does not allow (or does not need) resizing. There are one or two exceptions to displaying the components at the preferred size. One is command buttons, in that groups of command buttons look best when the buttons are aligned and all are the same size. A perfect layout compensates for this desired layout by choosing the button with the largest preferred size and making all other buttons in the group the same size as that button. The other exception is text components, which tend to have a preferred size that is inadequate for human users to perform text entry. Text components should be stretched to align visually with other components and to present a large enough area for the user to enter text.
Stretchable layouts are those in which it is desirable for some or all of the components in the container to be able to resize as the container resizes. An example is a window that contains a text area. It may be desirable for the text area to grow larger to display more text as the window is made larger. Other examples of components that might want to stretch to allow the user to see more of its contents are lists and trees. Usually a stretchable layout has some components that do not want to be stretched, such as command buttons, so a stretchable layout needs to be able to accomodate these kinds of components as well.
KappaLayout is the best choice for a perfect layout as it pays close attention to the preferred sizes of components. It can cause a component to be stretched for particular purposes, as in the example of command buttons that should be the same size. KappaLayout only allows components to be stretched once during initial layout, thereafter, the component does not change size regardless of size changes in the parent container.
LambdaLayout is the best choice for a stretchable layout as it allows components to stretch or shrink as the parent container is resized. LambdaLayout also pays close attention to the preferred sizes of components and will not allow components to be shrunk to less than the preferred size.
Often there are parts of a layout that should be stretchable and parts that should not. In these cases, a combination of the two layout managers should be used along with the nested panels technique.
A Practical Example.
An applet should have started when you first loaded this page. It is the result of the following example. If you closed the applet, you can get it back by reloading this page.
The following code example shows how to construct the "Find" dialog as shown in Figure 30 of the Java Look and Feel Design Guidelines. This is a 'perfect' layout. The dialog is designed using the design grid method. This figure shows what the dialog will look like when displayed and the design parameters for laying out the components. The red lines are KappaLayout struts and are invisible in the displayed dialog. These struts are rigid, that is, they set the width or height of the column or row to a fixed size. Four of the columns from the design grid are not necessary so are not used. Columns and rows are numbered and are used to set the constraints for each component.
1:import java.awt.*; 2:import java.awt.event.*; 3:import javax.swing.*; 4:import javax.swing.border.*; 5: 6:/* 7:This displays a "find" dialog as is shown in Figure 30 in the Java Look 8:and Feel Design Guidelines. This class shows how to use KappaLayout to create 9:this layout while conforming exactly to the guidelines. 10:*/ 11: 12:public class Figure30 { 13: 14: public Figure30() { 15: // set up a JFrame 16: JFrame f = new JFrame("Figure30"); 17: f.addWindowListener(new WindowAdapter() { 18: public void windowClosing(WindowEvent we) { 19: f.dispose(); 20: } 21: }); 22: 23: /* 24: create the content pane and its layout manager. Use our own JPanel rather 25: than the default container so we can set a javax.swing.border and use a 26: KappaLayout rather than the default BorderLayout (the default content pane 27: for a JFrame uses a BorderLayout. In fact, the default content pane is a 28: JPanel, but would need to be cast as such to be useable as a JPanel.) 29: */ 30: KappaLayout kl = new KappaLayout(); 31: JPanel contents = new JPanel(kl); 32: f.setContentPane(contents); 33: 34: /* 35: set an EmptyBorder on our content panel to create the desired blank 36: space around the contained components. See text accompanying Figure 76 37: in the Java Look and Feel Guidelines -- the guideline is 12 pixels spacing 38: on top and left, 11 pixels on right and bottom. The EmptyBorder does 39: this nicely. An alternate method (suitable for AWT only layouts) is to 40: override the getInsets method. 41: 42: Panel contents = new Panel(kl) { 43: Insets insets = new Insets(12, 12, 11, 11); 44: public Insets getInsets() { 45: return insets; 46: } 47: }; 48: 49: KappaLayout is one of the few layout managers that respect the insets of 50: a container. 51: */ 52: contents.setBorder(new EmptyBorder(12, 11, 11, 12)); 53: 54: /* 55: add the components, following the design grid. Constraint string follows 56: this pattern: "x, y, w, h, a, s, p" where 57: x is start column of component 58: y is start row of component 59: w is width of component in columns 60: h is height of component in rows 61: a is alignment in cell 62: s is stretch parameter 63: p is padding around component in pixels 64: All parameters have defaults and all parameters are optional. See 65: KappaLayout documentation for details of the constraint string. 66: */ 67: // align label to right side of cell 68: contents.add(new JLabel("Find:"), "0, 0, 1, 1, 3"); 69: // stretch text field to fit across 3 columns 70: contents.add(new JTextField(), "2, 0, 3, 1, 0, w"); 71: // align check boxes and radio buttons to left side of cell 72: contents.add(new JCheckBox("Match Case"), "2, 2, 1, 1, 7"); 73: contents.add(new JCheckBox("Whole Word"), "2, 3, 1, 1, 7"); 74: contents.add(new JRadioButton("Start at Top"), "4, 2, 1, 1, 7"); 75: contents.add(new JRadioButton("Wrap Around"), "4, 3, 1, 1, 7"); 76: 77: /* 78: add some struts to ensure fixed separation between components follows 79: the guidelines: 11 pixels between groups, 17 between bottom group and 80: command buttons. 81: */ 82: // strut to separate textfield and top checkbox 83: contents.add(KappaLayout.createVerticalStrut(11, true), "0, 1"); 84: // strut to separate "Find:" label and textfield 85: contents.add(KappaLayout.createHorizontalStrut(11, true), "1, 1"); 86: // strut to separate checkbox column and radio button column 87: contents.add(KappaLayout.createHorizontalStrut(11, true), "3, 1"); 88: // strut to separate bottom checkbox and command buttons 89: contents.add(KappaLayout.createVerticalStrut(17, true), "0, 4"); 90: 91: /* 92: use a separate panel for the buttons to properly align the 93: buttons across the correct grids. This panel can stretch to the full 94: width of the dialog, so will fit regardless of the text on the buttons. 95: */ 96: KappaLayout kl2 = new KappaLayout(); 97: JPanel btn_panel = new JPanel(kl2); 98: // stretch button to fill full width of cell 99: btn_panel.add(new JButton("Find"), "0, 0, 1, 1, , w"); 100: // guidelines say to use 5 pixels between buttons 101: btn_panel.add(KappaLayout.createHorizontalStrut(5), "1, 0, 1, 1"); 102: // stretch button to fill full width of cell 103: btn_panel.add(new JButton("Close"), "2, 0, 1, 1, , w"); 104: 105: /* 106: make the 2 columns holding the buttons the same width. KappaLayout finds 107: the button with the widest preferred width, and uses that width for both 108: columns. The 'w' parameter used in laying out the buttons lets the button 109: with the smaller width of the 2 stretch to be the same size. This is 110: exactly the layout specified by the guidelines. 111: */ 112: kl2.makeColumnsSameWidth(0, 2); 113: 114: /* 115: add the button panel, Allow the panel to fill the full width of 116: the dialog if needed, but align it to the right side and bottom of the 117: dialog as required by the guidelines 118: */ 119: contents.add(btn_panel, "0, 5, 5, 1, 4"); 120: 121: /* 122: pack and show -- this is a 'perfect' dialog, that is, all components 123: are laid out at their preferred size (or, in the case of the buttons, 124: at the same size as the largest preferred size in the button group), 125: inter-component spacing is fixed, and there is no need to stretch any 126: component when resizing the dialog, so set the dialog to disallow 127: resizing. 128: */ 129: f.setResizable(false); 130: f.pack(); 131: f.show(); 132: } 133: 134: public static void main(String[] args) { 135: new Figure30(); 136: } 137:} 138:
(Code coloring produced by the Code2HTML plugin for jEdit.)
References.
The full Java Look and Feel Design guidelines can be found at:
http://java.sun.com/developer/techDocs/hi/guidelines.html
The full guidelines cover quite a lot of material that does not directly apply to laying out user interfaces, so I've compiled an abbreviated guideline containing just the rules for how a user interface should be constructed. The abbreviated guidelines can be found on this site at:
An excellent reference for constructing usable interfaces is "Software for Use" by Larry Constantine and Lucy Lockwood. See http://www.foruse.com for details.