Here, layoutObj is a reference to the desired layout manager. If you wish to disable the
layout manager and position components manually, pass null for layoutObj. If you do
this, you will need to determine the shape and position of each component manually,
using the setBounds( ) method defined by Component. Normally, you will want to
use a layout manager.
Each layout manager keeps track of a list of components that are stored by their
names. The layout manager is notified each time you add a component to a container.
Whenever the container needs to be resized, the layout manager is consulted via its
minimumLayoutSize( ) and preferredLayoutSize( ) methods. Each component
that is being managed by a layout manager contains the getPreferredSize( ) and
getMinimumSize( ) methods. These return the preferred and minimum size required
to display each component. The layout manager will honor these requests if at all
possible, while maintaining the integrity of the layout policy. You may override
these methods for controls that you subclass. Default values are provided otherwise.
Java has several predefined LayoutManager classes, several of which are described
next. You can use the layout manager that best fits your application.
FlowLayout
FlowLayout is the default layout manager. This is the layout manager that the preceding
examples have used. FlowLayout implements a simple layout style, which is similar to
how words flow in a text editor. Components are laid out from the upper-left corner, left
to right and top to bottom. When no more components fit on a line, the next one appears
on the next line. A small space is left between each component, above and below, as well
as left and right. Here are the constructors for FlowLayout:
FlowLayout( )
FlowLayout(int how)
FlowLayout(int how, int horz, int vert)
The first form creates the default layout, which centers components and leaves five
pixels of space between each component. The second form lets you specify how each
line is aligned. Valid values for how are as follows:
FlowLayout.LEFT
FlowLayout.CENTER
FlowLayout.RIGHT
These values specify left, center, and right alignment, respectively. The third form
allows you to specify the horizontal and vertical space left between components in
horz and vert, respectively.
Here is a version of the CheckboxDemo applet shown earlier in this chapter,
modified so that it uses left-aligned flow layout.
// Use left-aligned flow layout.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
*/
public class FlowLayoutDemo extends Applet
implements ItemListener {
String msg = "";
Checkbox Win98, winNT, solaris, mac;
public void init() {
// set left-aligned flow layout
setLayout(new FlowLayout(FlowLayout.LEFT));
Win98 = new Checkbox("Windows 98/XP", null, true);
winNT = new Checkbox("Windows NT/2000");
solaris = new Checkbox("Solaris");
mac = new Checkbox("MacOS");
add(Win98);
add(winNT);
add(solaris);
add(mac);
// register to receive item events
Win98.addItemListener(this);
winNT.addItemListener(this);
solaris.addItemListener(this);
mac.addItemListener(this);
}
// Repaint when status of a check box changes.
public void itemStateChanged(ItemEvent ie) {
repaint();
}
// Display current state of the check boxes.
public void paint(Graphics g) {
msg = "Current state: ";
g.drawString(msg, 6, 80);
msg = " Windows 98/XP: " + Win98.getState();
g.drawString(msg, 6, 100);
msg = " Windows NT/2000: " + winNT.getState();
g.drawString(msg, 6, 120);
msg = " Solaris: " + solaris.getState();
g.drawString(msg, 6, 140);
msg = " Mac: " + mac.getState();
g.drawString(msg, 6, 160);
}
}
BorderLayout
The BorderLayout class implements a common layout style for top-level windows. It
has four narrow, fixed-width components at the edges and one large area in the center.
The four sides are referred to as north, south, east, and west. The middle area is called
the center. Here are the constructors defined by BorderLayout:
BorderLayout( )
BorderLayout(int horz, int vert)
The first form creates a default border layout. The second allows you to specify the
horizontal and vertical space left between components in horz and vert, respectively.
BorderLayout defines the following constants that specify the regions:
BorderLayout.CENTER BorderLayout.SOUTH
BorderLayout.EAST BorderLayout.WEST
BorderLayout.NORTH
When adding components, you will use these constants with the following form of
add( ), which is defined by Container:
void add(Component compObj, Object region);
Here, compObj is the component to be added, and region specifies where the component
will be added.
Here is an example of a BorderLayout with a component in each layout area:
// Demonstrate BorderLayout.
import java.awt.*;
import java.applet.*;
import java.util.*;
/*
*/
public class BorderLayoutDemo extends Applet {
public void init() {
setLayout(new BorderLayout());
add(new Button("This is across the top."),
BorderLayout.NORTH);
add(new Label("The footer message might go here."),
BorderLayout.SOUTH);
add(new Button("Right"), BorderLayout.EAST);
add(new Button("Left"), BorderLayout.WEST);
String msg = "The reasonable man adapts " +
"himself to the world;\n" +
"the unreasonable one persists in " +
"trying to adapt the world to himself.\n" +
"Therefore all progress depends " +
"on the unreasonable man.\n\n" +
" - George Bernard Shaw\n\n";
add(new TextArea(msg), BorderLayout.CENTER);
}
}
Using Insets
Sometimes you will want to leave a small amount of space between the container
that holds your components and the window that contains it. To do this, override
the getInsets( ) method that is defined by Container. This function returns an Insets
object that contains the top, bottom, left, and right inset to be used when the container
is displayed. These values are used by the layout manager to inset the components
when it lays out the window. The constructor for Insets is shown here:
Insets(int top, int left, int bottom, int right)
The values passed in top, left, bottom, and right specify the amount of space between the
container and its enclosing window.
The getInsets( ) method has this general form:
Insets getInsets( )
When overriding one of these methods, you must return a new Insets object that contains
the inset spacing you desire.
Here is the preceding BorderLayout example modified so that it insets its components
ten pixels from each border. The background color has been set to cyan to help make the
insets more visible.
// Demonstrate BorderLayout with insets.
import java.awt.*;
import java.applet.*;
import java.util.*;
/*
*/
public class InsetsDemo extends Applet {
public void init() {
// set background color so insets can be easily seen
setBackground(Color.cyan);
setLayout(new BorderLayout());
add(new Button("This is across the top."),
BorderLayout.NORTH);
add(new Label("The footer message might go here."),
BorderLayout.SOUTH);
add(new Button("Right"), BorderLayout.EAST);
add(new Button("Left"), BorderLayout.WEST);
String msg = "The reasonable man adapts " +
"himself to the world;\n" +
"the unreasonable one persists in " +
"trying to adapt the world to himself.\n" +
"Therefore all progress depends " +
"on the unreasonable man.\n\n" +
" - George Bernard Shaw\n\n";
add(new TextArea(msg), BorderLa
yout.CENTER);
}
// add insets
public Insets getInsets() {
return new Insets(10, 10, 10, 10);
}
}
GridLayout
GridLayout lays out components in a two-dimensional grid. When you instantiate
a GridLayout, you define the number of rows and columns. The constructors
supported by GridLayout are shown here:
GridLayout( )
GridLayout(int numRows, int numColumns )
GridLayout(int numRows, int numColumns, int horz, int vert)
The first form creates a single-column grid layout. The second form creates a grid
layout with the specified number of rows and columns. The third form allows you
to specify the horizontal and vertical space left between components in horz and vert,
respectively. Either numRows or numColumns can be zero. Specifying numRows as zero
allows for unlimited-length columns. Specifying numColumns as zero allows for
unlimited-length rows.
Here is a sample program that creates a 4×4 grid and fills it in with 15 buttons, each
labeled with its index:
// Demonstrate GridLayout
import java.awt.*;
import java.applet.*;
/*
*/
public class GridLayoutDemo extends Applet {
static final int n = 4;
public void init() {
setLayout(new GridLayout(n, n));
setFont(new Font("SansSerif", Font.BOLD, 24));
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
int k = i * n + j;
if(k > 0)
add(new Button("" + k));
}
}
}
}
CardLayout
The CardLayout class is unique among the other layout managers in that it stores
several different layouts. Each layout can be thought of as being on a separate index
card in a deck that can be shuffled so that any card is on top at a given time. This can
be useful for user interfaces with optional components that can be dynamically enabled
and disabled upon user input. You can prepare the other layouts and have them hidden,
ready to be activated when needed.
CardLayout provides these two constructors:
CardLayout( )
CardLayout(int horz, int vert)
The first form creates a default card layout. The second form allows you to specify the
horizontal and vertical space left between components in horz and vert, respectively.
Use of a card layout requires a bit more work than the other layouts. The cards are
typically held in an object of type Panel. This panel must have CardLayout selected as
its layout manager. The cards that form the deck are also typically objects of type Panel.
Thus, you must create a panel that contains the deck and a panel for each card in the deck.
Next, you add to the appropriate panel the components that form each card. You then add
these panels to the panel for which CardLayout is the layout manager. Finally, you add this
panel to the main applet panel. Once these steps are complete, you must provide some
way for the user to select between cards. One common approach is to include one push
button for each card in the deck.
When card panels are added to a panel, they are usually given a name. Thus, most
of the time, you will use this form of add( ) when adding cards to a panel:
void add(Component panelObj, Object name);
Here, name is a string that specifies the name of the card whose panel is specified
by panelObj.
After you have created a deck, your program activates a card by calling one of the
following methods defined by CardLayout:
void first(Container deck)
void last(Container deck)
void next(Container deck)
void previous(Container deck)
void show(Container deck, String cardName)
Here, deck is a reference to the container (usually a panel) that holds the cards, and
cardName is the name of a card. Calling first( ) causes the first card in the deck to be shown. To show the last card, call last( ). To show the next card, call next( ). To show
the previous card, call previous( ). Both next( ) and previous( ) automatically cycle
back to the top or bottom of the deck, respectively. The show( ) method displays the
card whose name is passed in cardName.
The following example creates a two-level card deck that allows the user to select
an operating system. Windows-based operating systems are displayed in one card.
Macintosh and Solaris are displayed in the other card.
// Demonstrate CardLayout.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
*/
public class CardLayoutDemo extends Applet
implements ActionListener, MouseListener {
Checkbox Win98, winNT, solaris, mac;
Panel osCards;
CardLayout cardLO;
Button Win, Other;
public void init() {
Win = new Button("Windows");
Other = new Button("Other");
add(Win);
add(Other);
cardLO = new CardLayout();
osCards = new Panel();
osCards.setLayout(cardLO); // set panel layout to card layout
Win98 = new Checkbox("Windows 98/XP", null, true);
winNT = new Checkbox("Windows NT/2000");
solaris = new Checkbox("Solaris");
mac = new Checkbox("MacOS");
// add Windows check boxes to a panel
Panel winPan = new Panel();
winPan.add(Win98);
winPan.add(winNT);
// Add other OS check boxes to a panel
Panel otherPan = new Panel();
otherPan.add(solaris);
otherPan.add(mac);
// add panels to card deck panel
osCards.add(winPan, "Windows");
osCards.add(otherPan, "Other");
// add cards to main applet panel
add(osCards);
// register to receive action events
Win.addActionListener(this);
Other.addActionListener(this);
// register mouse events
addMouseListener(this);
}
// Cycle through panels.
public void mousePressed(MouseEvent me) {
cardLO.next(osCards);
}
// Provide empty implementations for the other MouseListener methods.
public void mouseClicked(MouseEvent me) {
}
public void mouseEntered(MouseEvent me) {
}
public void mouseExited(MouseEvent me) {
}
public void mouseReleased(MouseEvent me) {
}
public void actionPerformed(ActionEvent ae) {
if(ae.getSource() == Win) {
cardLO.show(osCards, "Windows");
}
else {
cardLO.show(osCards, "Other");
}
}
}
Read more...