The screenshot above provides a simple example of the type of problem that
can be difficult to diagnose when using a GridBagLayout . In
this case, a frame was created and a JLabel and a
JTextField have been added to it. However, a large gap exists
between the label and text field, and since JLabel instances
are transparent by default, there's no indication of whether or not the gap
is due to the label's size or exists for some other reason. Most of the
time, a component includes a border that is drawn around its edges, and
that border provides you with an easy way to estimate the component's size.
However, some frequently used components such as JLabel and
JPanel do not include a border by default, and it can be more
difficult to determine their sizes visually.
When you're designing a user interface using a GridBagLayout ,
this type of problem can cause a great deal of frustration. However, there
are some simple ways that you can modify your code so that it provides you
with visual feedback on the size of your components and/or the cells that
they occupy.
For example, when working with a JLabel or
JPanel , it can be helpful to temporarily add a border or set
the component's background color so that you can easily identify its edges.
The following code sets the background color for the JLabel
used in the previous example, as shown below:
label.setBackground(Color.green);
label.setOpaque(true);
In this case, the color was set to green, although you can use any color
that contrasts with the background color of parent the container. Note also
that it was necessary to call the setOpaque() method, since a
JLabel normally has a transparent background. Although
setting the label's background color did establish that the label itself
does not occupy the space between its text and the JTextField
, it's still not clear why there is such a large gap between the two
components.
Another way to provide helpful visual information is to create a
JPanel subclass that overrides the
paintComponent() method and uses information provided by
GridBagLayout to draw the borders of each cell within the grid. The
getLayoutDimensions() method returns a two-dimensional array
of integer values that identify the height of each row and width of each
column in the grid. Here is an example of such a JPanel
subclass, which should work fine with any program that uses
GridBagLayout .
import java.awt.*;
import javax.swing.*;
public class GridBagCellPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
LayoutManager manager = getLayout();
if ((manager != null) && (manager instanceof GridBagLayout)) {
GridBagLayout layout = (GridBagLayout) manager;
g.setColor(getForeground());
Point p = layout.getLayoutOrigin();
int[][] sizes = layout.getLayoutDimensions();
int[] colWidths = sizes[0];
int[] rowHeights = sizes[1];
int width, height;
int xpos = p.x;
int ypos;
for (int x = 0; x < colWidths.length; x++) {
ypos = p.y;
width = colWidths[x];
for (int y = 0; y < rowHeights.length; y++) {
height = rowHeights[y];
g.drawRect(xpos, ypos, width - 1, height - 1);
g.drawRect(xpos + 1, ypos + 1, width - 3, height - 3);
ypos += height;
}
xpos += width;
}
}
}
If the user interface is added to an instance of the
GridBagCellPanel class, a dark border
appears around the edge of each cell in the grid,
as shown below. This illustrates that the column
containing the label is very large, and the gap
exists because the component is positioned on the
left side of its cell.
This example illustrates another important point related to
GridBagLayout: a component does not necessarily expand to
completely fill the cell or cells that it occupies. A component's size is
normally set to its preferred or minimum size, and in this case, the
component's preferred width is considerably smaller than the width of the
cell that it occupies. It's important to keep in mind this distinction
between a component's actual size and its display area, or the area
of the container reserved for that component. A component's display area is
the rectangular region defined by the cell or cells assigned to the
component. In this case, only a single cell was assigned to each component,
but as mentioned earlier, a cell can span multiple rows and/or columns.
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.