The Source for Java Technology Collaboration


Home | Changes | Index | Search | Go

FormLayoutExample

This is the sample code for the example on John O'Conner's blog for a layout manager challenge using the FormLayout layout manager.

Nested subpanels are used. The subpanel created by createDetailsPanel() could be eliminated if another builder, PanelBuilder, is used instead of DefaultFormBuilder. DefaultFormBuilder is used because it provides a much more concise API. However, the nested panels created by createUnalignedField() probably could not be eliminated.

Can it align components across other components? For example, can it both left and right align the 'phone' text field with the 'city' text field on the other side of the two address fields? Easily. By having the components be in the same column, and having that column defined as fill and grow. That there are other components that span columns does not affect this.

Does your manager know about platform specific gaps and spacing among components. Just curious. Yes. It knows about Windows and Mac spacing out of the box. It will also reorder OK and Cancel buttons bars based on the platform.

Can the text fields, labels, etc grow and shrink when the text is localized? I don't understand the question

Just how much code do I have to write? Java code? Declarative XML? The components are placed in a grid that is defined declaratively using a Domain-specific language. The builder API saves a lot of typing.

Can I nest panels? Yes. I did so in my solution.

Can it align components along a baseline. For example, the new GroupLayout can align labels and text fields along the text baseline...that's nice. Yes. In fact, it's the default behavior.

What's the licensing? BSD

Will this work for bi-directional locales? How difficult would it be to mirror the layout for a right-to-left locale? I don't have much experience with this, but I know there is code in the builders that explicitly deals with right-to-left locales.

What else should we evaluate? One convenience that the example didn't use is that mnemonics can be associated with components automatically using the right method on the DefaultFormBuilder. There are many, many other convenience methods on the builders.

Sample code submitted by lmfinney:

import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.factories.ButtonBarFactory;
import com.jgoodies.forms.layout.FormLayout;

public class Showdown {

    public Showdown() {
        JFrame frame = new JFrame("Address Book Demo");
        FormLayout formLayout = new FormLayout(
                "pref:grow(0.33), 4dlu, pref:grow(0.67)",
                "fill:pref:grow");
        DefaultFormBuilder builder = new DefaultFormBuilder(formLayout);
        builder.setDefaultDialogBorder();

        JList list = new JList(new String[] {
                "Bunny, Bugs", "Cat, Sylvester", "Coyote, Wily E.",
                "Devil, Tasmanian", "Duck, Daffy", "Fedd, Elmer",
                "Le Pew, Pepe", "Martian, Marvin"
        });
        list.setPreferredSize(new Dimension(150, 20));
        JScrollPane scroll = new JScrollPane(list);
        builder.append(scroll);
        builder.append(createDetailsPanel(frame));
        frame.add(builder.getPanel());

        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private JPanel createDetailsPanel(JFrame frame) {
        FormLayout formLayout = new FormLayout(
                "right:pref, 2dlu, pref:grow(0.5), 2dlu, pref:grow(0.5)");
        DefaultFormBuilder builder = new DefaultFormBuilder(formLayout);

        builder.append("Last Name", new JTextField(12));
        builder.append(createUnalignedField("First Name"));
        builder.append("Phone", new JTextField(12));
        builder.append(createUnalignedField("Email"));
        builder.append("Address 1", new JTextField(40), 3);
        builder.append("Address 2", new JTextField(40), 3);
        builder.append("City", new JTextField(12));
        builder.nextLine();
        builder.append("State", new JTextField(12));
        builder.append(createUnalignedField("Postal Code"));
        builder.append("Country", new JTextField(12));
        builder.nextLine();
        JButton[] buttons = new JButton[] {
                new JButton("New"),
                new JButton("Delete"),
                new JButton("Edit"),
                new JButton("Save"),
                new JButton("Cancel")
        };
        builder.appendUnrelatedComponentsGapRow();
        builder.nextLine();
        builder.appendRow("p");
        builder.append(ButtonBarFactory.buildCenteredBar(buttons), 5);
        frame.getRootPane().setDefaultButton(buttons[1]);

        return builder.getPanel();
    }

    private JPanel createUnalignedField(String label) {
        FormLayout formLayout = new FormLayout("pref, 2dlu, pref:grow");
        DefaultFormBuilder builder = new DefaultFormBuilder(formLayout);

        builder.append(label, new JTextField(12));

        return builder.getPanel();
    }

    public static void main(String[] args) {
        new Showdown();
    }

}
-- Main.lmfinney - 12 Oct 2006

Topic FormLayoutExample . { Edit | Ref-By | Printable | Diffs r2 < r1 | More }
 XML java.net RSS

Revision r2 - 07 Nov 2006 - 02:50:21 - Main.lmfinney
Parents: 3rdParty