The Source for Java Technology Collaboration


Home | Changes | Index | Search | Go

Address Book Demo in GroupLayout

Here is the picture of the layout we are going to build as specified in the John O'Conner's Layout Manager Showdown:

Solution

You can take a look at the full source code written for Java 6. It is a JFrame subclass that can be executed.

Here is a code excerpt of the most interesting part (definition of the horizontal dimension):

layout.setHorizontalGroup(layout.createSequentialGroup()
    .addComponent(scrollpane, GroupLayout.DEFAULT_SIZE, 130, Short.MAX_VALUE)
    .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
    .addGroup(layout.createParallelGroup()
        .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                .addComponent(lastNameLabel)
                .addComponent(phoneLabel)
                .addComponent(address1Label)
                .addComponent(address2Label)
                .addComponent(cityLabel)
                .addComponent(stateLabel)
                .addComponent(countryLabel))
            .addGroup(layout.createParallelGroup()
                .addComponent(address1Field)
                .addComponent(adress2Field)
                .addGroup(layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup()
                        .addComponent(lastNameField)
                        .addComponent(phoneField)
                        .addComponent(cityField)
                        .addComponent(stateField)
                        .addComponent(countryField))
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(firstNameLabel)
                            .addComponent(firstNameField))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(emailLabel)
                            .addComponent(emailField))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(postalLabel)
                            .addComponent(postalField))))))
        .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addComponent(newButton)
            .addComponent(deleteButton)
            .addComponent(editButton)
            .addComponent(saveButton)
            .addComponent(cancelButton))));

layout.linkSize(SwingConstants.HORIZONTAL,
    cancelButton, deleteButton, editButton, newButton, saveButton);

Some notes to the code above:

  • GroupLayout adds the gaps between component automatically. These gaps are computed dynamically according to the actual Look&Feel that defines preferred gaps between components. It is still possible to insert custom gaps, though.
  • All components are kept in their default size. There is no absolute number, except the list box (in a scroll pane) which has an initial size set.
  • GroupLayouts respects the default resizing behavior of the components. In this case the resizability need not be defined at all and the components expand/shrink just right. GroupLayout still allows to control the resizability precisely for each component.
  • No sub-panels were needed to build this layout.
  • The resulting layout fulfils all points from the assignment except the row of buttons is anchored to the right instead of to the left which looks really strange (it would be trivial to change it, though).

Q&A about GroupLayout

Answering the questions about layout manager's capabilities:
(http://weblogs.java.net/blog/joconner/archive/2006/10/layout_manager.html)

Q: 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?

Yes. This is done simply by placing the text fields in the same parallel group. In GroupLayout each axis is defined separately, the horizontal positioning of the text fields is not affected by the Address 1 and Address 2 text fields placed in between vertically. Code excerpt:

.addGroup(layout.createParallelGroup()
    .addComponent(lastNameField)
    .addComponent(phoneField)
    .addComponent(cityField)
    .addComponent(stateField)
    .addComponent(countryField))

Q: Does your manager know about platform specific gaps and spacing among components?

Yes. A core feature, first introduced in GroupLayout. It uses LayoutStyle to compute gaps between components dynamically in runtime according to the actual Look&Feel guidelines.

Q: Can the text fields, labels, etc grow and shrink when the text is localized?

Yes. The components are positioned relatively and use their default preferred sizes computed according to their actual content in runtime.

Q: Just how much code do I have to write? Java code? Declarative XML?

Everything is in Java, no XML ;-). You need to write the code for two dimensions separately. It means to write a bit more code, on the other hand the code is simpler for each dimension. There are no dependencies between the dimensions. GroupLayout was not designed primarily for hand coding, it is rather low-level, lacking an API layer easing to express some common patterns. However it is capable enough to work with without the need for custom subclasses as extensions (unlike SpringLayout, for example).

The definition of the layout is on one place and thus easier to maintain. There is no separate definition of a grid and additional code placing the components into the grid via constraints. The structure of the layout is defined in one go, just using hierarchical nesting of groups.

Q: Can I nest panels?

Sure wink . The point is, however, that you don't need to. Sub-panels are not needed to achieve certain layout. GroupLayout itself is based on nesting which is more lightweight and flexible than using panels.

Q: Can it align components along a baseline.

Yes. A core feature GroupLayout.

Q: What's the licensing?

GroupLayout is already part of JDK (Java 6). For earlier JDK the swing-layout library can be used under LGPL.

Q: Will this work for bi-directional locales? How difficult would it be to mirror the layout for a right-to-left locale?

Yes. Everything is defined relatively based on bi-di neutral constants. So you can just change the orientation of the container and you are done.

Q: What else should we evaluate?

Besides what has been already mentioned, GroupLayout provides an easy way to swap components in the layout, allows to force the same size on arbitrary (even unrelated) components, allows to control if invisible components should be cosidered in the layout, and more (I don't remember everything wink ).

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

Revision r2 - 19 Mar 2005 - 09:21:59 - Main.tpavek
Parents: 3rdParty > LayoutManagerShowdown