The Container class
Is an extension of the Component class
Object
\
Component \
Container
Can contain other AWT components and containers
Is abstract so it can never be directly instantiated
Has been subclassed to be the root of all AWT containers. Commonly used subclasses are:
Class
Description
Panel The simplest container. Provides space in which an application can attach any other component, including other panels.
ScrollPane A container which implements automatic horizontal and/or vertical scrolling
Window A container for a top-level window that has no borders and no menu bar. Useful subclasses are Dialog and Frame.
Maintains and controls a list of components it contains. Commonly used methods are:
Method
Usage
add()
Adds a component to the internal list
remove()
Removes a component from the internal list
removeAll()
Removes all components from the internal list
setLayout()
Sets the layout manager for the container
validate()
Causes the container to lay out its components again after a component has been added or removed
Notes:
Many methods are overloaded to accept a range of parameter types and values
As an extension of Component (and Object), all features of those classes are inherited
Layout managers
Are objects that control the size and visual arrangement of components within a container
Can be assigned to a container using its setLayout() method but only one layout manager can be in effect at any given time
Can be complex. The simpler ones (BorderLayout, FlowLayout, and GridLayout) are covered in this lesson. The harder ones (CardLayout and GridBagLayout) will be covered later.
BorderLayout
Can manage up to five components that are placed in named positions
Is the default layout manager for all Window containers (Frame and Dialog)
Arranges components as follows:
North
West
Center
East
South
Example:
import java.awt.*;
import java.awt.event.*;
public class App extends Frame implements WindowListener, ActionListener {
Button b1, b2, b3, b4, b5;
public static void main(String[] args) {
App myWindow = new App("Border Layout");
myWindow.setSize(250,150);
myWindow.setVisible(true);
}
public App(String title) {
super(title);
setLayout(new BorderLayout());
addWindowListener(this);
b1 = new Button("North");
add(b1, BorderLayout.NORTH);
b1.addActionListener(this);
b2 = new Button("West");
add(b2, BorderLayout.WEST);
b2.addActionListener(this);
b3 = new Button("Center");
add(b3, BorderLayout.CENTER);
b3.addActionListener(this);
b4 = new Button("East");
add(b4, BorderLayout.EAST);
b4.addActionListener(this);
b5 = new Button("South");
add(b5, BorderLayout.SOUTH);
b5.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
remove((Component)e.getSource());
validate();
}
public void windowClosing(WindowEvent e) {
dispose();
System.exit(0);
}
public void windowOpened(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
}Notes:
The sample declares five Button object references (b1 through b5)
In the constructor, setLayout() is explicitly coded but isn't really needed as BorderLayout is the default for a Frame
With BorderLayout, the add() method accepts a second parameter that specifies where the component is to be placed. The default location is BorderLayout.CENTER.
The actionPerformed() method removes the component that the user clicked and forces the window to be redrawn. The object cast is needed because the getSource() method returns a generic Object and the remove() method requires a Component.
BorderLayout preserves the width of components in the EAST and WEST positions and the height of components in the NORTH and SOUTH positions. The component in the CENTER is stretched to fill the remaining space. This can be seen by resizing the window during program execution.
FlowLayout
Adds components from left to right, starting a new row when the current row is filled
Automatically centers the component(s) within each row
Gives each component its preferred size and does not resize components when the container is resized
Is the default layout manager for all Panel containers (and all applets because they are Panel extensions)
Example:
import java.awt.*;
import java.awt.event.*;
public class App extends Frame implements WindowListener, ActionListener {
Button b1, b2, b3, b4;
public static void main(String[] args) {
App myWindow = new App("Flow Layout");
myWindow.setSize(200,200);
myWindow.setVisible(true);
}
public App(String title) {
super(title);
setLayout(new FlowLayout());
addWindowListener(this);
b1 = new Button("Button One");
add(b1);
b1.addActionListener(this);
b2 = new Button("Button Two");
add(b2);
b2.addActionListener(this);
b3 = new Button("This is Button Three");
add(b3);
b3.addActionListener(this);
b4 = new Button("Button Four");
add(b4);
b4.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
remove((Component)e.getSource());
validate();
}
public void windowClosing(WindowEvent e) {
dispose();
System.exit(0);
}
public void windowOpened(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
}Notes:
The sample declares four Button object references (b1 through b4)
In the constructor, setLayout() is called to set FlowLayout for the Frame
With FlowLayout, the add() method simply adds components to the container in a first-come, first-served basis
The actionPerformed() method removes the component that the user clicked and forces the window to be redrawn. The object cast is needed because the getSource() method returns a generic Object and the remove() method requires a Component.
FlowLayout preserves the height and width of all components. Resizing the window during program execution will result in components being rearranged but not resized.
GridLayout
Divides the container into a rectangular grid of equal sized cells
Places each component in a different cell. Rows are filled from left to right starting with the top row.
Resizes each component to completely fill its assigned cell
Example:
import java.awt.*;
import java.awt.event.*;
public class App extends Frame implements WindowListener, ActionListener {
Button b1, b2, b3, b4, b5, b6;
public static void main(String[] args) {
App myWindow = new App("Grid Layout (2 x 3)");
myWindow.setSize(250,250);
myWindow.setVisible(true);
}
public App(String title) {
super(title);
setLayout(new GridLayout(2,3));
setFont(new Font("San Serif", Font.BOLD, 20));
addWindowListener(this);
b1 = new Button("1");
add(b1);
b1.addActionListener(this);
b2 = new Button("2");
add(b2);
b2.addActionListener(this);
b3 = new Button("3");
add(b3);
b3.addActionListener(this);
b4 = new Button("4");
add(b4);
b4.addActionListener(this);
b5 = new Button("5");
add(b5);
b5.addActionListener(this);
b6 = new Button("6");
add(b6);
b6.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
remove((Component)e.getSource());
validate();
}
public void windowClosing(WindowEvent e) {
dispose();
System.exit(0);
}
public void windowOpened(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
}Notes:
The sample declares six Button object references (b1 through b6)
In the constructor, setLayout() is called to set a GridLayout having 2 rows and 3 columns for the Frame
With FlowLayout, the add() method simply adds components to the next cell in the container (going left to right, row by row)
The actionPerformed() method removes the component that the user clicked and forces the window to be redrawn. The object cast is needed because the getSource() method returns a generic Object and the remove() method requires a Component.
GridLayout ignores the height and width of all components. They are resized to fit their cell. Resizing the window during program execution will result in components being resized but not rearranged.
Satisfying complex GUI requirements
Nested containers can be used to satisfy many complex graphical interface requirements. For example, a Panel with a GridLayout might be placed in the center of a Frame having a BorderLayout to produce something like this:
North
West
1
2
3
East
4
5
6
7
8
9
South
The possibilities are nearly infinite.
Review questions
Which of these layout managers can be used with a single container to show 6 components at one time? (choose two)
BorderLayout
FlowLayout
GridLayout
If myPanel references a Panel object, code a single statement to set the panel's layout manager so it will display components in three rows of five columns each.
Assume that myFrame references a Frame having a BorderLayout. Which of the following would correctly add a Button object to the center of myFrame? (choose two)
myFrame.add(new Button("Hello"));
myFrame.add("Hello");
myFrame.add(new Button("Hello"), CENTER);
myFrame.add(new Button("Hello"), BorderLayout.CENTER);
myFrame.add(new Button("Hello"), 1, 1);
Which one statement is true about attempting to compile and run the application shown below? The line numbers are for reference purposes only.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30import java.awt.*;
import java.awt.event.*;
public class App extends Frame implements WindowListener{
public static void main(String[] args) {
App myApp = new App();
myApp.setVisible(true);
}
public App() {
setSize(300, 300);
addWindowListener(this);
setFont(new Font("San Serif", Font.BOLD, 36));
Button b = new Button("XYZ");
add(b, BorderLayout.EAST);
}
public void windowClosing(WindowEvent e) {
dispose();
System.exit(0);
}
public void windowOpened(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
}
Compilation fails at line 16 because no layout manager has been specified
Compilation succeeds but nothing is displayed
A single button with the text "XYZ" will entirely fill the window on the screen
A single button with the text "XYZ" will occupy the right side of the window on the screen. The button will be taller than it is wide.
A single button with the text "XYZ" will occupy the right side of the window on the screen. If the window is resized to be wider, the button will also become wider.