Part 1: About GridBagLayout


XYLayout is a feature of JBuilder Professional and Enterprise. If you use JBuilder Foundation, substitute null layout wherever XYLayout is specified.

Overview of GridBagLayout

GridBagLayout is a complex layout manager that requires some study and practice to understand it, but once it is mastered, it is extremely useful. JBuilder has added some special features to the visual design tools that make GridBagLayout much easier to design and control, such as a GridBagConstraints Editor, a visual grid, drag and drop editing, and a special pop-up menu for components in a GridBagLayout container.

There are two approaches you can take to designing GridBagLayout in the UI designer. You can design it from scratch by adding components to a GridBagLayout panel, or you can prototype the panel in the UI designer using another layout first, such as XYLayout or null layout, then convert it to GridBagLayout when you have all the components arranged and sized the way you want. This method can speed up your design work substantially, and is the one which is the focus of this tutorial.

Whichever method you use, you should take advantage of using nested panels to group the components. Use panels to define the major areas of the GridBagLayout container. This will greatly simplify your GridBagLayout design giving you fewer cells in the grid and fewer components that need GridBagConstraints.

What is GridBagLayout?

In Java, you create a user interface by adding components to a Container object, such as Frame or a Panel, and using a layout manager to control the size and placement of the objects within the container. By default, every Container object has a layout manager object that controls its layout.

GridBagLayout is an extremely flexible and powerful layout manager that implements the interface LayoutManager2 and knows where and how to layout objects based on object GridBagConstraints. It places components horizontally and vertically on a dynamic rectangular grid, but provides more control in the size and location of the components than GridLayout (in which the grid cells are of equal size, filled with one component each.)

In a GridBagLayout, the components do not have to be the same size, and they can span multiple cells. Also, the columns and rows in the grid do not have to be the same width or height.

GridBagLayout controls the placement of its components based on the values in each component's GridBagConstraints object, the component's minimum size, and the container's preferred size.

Example GridBagLayout

GridBagLayout

The buttons grow and shrink as you change the size and shape of the container represented in this example. The ability to grow or shrink reliably is what makes this whole layout work when you change computer resolutions or localize the product so the strings change length.

In the example above, some of the buttons occupy only one cell of the grid (one row, one column), but others span multiple cells, or rows and columns. You can see the exact number of cells each component occupies in the JBuilder UI designer when you display the grid for a GridBagLayout container. The area each component difference between a cell and the area each component occupies is explained in the next topic "What is the component's display area?".


What is the component's display area?

The definition of a grid cell is the same for GridBagLayout as it is for GridLayout: a cell is one column wide by one row deep. However, unlike GridLayout where all cells are equal in size, GridBagLayout cells can be different heights and widths, and a component can occupy more than one cell horizontally and vertically.

This area occupied by a component is called its display area, and it is specified with the component's GridBagConstraints gridwidth and gridheight (number of horizontal and vertical cells in the display area).

For example, in the following GridBagLayout container, component "4" spans one cell (or column) horizontally and two cells (rows) vertically. Therefore, its display area consists of two cells.

displayarea2.gif - 3478 Bytes

A component can completely fill up its display area (as with component "4" in the example above), or it can be smaller than its display area.

For example, in the following GridBagLayout container, the display area for component "3" consists of nine cells, three horizontally and three vertically. However, the component is smaller than the display area because it has insets which create a barrier between the edges of the display area and the component.

displayarea1.gif - 4834 Bytes

Even though this component has both horizontal and vertical fill constraints, since it also has insets on all four sides of the component (represented by the double blue nibs on each side of the display area), these take precedence over the fill constraints. The result is that the component will only fill the display area up to the insets.

If you try to make the component larger than its current display area, GridBagLayout will increase the size of the cells in the display area to accommodate the new size of the component, plus leaving space for the insets.

A component can also be smaller than its display area when there are no insets, as with component "6" in the following example.

displayarea3.gif - 3204 Bytes

Even though the display area is only one cell, there are no constraints that enlarge the component beyond its minimum size. In this case, the width of the display area is determined by the larger components above it in the same column. Component "6" is displayed at its minimum size, and since it is smaller than its display area, it is anchored at the west edge of the display area with an anchor constraint.

As you can see, GridBagConstraints play a critical role in GridBagLayout. We'll look at these constraints in detail in the next topic, "What are GridBagConstraints", and later in the Tips and Techniques section of this tutorial.


What are GridBagConstraints?

GridBagLayout uses a GridBagConstraints object to specify the layout information for each component in a GridBagLayout container. Since there is a one-to-one relationship between each component and GridBagConstraints object, you need to customize the GridBagConstraints object for each of the container's components.

GridBagConstraints give you control over,

GridBagLayout components have the following constraints:

See Also:

java.awt.GridBagConstraints.html
java.awt.GridBagLayout.html



Why is GridBagLayout so complicated?

When you first start modifying the constraints in a GridBagLayout, you can often have unexpected results that can seem dramatic and difficult to understand. The difficult thing about learning how to assign constraints to components in the GridBagLayout container is knowing what effect the change to one component will have on the other components in the grid. The constraint behavior for one component depends on the other components in the container and their constraints. For example, if you decide to remove weight values from a component, the position of the other components in the grid might change relative to this.

The two examples below show the effect of changing the weighty constraint value of Area 4 from 1.0 to 0.0. Notice how the row collapses, and the bottom row expands.

Area 4 weighty constraint value is 1.0:

Area 4 weighty constraint value of 1.0

Area 4 weighty constraint value changed to 0.0:

Area 4 Weighty constraint value is 0.0

JBuilder shortens the GridBagLayout learning curve time by allowing you to see the effects of changes immediately in a graphical UI designer .


Why use GridBagLayout?

This is a really good question. Most books and tutorials tend to skip an in depth discussion of GridBagLayout, and many recommend avoiding using it altogether. In fact, it's true that you could accomplish much of your UI design work by using a combination of all the other layouts and never using GridBagLayout.

However, if you are seriously concerned with creating a UI that behaves correctly on multiple platforms, then you will want to use GridBagLayout somewhere in your overall design for the following reason:

GridBagLayout gives you complete control over how components behave and how they are displayed when the container is resized or viewed on different platforms.

If you have tried to use GridBagLayout before now, you've discovered that it is very complex, and getting the design to work exactly the way you want involves tedious trial and error--modifying the constraints in the code, then compiling and running to see if it worked. Until you fully understand the behavior of the individual constraints and the effect their modifications will have on the design, you may experience tremendous frustration and even give up trying.

The question, then, is what is the quickest way to successfully learn and create GridBagLayout? The answer to this is in the following topic, "Simplifying GridBagLayout."


Simplifying GridBagLayout

JBuilder gives you a much simpler way to do GridBagLayout design work, making it possible for even the beginning Java programmer to use. By using a combination of the graphical UI designer, JBuilder's XYLayout, and JBuilder's excellent layout conversion ability, all of the initial layout and design code is generated automatically, taking most of the guesswork out and leaving only minor adjustments to you (if any).

Whether you are new to Java, or are an advanced programmer, using the suggestions below will significantly reduce the frustration of using GridBagLayout and speed up your UI design work:

Sketch your design on paper first
Use nested panels and layouts
Use the JBuilder UI designer
Prototype your design in XYLayout


Sketch your design on paper first

Always start your GridBagLayout design on paper. Take the time to sketch out the final design and decide where it would be best to include nested panels with other layouts to simplify the design and further control component placement. For example, if you want a toolbar in your GridBagLayout design, use a nested GridLayout panel to contain the buttons, rather than placing the buttons directly into the GridBagLayout container. Try to arrange your design so you have a minimum number of panels and components for the GridBagLayout container to control.

At first, it may not be obvious how important planning ahead on paper is. But, if you start prototyping without a plan, you will soon discover how much time you would have saved if you had logically thought it through before beginning. Eventually, your knowledge and skill with the various layout managers will become advanced enough that you may be able to skip this step and just begin your prototype in the designer. But, in the beginning, it is well worth the time and extra effort it takes to plan it out. (See "Step 1: Design the layout structure" in Part 2 of this tutorial.)

While this piece of advice is true for any UI design, it is especially important when using GridBagLayout. When you add components to an existing GridBagLayout container, or move existing ones, unpredictable results may surprise and overwhelm you. If you can anticipate the final layout requirements before you start, you can minimize the amount of final adjustments needed after you convert the layout from XYLayout to GridBagLayout. (See Prototype your UI in XYLayout.)

The following animation demonstrates what can happen when you add components to a panel after converting it from XYLayout to GridBagLayout. This example uses the same layout design you're going to create in Part 2 of the tutorial. However, in this instance, no nested panels were used, and the conversion to GridBagLayout was done before adding the three buttons across the bottom. You can easily see the difficulty in just trying to add the first of those three buttons!

View animation:   View animation

Notice the difficulty GridBagLayout has figuring out where to put the new button. Even though the button is drawn in the middle of the bottom row, GridBagLayout snaps it to the first column and row. When it is dragged to the middle again, GridBagLayout changes the number of columns in the layout as it tries to accommodate the new button location, which then messes up the nice arrangement of the rest of the components.

It's obvious to see from this example that adding the buttons while the UI was still in XYLayout would have enabled us to place them exactly where and how we wanted. (In reality, when you create this layout, you will add a panel across the bottom to hold all three buttons which will give you greater control over their placement in GridBagLayout.)


Use nested panels and layouts

Most UI designs in Java use more than one type of layout to achieve the desired results. You can often get the best control by nesting multiple panels with different layouts in the main UI container. You can also nest panels within other panels to gain more control over the placement of components. By creating a composite design, and by using the appropriate layout manager for each panel, you can group and arrange components in a way that is both functional and portable.

While GridBagLayout can accommodate a complex grid, it will behave more successfully (and more predictably) if you organize your components into smaller panels, nested inside the GridBagLayout container. These nested panels can use other layouts, including GridBagLayout, and can contain additional panels of components if necessary. This method has several advantages:

Tip Good rule of thumb: It's best to group components into nested panels if grouping can make it easier to keep the grid divided into fewer evenly placed cells. The fewer components you have in a GridBagLayout container, the easier it is to control placement of the components.

For example, in the UI design used for this tutorial, you can fit most of the components into two columns, except for the three buttons at the bottom.

GridBagLayout UI

Placing three buttons at the bottom of the panel increases the total number of columns, making the alignment of the other components trickier. Also, getting those three buttons to stay the same size in the middle of the dialog box when the container is resized is harder to achieve if they are separate components in the larger GridBagLayout panel.

If you choose to leave the buttons in the larger GridBagLayout panel, when you really stretch the container horizontally, the buttons at the bottom get further and further apart, rather than staying together in the center of the panel.

If, instead, you group the three buttons into one GridLayout panel, that panel can span two columns of the GridBagLayout, making it possible to have a total of two columns in the entire GridBagLayout. This is much simpler for GridBagLayout to manage. Also, when the container is stretched, the placement of the buttons in the dialog box will behave predictably when the container is resized, staying together nicely in the center.


Use the JBuilder UI designer

Once you have used the JBuilder UI designer to create a GridBagLayout, you may never go back to only creating GridBagLayout in source code. The advantages of using the UI designer are numerous and convincing:


Prototype your UI in XYLayout

The main advantage to prototyping your UI design in JBuilder's XYLayout is that this layout keeps components at the exact pixel location and size you create them. You also have numerous alignment options available on the component's right-click menu for aligning multiple components: left, right, center, top, bottom, middle, same size horizontally or vertically, and equal spacing horizontally or vertically.

Using XYLayout, you can lay out your components exactly the way you want them to be, then convert the container to GridBagLayout, letting JBuilder calculate the grid cells and constraint values automatically. JBuilder does a good job of this conversion, but in many cases, you may want to fine-tune a few constraints to get the exact behavior you want. This is usually because of two factors:

Even so, the bulk of the work of coding GridBagLayout has already been done for you, greatly speeding up the entire process. As you become more familiar with how constraints affect component behavior and with how JBuilder does the conversion from XYLayout to GridBagLayout, you will be able to anticipate what is going to be necessary, and your pre-planning of where nested panels would make the design work better will improve.

Below are the basic work flow steps for using this design strategy:

  1. Create the container that will ultimately be GridBagLayout. This can be the main UI container, or it can be a panel inside the UI container.

  2. Change its layout to XYLayout, if necessary. The easiest way is to change the Layout property in the Inspector.

  3. Add all the components to the container while it is still in XYLayout. Use nested panels to minimize the actual number of components being ultimately controlled by the GridBagLayout.

  4. Get as close as possible to the finished layout design so the conversion to GridBagLayout will be more successful. Take advantage of XYLayout's alignment options on the right-click menu to fine-tune the placement, size, and alignment of the components.

  5. When the UI is basically finished, convert the main container to GridBagLayout.

    Tip Generally, when you use nested panels in a layout, you would convert the inner panels to their intended layout first, working outward to convert each level of containers, then converting the main container last. However, the strategy is different for GridBagLayout.

    When converting a container from XYLayout to GridBagLayout, you should leave the inner panels in XYLayout until you have converted the outer container to GridBagLayout. This is because during the conversion process, JBuilder determines the number of columns and rows to create in the grid based on the preferred width and height of the components at the time of conversion. The conversion process honors the preferred width and height of the XYLayout panel and determines the number of columns to create, and the insets needed, based on those dimensions.

    For example, if you are trying, as in our example UI, to center a GridLayout toolbar panel across the bottom of the GridBagLayout container, converting that panel of buttons to GridLayout first will shrink the panel to fit the buttons. Depending on the width of the components in the rest of the GridBagLayout container, the conversion might not make the GridLayout panel span all the columns in the GridBagLayout.

    By leaving the panel in XYLayout during the conversion to GridBagLayout (extended across the entire width of the container), JBuilder will know it needs to center the panel and span it across all the columns in the container. The toolbar panel will be well behaved inside the GridBagLayout container after you convert it to GridLayout.

  6. Convert the inner panels to their intended layouts.

  7. Make minor adjustments to constraints if needed to perfect your design. This mainly involves changing insets (for example matching left and right insets for components you want centered in the cell), and making sure the fill and weight constraints were applied the way you want.

    For tips on fine-tuning your design after you have converted to GridBagLayout, see Part 3: Tips and techniques.

  8. Save and run your program. Resize the frame different ways to check for any unwanted behavior. If necessary, make additional adjustments until you are satisfied with the results.