What We Will Cover
Illuminations
Questions on Assignments?
^ top
9.1: Graphical-User Interfaces
Objectives
At the end of the lesson the student will be able to:
- Describe the three categories of GUI components
- Collect user input in an input dialog box
- Show messages using a message dialog
|
^ top
9.1.1: About Graphical User Interfaces (GUIs)
- Graphical User Interface (GUI) -- pronounced "gooey"
- Graphical: not just text or characters but includes windows, menus, buttons, etc.
- User: person using the program via mouse, keyboard, etc.
- Interface: interaction with the program using visual controls, widgets, etc.
- GUIs present a user-friendly way to interact with a program
- Most modern programs use a GUI
- Typical graphical components include:
- Window: portion of screen providing an area for the other components
- Button: looks like a button that can be pressed
- Labels: Displays text or images in the window
- Text field: place where users can type values

Java's GUI Libraries
- GUIs are built from objects called components
- Also called controls or widgets
- Users interact with GUI components using a mouse, keyboard or other input device
- Java provides two sets of GUI components: AWT and Swing
- AWT (Abstract Window Toolkit) is the older set of components
- Relies on the underlying visual components of the operating system
- GUIs look different on every operating system
- Swing (like the dance) is the newer set of components
- Extends AWT components and adds new capabilities
- Components draw their own visual shapes on the screen
- GUIs look about the same on every operating system
- The inheritance hierarchy below shows how Swing extends AWT
- Note that Swing components all start with the letter "J"
- We will focus on how to use Swing components
Inheritance Hierarchy for GUI Components

^ top
9.1.2: Component Categories
- GUI components fall into three categories
Top-Level Containers
- Basic window structure that ties the GUI into the operating system
- Includes capabilities such as borders and resizability
- Holds intermediate containers and atomic components
- Every GUI program must have one top-level container
- Some of the frequently used components are:
| Component |
Description |
| JFrame |
A top-level window with a title, border and buttons for closing, maximizing/restoring and iconifying the window. |
| JApplet |
Container for applets, which are small programs that run inside a Web browser |
| JOptionPane |
Limited window that makes it easy to pop up a standard dialog box that prompts users for a value or informs them of something. |
Intermediate Containers
- Graphical object displayed in a top-level container
- Can also hold other intermediate containers and atomic components
- Used to simplify placement of atomic components
- Some of the frequently used components are:
| Component |
Description |
| JPanel |
Provides a general-purpose container for atomic components and other intermediate containers. |
| JRootPane |
A container used behind the scenes by JFrame, JApplet and other containers. |
| JScrollPane |
A container that provides a scrollable view of a component. |
Atomic Components
- Graphical objects used to accept input or display information
- Must be placed in a container using the
add method
- Some of the frequently used components are:
| Component |
Description |
| JButton |
Display area that triggers an event when clicked. |
| JComboBox |
Drop-down list of items from which the user can make a selection by clicking an item in the list or possibly by typing into a box. |
| JCheckBox |
GUI component that can be selected or deselected and displays its state to the user as a checked square. |
| JRadioButton |
GUI component that can be selected or deselected and displays its state to the user as a filled or unfilled circle. |
| JLabel |
Display area for text or icons |
| JTextField |
Single-line display and input area for the user to enter data from the keyboard. |
| JTextArea |
Multi-line display and input area for the user to enter data from the keyboard. |
Further Information
^ top
9.1.3: Example GUI Using JOptionPane
- One type of GUI window is known as a dialog box
- Dialogs provide a simple "popup" type of interaction with users
- JOptionPane provides several static methods for constructing dialogs
- Code for dialogs can be minimal
- For instance, to collect text input from a dialog:
String inputString = JOptionPane.showInputDialog(
"Enter your first name:");
Produces the following input dialog

Most dialogs are small windows with minimal options like the above
For Example
- Lets create a simple program to ask for and display a name
- We will use three types of dialog boxes in sequence:
showInputDialog: ask for name
showConfirmDialog: verify entry
showMessageDialog: display results
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import javax.swing.JOptionPane;
public class NameApp {
public static void main(String[] args) {
String inputString = JOptionPane.showInputDialog(
"Enter your first name: ");
int choice = JOptionPane.showConfirmDialog(null,
"Are you sure?");
String message = "First name: " + inputString + "\n"
+ "Choice: " + choice + "\n"
+ "Press enter to exit.";
JOptionPane.showMessageDialog(null, message);
System.exit(0);
}
}
|
Input with showInputDialog()
- Use the showInputDialog method of JOptionPane to get text input from users
- In the above example, we created the first dialog like this:
String inputString = JOptionPane.showInputDialog(
"Enter your first name:");
Essentially a single line of code
Input with showConfirmDialog()
- Use the showConfirmDialog method of JOptionPane to get text input from users
- In the above example, we created the first dialog like this:
JOptionPane.showConfirmDialog(null, "Are you sure?");
Output with showMessageDialog()
String message = "First name: " + inputString + "\n\n"
+ "Press enter to exit.";
JOptionPane.showMessageDialog(null, message);
Note that you can use both showInputDialog() and showConfirmDialog() for output as well
Commonly-Used Methods of JOptionPane
^ top
9.1.4: Dialog Arguments
- Most methods of
JOptionPane are overloaded to accept arguments
- These options control dialog placement, messages and icons displayed, and title-bar wording
- Both
showInputDialog and showMessageDialog accept the arguments listed in the table below
showInputDialog can accept four arguments
JOptionPane.showInputDialog(parentComponent, messageString,
titleString, messageTypeInt);
To display a different dialog without an input field:
JOptionPane.showMessageDialog(parent, message);
If the parent component is unknown, you can use null for that argument
JOptionPane.showMessageDialog(null, "Hello, world!");
You will need to look up the exact usage in the JOptionPane API documentation
Commonly-Used Arguments in JOptionPane Methods
| Argument |
Description |
| parentComponent |
An object representing the frame of the dialog box and controls its placement on the screen. If null is used, the dialog is centered on the screen. |
| messageString |
A descriptive message displayed in the dialog box. |
| titleString |
A title typically placed in the title bar above the dialog box. |
| messageTypeInt |
Indicates the type of icon to display in the dialog box. Use one of the fields of JOptionPane to choose the icon. |
Icons provided by JOptionPane
| Icon |
Message Type |
Description |
 |
ERROR_MESSAGE |
Displays an error icon. |
 |
INFORMATION_MESSAGE |
Displays an information icon. |
 |
WARNING_MESSAGE |
Displays an warning icon. |
 |
QUESTION_MESSAGE |
Displays an question icon. |
| |
PLAIN_MESSAGE |
Does not display an icon. |
Further Information
^ top
9.1.5: Summary
- Graphical user interfaces (GUIs) present a user-friendly way to interact with a program
- GUIs are built from objects called components
- Java provides special libraries for implementing GUI interfaces, the newer of which is called Swing
- GUI components fall into three categories:
- Top-level containers: basic window structure that ties the GUI into the operating system
- Intermediate containers: used to hold other components
- Atomic components: graphical objects used to accept input or display information
- You can create simple GUIs using JOptionPane
- JoptionPane produces "popup" dialog boxes for simple interactions with users
- Code for dialogs can be minimal and is usually coded using "one-liners"
String inputString = JOptionPane.showInputDialog(
"Enter your first name:");
Which produces the following input dialog

Most methods of JOptionPane are overloaded to accept arguments
These options control dialog placement, messages and icons displayed, and title-bar wording
You will need to look up the exact usage in the Java API documentation
^ top
Exercise 9.1
Take one minute to prepare answers to the following questions:
- What are the three types of GUI components?
- What package(s) must be imported to create dialogs?
- How many statements are typically needed to code a dialog box?
^ top
9.2: Building a Simple GUI Application
Objectives
At the end of the lesson the student will be able to:
- Work with frames
- Add a panel to a frame
- Add buttons to a panel
- Handle button events
|
^ top
9.2.1: Working With Frames
- A
JFrame is a top-level component commonly used with Java applications
- It inherits many methods from both the
Frame and Window class
- By default, all frames are 0 x 0 pixels and open in the top left corner of the screen
- To code a GUI application, you typically extend
JFrame
public class HelloWindow extends JFrame
To close a JFrame, you often use the method setDefaultCloseOperation()
setDefaultCloseOperation(EXIT_ON_CLOSE);
For Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import javax.swing.*;
public class HelloFrame extends JFrame {
public final static int X_LOC = 100, Y_LOC = 100,
WIDTH = 300, HEIGHT = 150;
public HelloFrame() {
super("Hello Frame Application");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
setVisible(true);
}
public static void main(String[] args) {
new HelloFrame();
}
}
|
Commonly Used Methods of the Frame Class
Commonly Used Methods of the Window Class
| Method |
Description |
| hide() |
Hides this window without closing it. |
| pack() |
Size this window to fit the preferred size and layout of its components. |
| show() |
Makes this window visible. |
Commonly Used Methods of the Component Class
^ top
9.2.2: Adding a Panel to a Frame
- After you create a frame, you need to add components to it
- One component you often add is a
JPanel
- The
JPanel is an intermediate container
- You use a
JPanel to contain atomic components and other intermediate containers
- The code to add a
JPanel to the content pane of a JFrame is:
JPanel panel = new JPanel();
Container contentPane = getContentPane();
contentPane.add(panel);
You can add components, such as buttons, directly to the content pane
However, you often add components to a panel and then add the panel to the content pane
This helps you to group components so your code is easier to read and understand
Methods to Add Components to the Content Pane
^ top
9.2.3: Adding Buttons to a Panel
- Button: a component the user clicks to trigger a specific action
- Basic buttons are created with class JButton
- You can add a button to a panel like this:
JPanel panel = new JPanel();
JButton button = new JButton("Hello");
panel.add(button);
The first two statements create the panel and the button
The third statement adds the button to the panel
The following example adds two buttons to a panel and then adds the panel to a frame
For Example
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
|
import java.awt.*;
import javax.swing.*;
public class HelloFrame2 extends JFrame {
public final static int X_LOC = 100, Y_LOC = 100,
WIDTH = 300, HEIGHT = 150;
private JButton helloButton;
private JButton exitButton;
public HelloFrame2() {
super("Hello Frame Application");
setDefaultCloseOperation(EXIT_ON_CLOSE);
helloButton = new JButton("Hello");
exitButton = new JButton("Exit");
JPanel panel = new JPanel();
panel.add(helloButton);
panel.add(exitButton);
Container contentPane = getContentPane();
contentPane.add(panel);
setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
setVisible(true);
}
public static void main(String[] args) {
new HelloFrame2();
}
}
|
Commonly Used Constructors of the JButton Class
Some Methods of the JButton Class
^ top
9.2.4: Handling Button Events
- So far the buttons do not respond when the user clicks them
- To make them respond, you need to add code that is executed when a button is clicked
- This is known as event-handling code
- The following only shows how to handle button events
- However, you use the same principles to handle other types of events
How To Handle Action Events
- Specify that a class implements the
ActionListener interface
public class HelloFrame3 extends JFrame
implements ActionListener {
- Register the
ActionListener object with the button by calling the addActionListener() method
helloButton.addActionListener(this);
- Implement the
ActionListener interface by coding an actionPerformed() method
public void actionPerformed(ActionEvent ae) {
Object source = ae.getSource();
if (source == helloButton) {
JOptionPane.showMessageDialog(this, "Hello");
} else if (source == exitButton) {
System.out.println("Goodbye!");
System.exit(0);
} else {
System.out.println("Unknown ActionEvent");
}
}
Identifying the Component Firing the Event
- Note that the
getSource() method of an event object returns the memory location of the object that generated the event.
- This allows you to compare the value returned by
getSource() against references to components
Object source = ae.getSource();
if (source == helloButton) {
// now you know the helloButton was pressed
}
The above code allows you to identify the component that fired the event
For Example
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloFrame3 extends JFrame
implements ActionListener {
public final static int X_LOC = 100, Y_LOC = 100,
WIDTH = 300, HEIGHT = 150;
private JButton helloButton;
private JButton exitButton;
public HelloFrame3() {
super("Hello Frame Application");
setDefaultCloseOperation(EXIT_ON_CLOSE);
helloButton = new JButton("Hello");
helloButton.addActionListener(this);
exitButton = new JButton("Exit");
exitButton.addActionListener(this);
JPanel panel = new JPanel();
panel.add(helloButton);
panel.add(exitButton);
Container contentPane = getContentPane();
contentPane.add(panel);
setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
Object source = ae.getSource();
if (source == helloButton) {
JOptionPane.showMessageDialog(this, "Hey");
} else if (source == exitButton) {
System.out.println("Goodbye!");
System.exit(0);
} else {
System.out.println("Unknown ActionEvent");
}
}
public static void main(String[] args) {
new HelloFrame3();
}
}
|
^ top
9.2.5: Summary
- Most Java GUI applications inherit from a
JFrame
public class HelloWindow extends JFrame
To close a JFrame, you often use the method setDefaultCloseOperation()
setDefaultCloseOperation(EXIT_ON_CLOSE);
To add components to a JFrame, you often use a JPanel as an intermediate container
To add button components, you use the JButton class
The code for adding buttons is something like:
JPanel panel = new JPanel();
helloButton = new JButton("Hello");
panel.add(helloButton);
Container contentPane = getContentPane();
contentPane.add(panel);
To make a button respond when clicked, you add an ActionEvent handler
There are three steps for adding an ActionEvent handler:
- Specify that a class implements the
ActionListener interface
public class HelloFrame3 extends JFrame
implements ActionListener {
- Register the
ActionListener object with the button by calling the addActionListener() method
helloButton.addActionListener(this);
- Implement the
ActionListener interface by coding the actionPerformed() method
public void actionPerformed(ActionEvent ae) {
// event handling code
}
- You handle other events using code like that used for the
ActionEvent
^ top
Exercise 9.2
Take one minute to prepare answers to the following questions:
- How does a component, like a
JButton, signal that it was used?
- How does an object become a listener?
- How does an event get passed to a listener object?
- What gets executed when an event occurs?
^ top
9.3: Laying Out Components
Objectives
At the end of the lesson the student will be able to:
- Describe the purpose of a layout manager
- Use the Flow layout Manager
- Use the Border layout Manager
- Describe how to organize layout code
|
^ top
9.3.1: About Layout Managers
- When you add multiple components to a GUI, your program has to set the size and position of each component.
- You use a layout manager to provide this functionality
- Each
Container object has a default layout manager
- For instance, a
JPanel uses a FlowLayout manager
- On the other hand, content panes like those used in
JFrame use a BorderLayout manager
- Normally, you only need to think about layout managers when:
- You add components to a container
- You do not like the default layout manager
- To add a new layout manager, you use the
setLayout() method of the container
- We will discuss two commonly used layout managers in the next few sections
Method of the Container Class Used to Change Layout Managers
^ top
9.3.2: Using the FlowLayout Manager
- The
FlowLayout manager is the default for a JPanel
- It adds components to the top of a container moving from left to right
- When a container runs out of horizontal space, it starts adding components to a new row
- You can adjust the alignment of the components on a row using the alignment fields of the
FlowLayout class:
FlowLayout.CENTER
FlowLayout.LEFT
FlowLayout.RIGHT
For Example
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
30
31
32
33
34
35
36
37
38
39
40
41
|
import java.awt.*;
import javax.swing.*;
public class FlowLayoutApp extends JFrame {
public final static int X_LOC = 100, Y_LOC = 100,
WIDTH = 300, HEIGHT = 150;
private JButton button1;
private JButton button2;
private JButton button3;
private JButton button4;
private JButton button5;
public FlowLayoutApp() {
super("Flow Layout Application");
setDefaultCloseOperation(EXIT_ON_CLOSE);
button1 = new JButton("Button One");
button2 = new JButton("Button Two");
button3 = new JButton("Button with a long name");
button4 = new JButton("Button Four");
button5 = new JButton("5");
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.LEFT));
panel.add(button1);
panel.add(button2);
panel.add(button3);
panel.add(button4);
panel.add(button5);
Container contentPane = getContentPane();
contentPane.add(panel);
setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
setVisible(true);
}
public static void main(String[] args) {
new FlowLayoutApp();
}
}
|
Commonly Used Constructors of the FlowLayout Class
| Constructor |
Description |
| FlowLayout() |
Constructs a new FlowLayout with a centered alignment. |
| FlowLayout(intAlign) |
Constructs a new FlowLayout with the specified alignment. |
More Information
^ top
9.3.3: Using the BorderLayout Manager
- You can align buttons left or right with a
FlowLayout manager
- However, you cannot place buttons at the bottom of the container
- To do that, you use the
BorderLayout manager
- With a
BorderLayout manager, you can place components in 5 separate regions

- To create a new BorderLayout, you typically call its no-arg constructor:
BorderLayout bl = new BorderLayout()
To add the BorderLayout to a container you use the setLayout() method
panel.setLayout(new BorderLayout());
The default layout manager of a content pane is BorderLayout
To add a component to a container using a BorderLayout, you specify:
add(ComponentObj, regionField);
If you do not specify the region, the component is added to the center region
For Example
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
30
31
32
33
34
35
36
37
38
39
40
41
|
import java.awt.*;
import javax.swing.*;
public class BorderLayoutApp extends JFrame {
public final static int X_LOC = 100, Y_LOC = 100,
WIDTH = 300, HEIGHT = 150;
private JButton buttonNorth;
private JButton buttonSouth;
private JButton buttonEast;
private JButton buttonWest;
private JButton buttonCenter;
public BorderLayoutApp() {
super("BorderLayout Application");
setDefaultCloseOperation(EXIT_ON_CLOSE);
buttonNorth = new JButton("North");
buttonSouth = new JButton("South");
buttonEast = new JButton("East");
buttonWest = new JButton("West");
buttonCenter = new JButton("Center");
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(buttonNorth, BorderLayout.NORTH);
panel.add(buttonSouth, BorderLayout.SOUTH);
panel.add(buttonEast, BorderLayout.EAST);
panel.add(buttonWest, BorderLayout.WEST);
panel.add(buttonCenter, BorderLayout.CENTER);
Container contentPane = getContentPane();
contentPane.add(panel);
setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
setVisible(true);
}
public static void main(String[] args) {
new BorderLayoutApp();
}
}
|
Commonly Used Constructors of the BorderLayout Class
More Information
^ top
9.3.4: Combining Layout Managers
- The
FlowLayout manager lets you align components left, center or right
- However, it does not let you place components at the bottom of the container
- On the other hand, the BorderLayout manager lets you put components at the bottom
- However, you can only place one component at the bottom
- To get multiple components at the bottom of a window, you must combine layout managers

- Since you can only have one layout manager per container, you must have multiple containers to get the effect of multiple layouts
- The following code shows how you add two layouts together
- The first container is named
firstPanel and uses a BorderLayout
buttonNorth = new JButton("North");
buttonEast = new JButton("East");
buttonWest = new JButton("West");
buttonCenter = new JButton("Center");
JPanel firstPanel = new JPanel();
firstPanel.setLayout(new BorderLayout());
firstPanel.add(buttonNorth, BorderLayout.NORTH);
firstPanel.add(buttonEast, BorderLayout.EAST);
firstPanel.add(buttonWest, BorderLayout.WEST);
firstPanel.add(buttonCenter, BorderLayout.CENTER);
The second container is named secondPanel and uses a FlowLayout
buttonSouth1 = new JButton("South 1");
buttonSouth2 = new JButton("South 2");
JPanel secondPanel = new JPanel();
secondPanel.setLayout(
new FlowLayout(FlowLayout.RIGHT));
secondPanel.add(buttonSouth1);
secondPanel.add(buttonSouth2);
We then add the secondPanel to the firstPanel
firstPanel.add(secondPanel, BorderLayout.SOUTH);
Thus you combine layouts by nesting them inside another container
The complete code is shown below
For Example
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
import java.awt.*;
import javax.swing.*;
public class CombinedLayoutApp extends JFrame {
public final static int X_LOC = 100, Y_LOC = 100,
WIDTH = 300, HEIGHT = 150;
private JButton buttonNorth;
private JButton buttonEast;
private JButton buttonWest;
private JButton buttonCenter;
private JButton buttonSouth1;
private JButton buttonSouth2;
public CombinedLayoutApp() {
super("Combined Layout Application");
setDefaultCloseOperation(EXIT_ON_CLOSE);
buttonNorth = new JButton("North");
buttonEast = new JButton("East");
buttonWest = new JButton("West");
buttonCenter = new JButton("Center");
JPanel firstPanel = new JPanel();
firstPanel.setLayout(new BorderLayout());
firstPanel.add(buttonNorth, BorderLayout.NORTH);
firstPanel.add(buttonEast, BorderLayout.EAST);
firstPanel.add(buttonWest, BorderLayout.WEST);
firstPanel.add(buttonCenter, BorderLayout.CENTER);
buttonSouth1 = new JButton("South 1");
buttonSouth2 = new JButton("South 2");
JPanel secondPanel = new JPanel();
secondPanel.setLayout(
new FlowLayout(FlowLayout.RIGHT));
secondPanel.add(buttonSouth1);
secondPanel.add(buttonSouth2);
firstPanel.add(secondPanel, BorderLayout.SOUTH);
Container contentPane = getContentPane();
contentPane.add(firstPanel);
setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
setVisible(true);
}
public static void main(String[] args) {
new CombinedLayoutApp();
}
}
|
^ top
9.3.5: Other Layout Managers
Java provides other layout managers you can research and use including:
- BoxLayout: positions components in a single row or column
- CardLayout: lets you create an area that can contain different components at different times
- GridBagLayout: places components in a grid and allows some components to span more than one cell
- GridLayout: displays components with equal size in a row-column layout like a spreadsheet
- SpringLayout: allows you to specify precise relationships between the edges of components
More Information
^ top
9.3.6: Absolute Positioning
- It is possible to do without a layout manager and use absolute positioning
- However, you should use a layout manager if at all possible
- Not using a layout manager restricts the user interface and usually makes a substandard interface
- To show the components optimally, you often need to make the frame a fixed size and not resizeable
- A fixed-size frame can interfere with other applications the user is running
- To get a feel for these limitations, run the following example
Example of Absolute Positioning
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
import java.awt.*;
import javax.swing.*;
public class AbsoluteApp extends JFrame {
public final static int X_LOC = 100, Y_LOC = 100,
WIDTH = 300, HEIGHT = 170;
private JButton button1;
private JButton button2;
private JButton button3;
private JButton button4;
private JButton button5;
public AbsoluteApp() {
super("Absolute Positioning Application");
setDefaultCloseOperation(EXIT_ON_CLOSE);
button1 = new JButton("Button One");
button2 = new JButton("Button Two");
button3 = new JButton("Button with a long name");
button4 = new JButton("Button Four");
button5 = new JButton("5");
button1.setBounds(10, 10, 100, 50);
button2.setBounds(120, 10, 100, 50);
button3.setBounds(230, 10, 150, 50);
button4.setBounds(10, 70, 100, 50);
button5.setBounds(120, 70, 50, 50);
JPanel panel = new JPanel();
panel.setLayout(null);
panel.add(button1);
panel.add(button2);
panel.add(button3);
panel.add(button4);
panel.add(button5);
Container contentPane = getContentPane();
contentPane.add(panel);
setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
setVisible(true);
}
public static void main(String[] args) {
new AbsoluteApp();
}
}
|
- To remove the layout manager, you set the layout to
null
panel.setLayout(null);
Now you need to set the position and size of each component individually
button1.setBounds(10, 10, 100, 50);
More Information
^ top
9.3.7: Summary
- When you add multiple components to a GUI, your program has to set the size and position of each component
- You use a layout manager to provide this functionality
- Normally, you only need to think about layout managers when:
- You add components to a container
- You do not like the default layout manager
- To set a new layout for a container, you use the
setLayout() method
- To set a new
FlowLayout for a panel, you code something like:
panel.setLayout(new FlowLayout(FlowLayout.LEFT));
To set a new BorderLayout for a panel, you code something like:
panel.setLayout(new BorderLayout());
To add a component to a container using a BorderLayout, you code something like:
panel.add(button1, BorderLayout.NORTH);
If you do not specify the region, the component is added to the center region
You can combine layout managers using multiple containers
- One container is added to another container
firstPanel.add(secondPanel, BorderLayout.SOUTH);
Java has other layout managers you can use
Also, you can remove the layout manager and set all the component positions and sizes individually
However, you produce more professional and user friendly applications by using a layout manager
^ top
Exercise 9.3
Take one minute to prepare answers to the following questions:
- How are components positioned with a
BorderLayout manager?
- How are components positioned with a
FlowLayout manager?
^ top
9.4: Structuring Event Handling Code
Objectives
At the end of the lesson the student will be able to:
- Distinguish among an event, an event source, an event object, and an event listener
- List four options for structuring the classes that implement the listener interface for an event
- Explain the difference between an inner class and an anonymous inner class
- Explain the benefit of using adapter classes rather than implementing listener interfaces
|
^ top
9.4.1: About Event Handling
- Most GUI programs use events and event handlers
- An event in a GUI is an object representing an action like:
- Clicking a mouse button
- Dragging the mouse
- Pressing a key on the keyboard
- Or any other event expected to produce an action
Event-Firing and Listening

Terminology
- Firing an event: when an object creates an event object
- Listener: an object that waits for events to occur
- Event handler: a method that responds to an event
Event Classes
- Event classes define events that are triggered when users do things
- Components, like
JButton, create the events in response to user actions
- Following is an inheritance hierarchy of some Event classes:
java.lang.Object
|
+--java.util.EventObject
|
+--java.awt.AWTEvent
|
+--java.awt.event.ActionEvent
|
+--java.awt.event.AdjustmentEvent
|
+--java.awt.event.ItemEvent
|
+--java.awt.event.ComponentEvent
|
+--java.awt.event.ContainerEvent
|
+--java.awt.event.FocusEvent
|
+--java.awt.event.PaintEvent
|
+--java.awt.event.WindowEvent
|
+--java.awt.event.InputEvent
|
+--java.awt.event.KeyEvent
|
+--java.awt.event.MouseEvent
Event-listener Interfaces
- To handle an event, an object must become an event listener
implements ActionListener
So that any object can become a listener, Java uses interfaces to declare listeners
A listener has one or more methods that are called when events occur
public void actionPerformed(ActionEvent ae);
Event objects are passed to the listener by calling a listener method
Programmers implement the methods defined in the interface
While implementing the method, the programmer writes the event-handling code
A listener must register with an event-producing component
exitButton.addActionListener(this);
Some of the commonly used listener interfaces are shown below
java.util.EventListener
|
+--java.awt.event.ActionListener
|
+--java.awt.event.AdjustmentListener
|
+--java.awt.event.ComponentListener
|
+--java.awt.event.ContainerListener
|
+--java.awt.event.FocusListener
|
+--java.awt.event.ItemListener
|
+--java.awt.event.KeyListener
|
+--java.awt.event.MouseListener
|
+--java.awt.event.MouseMotionListener
|
+--java.awt.event.TextListener
|
+--java.awt.event.WindowListener
^ top
9.4.2: Organizing Event Handling Code
- The basic procedure for handling events is straightforward
- Implement the listener interface for the event in some class
- Register an instance of the listener class to the event source by calling the appropriate addeventListener method
- Code the required methods of the listener interface
- The basic procedure for handling events is also very flexible
- An event listener can be any object that implements the listener interface
- As a result, you can place the event-handling code in many different locations
- We will look at placing the code in the locations listed below
- Along the ay we learn about inner and anonymous inner classes
Some Options for Implementing the Listener Interface
- Implement it in a
JFrame or JPanel
- Implement it in a separate class
- Implement it in an inner class
- Implement it as an anonymous inner class
^ top
9.4.3: Using the Component Container
- Perhaps the easiest way to implement a listener interface is in the container for the components generating the events
- This is the technique we have used so far in our examples and it works well for containers like
JFrame and JPanel
- When using this technique, you implement the listener interface when coding the class
public class HelloFrame3 extends JFrame
implements ActionListener {
Within the container class, you can specify the this keyword as the parameter to the method that registers the listener
helloButton.addActionListener(this);
Within the container class you code the methods required by the interface
public void actionPerformed(ActionEvent ae) {
Object source = ae.getSource();
if (source == helloButton) {
JOptionPane.showMessageDialog(this, "Hello");
} else if (source == exitButton) {
System.out.println("Goodbye!");
System.exit(0);
} else {
System.out.println("Unknown ActionEvent");
}
}
When you use this technique with multiple components, you can use the getSource() method to determine which component fired the event
The getSource() method of an event object returns the memory location of the object that generated the event.
This allows you to compare the value returned by getSource() against references to components
Object source = ae.getSource();
if (source == helloButton) {
// now you know the helloButton was pressed
}
Example Using the Component Container
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloFrame3 extends JFrame
implements ActionListener {
public final static int X_LOC = 100, Y_LOC = 100,
WIDTH = 300, HEIGHT = 150;
private JButton helloButton;
private JButton exitButton;
public HelloFrame3() {
super("Hello Frame Application");
setDefaultCloseOperation(EXIT_ON_CLOSE);
helloButton = new JButton("Hello");
helloButton.addActionListener(this);
exitButton = new JButton("Exit");
exitButton.addActionListener(this);
JPanel panel = new JPanel();
panel.add(helloButton);
panel.add(exitButton);
Container contentPane = getContentPane();
contentPane.add(panel);
setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
Object source = ae.getSource();
if (source == helloButton) {
JOptionPane.showMessageDialog(this, "Hey");
} else if (source == exitButton) {
System.out.println("Goodbye!");
System.exit(0);
} else {
System.out.println("Unknown ActionEvent");
}
}
public static void main(String[] args) {
new HelloFrame3();
}
}
|
^ top
9.4.4: Using Separate Classes
- You can use separate classes for the components and the code that handles component events
- Using this technique, you do not need to use
getSource() to determine which component fired the event
- Instead, each component has its own event handling class
class HelloButtonListener implements ActionListener
The major problem with this technique is that the event handler code does not have direct access to the component
As a result, you must provide a way for the event listener to access the component
The easiest way to do that is to pass the component reference to the constructor of event handler
Then you save the component reference as an instance variable
private JButton button;
public HelloButtonListener(JButton buttonRef) {
button = buttonRef;
}
If the component needs to interact with other components, you will need to pass those references as well
Example Using Separate Classes
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloFrame4 extends JFrame {
public final static int X_LOC = 100, Y_LOC = 100,
WIDTH = 300, HEIGHT = 150;
public HelloFrame4() {
super("Hello Frame Application");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton helloButton = new JButton("Hello");
helloButton.addActionListener(
new HelloButtonListener(helloButton));
JButton exitButton = new JButton("Exit");
exitButton.addActionListener(
new ExitButtonListener(exitButton));
JPanel panel = new JPanel();
panel.add(helloButton);
panel.add(exitButton);
Container contentPane = getContentPane();
contentPane.add(panel);
setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
setVisible(true);
}
public static void main(String[] args) {
new HelloFrame4();
}
}
class HelloButtonListener implements ActionListener {
private JButton button;
public HelloButtonListener(JButton buttonRef) {
button = buttonRef;
}
public void actionPerformed(ActionEvent ae) {
JOptionPane.showMessageDialog(button, "Hey");
}
}
class ExitButtonListener implements ActionListener {
private JButton button;
public ExitButtonListener(JButton buttonRef) {
button = buttonRef;
}
public void actionPerformed(ActionEvent ae) {
System.out.println("Goodbye!");
System.exit(0);
}
}
|
Simplifying Listeners with Adaptor Classes
- Some listener interfaces have many methods that must be implemented
- For example, a WindowListener has seven methods that must be implemented
- Yet, you often only want to use one of the methods
- One way to simplify coding these listener interfaces is to use an adaptor class
- An adaptor class implements all the methods of a listener interface with empty methods
- For example, the WindowAdapter class looks something like:
public void windowClosing(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
Using an adaptor class, you can implement only those methods you need
import java.awt.event.*;
public class WinHandler extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
Java has adaptor classes for listener interfaces requiring more than one method
^ top
9.4.5: Using Inner Classes
- One way to reduce the complexity of passing references to listener classes is to use an inner class
- An inner class is a class that is contained within another class
- An inner class has access to all members of its containing class
- This makes inner classes a useful solution for implementing event listeners
Example Using Inner Classes
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloFrame5 extends JFrame {
public final static int X_LOC = 100, Y_LOC = 100,
WIDTH = 300, HEIGHT = 150;
public HelloFrame5() {
super("Hello Frame Application");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton helloButton = new JButton("Hello");
helloButton.addActionListener(
new HelloButtonListener());
JButton exitButton = new JButton("Exit");
exitButton.addActionListener(
new ExitButtonListener());
JPanel panel = new JPanel();
panel.add(helloButton);
panel.add(exitButton);
Container contentPane = getContentPane();
contentPane.add(panel);
setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
setVisible(true);
}
public static void main(String[] args) {
new HelloFrame5();
}
class HelloButtonListener implements ActionListener {
public void actionPerformed(ActionEvent ae) {
JOptionPane.showMessageDialog(
HelloFrame5.this, "Hey");
}
}
class ExitButtonListener implements ActionListener {
public void actionPerformed(ActionEvent ae) {
System.out.println("Goodbye!");
System.exit(0);
}
}
}
|
Notes on the Code
- As you can see the code is no longer than our original example
- Thus inner classes make the code more compact and simpler than when using separate classes
- Also note that no conditional statements are required in the code
- Unlike when using
getSource() to separate events in the component container
- In addition, note the reference to
this in the outer class of HelloButtonListener
HelloFrame5.this
This is the required syntax for accessing the this reference of the outer class
One final thing to note is how the compiler names the inner classes:
HelloFrame5$ExitButtonListener.class
HelloFrame5$HelloButtonListener.class
They are easily identified as inner classes from the file name
^ top
9.4.6: Using Anonymous Inner Classes
- One other commonly used way to write handlers is to use an anonymous inner class
- Usually just called an anonymous class
- An anonymous class is a special type of inner class without a name
- It is both declared and instantiated in one statement
- The syntax is:
new ListenerInterface() { class-body }
For example:
helloButton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent ae) {
JOptionPane.showMessageDialog(
HelloFrame6.this, "Hey");
}
});
Example Using Anonymous Inner Classes
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
30
31
32
33
34
35
36
37
38
39
40
41
|
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloFrame6 extends JFrame {
public final static int X_LOC = 100, Y_LOC = 100,
WIDTH = 300, HEIGHT = 150;
public HelloFrame6() {
super("Hello Frame Application");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton helloButton = new JButton("Hello");
helloButton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(
HelloFrame6.this, "Hey");
}
});
JButton exitButton = new JButton("Exit");
exitButton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Goodbye!");
System.exit(0);
}
});
JPanel panel = new JPanel();
panel.add(helloButton);
panel.add(exitButton);
Container contentPane = getContentPane();
contentPane.add(panel);
setBounds(X_LOC, Y_LOC, WIDTH, HEIGHT);
setVisible(true);
}
public static void main(String[] args) {
new HelloFrame6();
}
}
|
Notes on the Code
- As you can see the code is shorter than our original example
- Thus anonymous classes make the code even more compact and simpler
- Also note how the compiler names the inner classes:
HelloFrame6$1.class
HelloFrame6$2.class
An anonymous class is referred to by a number rather than a name
In addition, note that anonymous classes can implement adaptor classes
For example:
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e){
System.exit(0);
}});
^ top
9.4.7: Summary
- An event is an object that is generated by user actions or by system events
- An event listener is an object that implements a listener interface
- To handle an event, you must:
- Implement the listener interface for the event in some class
- Register an instance of the listener class to the event source by calling the appropriate addeventListener method
- Code the required methods of the listener interface
- The container for the for the components generating the events can also be the listener for the events
- In that case, you specify
this in the addeventListener() method
- You can also use separate classes to listen for events
- Using this technique, you do not need to use
getSource() to determine which component fired the event
- Instead, each component has its own event handling class
- To reduce the amount of code needed for separate classes, Java provides adaptor classes for listener interfaces requiring more than one method
- One commonly used technique for writing event listeners is to use an inner class
- This reduces the complexity of using separate classes because an inner class has access to all members of its containing class
- One other commonly used way to write handlers is to use an anonymous inner class
- An anonymous class is a special type of inner class without a name
- It is both declared and instantiated in one statement
new ListenerInterface() { class-body }
^ top
Exercise 9.4
Take one minute to prepare answers to the following questions:
- What is the difference between an event, an event source, an event object, and an event listener?
- What are four options for structuring the classes that implement the listener interface for an event?
- What is the difference between an inner class and an anonymous inner class?
- What is the benefit of using adapter classes rather than implementing listener interfaces?
^ top
Wrap Up
^ top
Home
| WebCT
| Announcements
| Schedule
| Room Policies
| Course Info
Help
| FAQ's
| HowTo's
| Links
Last Updated: April 16 2005 @12:26:02
|