- •CONTENTS
- •1.1 Introduction
- •1.2 What Is a Computer?
- •1.3 Programs
- •1.4 Operating Systems
- •1.5 Java, World Wide Web, and Beyond
- •1.6 The Java Language Specification, API, JDK, and IDE
- •1.7 A Simple Java Program
- •1.8 Creating, Compiling, and Executing a Java Program
- •1.9 (GUI) Displaying Text in a Message Dialog Box
- •2.1 Introduction
- •2.2 Writing Simple Programs
- •2.3 Reading Input from the Console
- •2.4 Identifiers
- •2.5 Variables
- •2.7 Named Constants
- •2.8 Numeric Data Types and Operations
- •2.9 Problem: Displaying the Current Time
- •2.10 Shorthand Operators
- •2.11 Numeric Type Conversions
- •2.12 Problem: Computing Loan Payments
- •2.13 Character Data Type and Operations
- •2.14 Problem: Counting Monetary Units
- •2.15 The String Type
- •2.16 Programming Style and Documentation
- •2.17 Programming Errors
- •2.18 (GUI) Getting Input from Input Dialogs
- •3.1 Introduction
- •3.2 boolean Data Type
- •3.3 Problem: A Simple Math Learning Tool
- •3.4 if Statements
- •3.5 Problem: Guessing Birthdays
- •3.6 Two-Way if Statements
- •3.7 Nested if Statements
- •3.8 Common Errors in Selection Statements
- •3.9 Problem: An Improved Math Learning Tool
- •3.10 Problem: Computing Body Mass Index
- •3.11 Problem: Computing Taxes
- •3.12 Logical Operators
- •3.13 Problem: Determining Leap Year
- •3.14 Problem: Lottery
- •3.15 switch Statements
- •3.16 Conditional Expressions
- •3.17 Formatting Console Output
- •3.18 Operator Precedence and Associativity
- •3.19 (GUI) Confirmation Dialogs
- •4.1 Introduction
- •4.2 The while Loop
- •4.3 The do-while Loop
- •4.4 The for Loop
- •4.5 Which Loop to Use?
- •4.6 Nested Loops
- •4.7 Minimizing Numeric Errors
- •4.8 Case Studies
- •4.9 Keywords break and continue
- •4.10 (GUI) Controlling a Loop with a Confirmation Dialog
- •5.1 Introduction
- •5.2 Defining a Method
- •5.3 Calling a Method
- •5.4 void Method Example
- •5.5 Passing Parameters by Values
- •5.6 Modularizing Code
- •5.7 Problem: Converting Decimals to Hexadecimals
- •5.8 Overloading Methods
- •5.9 The Scope of Variables
- •5.10 The Math Class
- •5.11 Case Study: Generating Random Characters
- •5.12 Method Abstraction and Stepwise Refinement
- •6.1 Introduction
- •6.2 Array Basics
- •6.3 Problem: Lotto Numbers
- •6.4 Problem: Deck of Cards
- •6.5 Copying Arrays
- •6.6 Passing Arrays to Methods
- •6.7 Returning an Array from a Method
- •6.8 Variable-Length Argument Lists
- •6.9 Searching Arrays
- •6.10 Sorting Arrays
- •6.11 The Arrays Class
- •7.1 Introduction
- •7.2 Two-Dimensional Array Basics
- •7.3 Processing Two-Dimensional Arrays
- •7.4 Passing Two-Dimensional Arrays to Methods
- •7.5 Problem: Grading a Multiple-Choice Test
- •7.6 Problem: Finding a Closest Pair
- •7.7 Problem: Sudoku
- •7.8 Multidimensional Arrays
- •8.1 Introduction
- •8.2 Defining Classes for Objects
- •8.3 Example: Defining Classes and Creating Objects
- •8.4 Constructing Objects Using Constructors
- •8.5 Accessing Objects via Reference Variables
- •8.6 Using Classes from the Java Library
- •8.7 Static Variables, Constants, and Methods
- •8.8 Visibility Modifiers
- •8.9 Data Field Encapsulation
- •8.10 Passing Objects to Methods
- •8.11 Array of Objects
- •9.1 Introduction
- •9.2 The String Class
- •9.3 The Character Class
- •9.4 The StringBuilder/StringBuffer Class
- •9.5 Command-Line Arguments
- •9.6 The File Class
- •9.7 File Input and Output
- •9.8 (GUI) File Dialogs
- •10.1 Introduction
- •10.2 Immutable Objects and Classes
- •10.3 The Scope of Variables
- •10.4 The this Reference
- •10.5 Class Abstraction and Encapsulation
- •10.6 Object-Oriented Thinking
- •10.7 Object Composition
- •10.8 Designing the Course Class
- •10.9 Designing a Class for Stacks
- •10.10 Designing the GuessDate Class
- •10.11 Class Design Guidelines
- •11.1 Introduction
- •11.2 Superclasses and Subclasses
- •11.3 Using the super Keyword
- •11.4 Overriding Methods
- •11.5 Overriding vs. Overloading
- •11.6 The Object Class and Its toString() Method
- •11.7 Polymorphism
- •11.8 Dynamic Binding
- •11.9 Casting Objects and the instanceof Operator
- •11.11 The ArrayList Class
- •11.12 A Custom Stack Class
- •11.13 The protected Data and Methods
- •11.14 Preventing Extending and Overriding
- •12.1 Introduction
- •12.2 Swing vs. AWT
- •12.3 The Java GUI API
- •12.4 Frames
- •12.5 Layout Managers
- •12.6 Using Panels as Subcontainers
- •12.7 The Color Class
- •12.8 The Font Class
- •12.9 Common Features of Swing GUI Components
- •12.10 Image Icons
- •13.1 Introduction
- •13.2 Exception-Handling Overview
- •13.3 Exception-Handling Advantages
- •13.4 Exception Types
- •13.5 More on Exception Handling
- •13.6 The finally Clause
- •13.7 When to Use Exceptions
- •13.8 Rethrowing Exceptions
- •13.9 Chained Exceptions
- •13.10 Creating Custom Exception Classes
- •14.1 Introduction
- •14.2 Abstract Classes
- •14.3 Example: Calendar and GregorianCalendar
- •14.4 Interfaces
- •14.5 Example: The Comparable Interface
- •14.6 Example: The ActionListener Interface
- •14.7 Example: The Cloneable Interface
- •14.8 Interfaces vs. Abstract Classes
- •14.9 Processing Primitive Data Type Values as Objects
- •14.10 Sorting an Array of Objects
- •14.11 Automatic Conversion between Primitive Types and Wrapper Class Types
- •14.12 The BigInteger and BigDecimal Classes
- •14.13 Case Study: The Rational Class
- •15.1 Introduction
- •15.2 Graphical Coordinate Systems
- •15.3 The Graphics Class
- •15.4 Drawing Strings, Lines, Rectangles, and Ovals
- •15.5 Case Study: The FigurePanel Class
- •15.6 Drawing Arcs
- •15.7 Drawing Polygons and Polylines
- •15.8 Centering a String Using the FontMetrics Class
- •15.9 Case Study: The MessagePanel Class
- •15.10 Case Study: The StillClock Class
- •15.11 Displaying Images
- •15.12 Case Study: The ImageViewer Class
- •16.1 Introduction
- •16.2 Event and Event Source
- •16.3 Listeners, Registrations, and Handling Events
- •16.4 Inner Classes
- •16.5 Anonymous Class Listeners
- •16.6 Alternative Ways of Defining Listener Classes
- •16.7 Problem: Loan Calculator
- •16.8 Window Events
- •16.9 Listener Interface Adapters
- •16.10 Mouse Events
- •16.11 Key Events
- •16.12 Animation Using the Timer Class
- •17.1 Introduction
- •17.2 Buttons
- •17.3 Check Boxes
- •17.4 Radio Buttons
- •17.5 Labels
- •17.6 Text Fields
- •17.7 Text Areas
- •17.8 Combo Boxes
- •17.9 Lists
- •17.10 Scroll Bars
- •17.11 Sliders
- •17.12 Creating Multiple Windows
- •18.1 Introduction
- •18.2 Developing Applets
- •18.3 The HTML File and the <applet> Tag
- •18.4 Applet Security Restrictions
- •18.5 Enabling Applets to Run as Applications
- •18.6 Applet Life-Cycle Methods
- •18.7 Passing Strings to Applets
- •18.8 Case Study: Bouncing Ball
- •18.9 Case Study: TicTacToe
- •18.10 Locating Resources Using the URL Class
- •18.11 Playing Audio in Any Java Program
- •18.12 Case Study: Multimedia Animations
- •19.1 Introduction
- •19.2 How is I/O Handled in Java?
- •19.3 Text I/O vs. Binary I/O
- •19.4 Binary I/O Classes
- •19.5 Problem: Copying Files
- •19.6 Object I/O
- •19.7 Random-Access Files
- •20.1 Introduction
- •20.2 Problem: Computing Factorials
- •20.3 Problem: Computing Fibonacci Numbers
- •20.4 Problem Solving Using Recursion
- •20.5 Recursive Helper Methods
- •20.6 Problem: Finding the Directory Size
- •20.7 Problem: Towers of Hanoi
- •20.8 Problem: Fractals
- •20.9 Problem: Eight Queens
- •20.10 Recursion vs. Iteration
- •20.11 Tail Recursion
- •APPENDIXES
- •INDEX
16.7 Problem: Loan Calculator 547
The frame class extends JFrame and implements ActionListener (line 5). So the class is a listener class for action events. The listener is registered to four buttons (lines 23–26). When a button is clicked, the button fires an ActionEvent and invokes the listener’s actionPerformed method. The actionPerformed method checks the source of the event using the getSource() method for the event (lines 31, 33, 35, 37) and determines which button fired the event.
This design is not desirable because it places too many responsibilities into one class. It is better to design a listener class that is solely responsible for handling events. This design makes the code easy to read and easy to maintain.
You can define listener classes in many ways. Which way is preferred? Defining listener classes using inner class or anonymous inner class has become a standard for event-handling programming because it generally provides clear, clean, and concise code. So, we will consistently use it in this book.
16.7 Problem: Loan Calculator
Now you can write the program for the loan-calculator problem presented in the introduction of this chapter. Here are the major steps in the program:
1.Create the user interface, as shown in Figure 16.9.
a.Create a panel of a GridLayout with 5 rows and 2 columns. Add labels and text fields into the panel. Set a title “Enter loan amount, interest rate, and years” for the panel.
b.Create another panel with a FlowLayout(FlowLayout.RIGHT) and add a button into the panel.
c.Add the first panel to the center of the frame and the second panel to the south side of the frame.
2.Process the event.
Create and register the listener for processing the button-clicking action event. The handler obtains the user input on loan, interest rate, and number of years, computes the monthly and total payments, and displays the values in the text fields.
JPanel of
GridLayout(5,2)
JPanel of FlowLayout
right aligned
FIGURE 16.9 The program computes loan payments.
The complete program is given in Listing 16.6.
LISTING 16.6 LoanCalculator.java
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 import javax.swing.border.TitledBorder;
5
6 public class LoanCalculator extends JFrame {
7 // Create text fields for interest rate,
548 Chapter 16 |
Event-Driven Programming |
||||||||||||||
|
8 |
|
// year, loan amount, monthly payment, and total payment |
||||||||||||
text fields |
9 |
|
private JTextField jtfAnnualInterestRate = new JTextField(); |
||||||||||||
|
10 |
|
private JTextField jtfNumberOfYears = new JTextField(); |
||||||||||||
|
11 |
|
private JTextField jtfLoanAmount = new JTextField(); |
||||||||||||
|
12 |
|
private JTextField jtfMonthlyPayment = new JTextField(); |
||||||||||||
|
13 |
|
private JTextField jtfTotalPayment = new JTextField(); |
||||||||||||
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
// Create a Compute Payment button |
|||||||||||||
button |
16 |
private JButton jbtComputeLoan = new JButton("Compute Payment"); |
|||||||||||||
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
public LoanCalculator() { |
|
|||||||||||
|
19 |
|
|
// Panel p1 to hold labels and text fields |
|||||||||||
create UI |
20 |
|
|
JPanel p1 = new JPanel(new GridLayout(5, 2)); |
|
||||||||||
|
21 |
|
|
p1.add(new JLabel("Annual Interest Rate")); |
|||||||||||
|
22 |
|
|
p1.add(jtfAnnualInterestRate); |
|||||||||||
|
23 |
|
|
p1.add(new JLabel("Number of Years")); |
|||||||||||
|
24 |
|
|
p1.add(jtfNumberOfYears); |
|||||||||||
|
25 |
|
|
p1.add(new JLabel("Loan Amount")); |
|||||||||||
|
26 |
|
|
p1.add(jtfLoanAmount); |
|||||||||||
|
27 |
|
|
p1.add(new JLabel("Monthly Payment")); |
|||||||||||
|
28 |
|
|
p1.add(jtfMonthlyPayment); |
|||||||||||
|
29 |
|
|
p1.add(new JLabel("Total Payment")); |
|||||||||||
|
30 |
|
|
p1.add(jtfTotalPayment); |
|||||||||||
|
31 |
|
|
p1.setBorder(new |
|||||||||||
|
32 |
|
|
|
TitledBorder("Enter loan amount, interest rate, and year")); |
||||||||||
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
|
// Panel p2 to hold the button |
|||||||||||
add to frame |
35 |
|
|
JPanel p2 = new JPanel(new FlowLayout(FlowLayout.RIGHT)); |
|
||||||||||
|
36 |
|
|
p2.add(jbtComputeLoan); |
|||||||||||
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
|
|
// Add the panels to the frame |
|||||||||||
|
39 |
|
|
add(p1, BorderLayout.CENTER); |
|||||||||||
|
40 |
|
|
add(p2, BorderLayout.SOUTH); |
|||||||||||
|
41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
|
|
// Register listener |
|||||||||||
register listener |
43 |
|
|
jbtComputeLoan.addActionListener(new ButtonListener()); |
|
|
|||||||||
|
44 |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
|
/** Handle the Compute Payment button */ |
||||||||||||
|
47 |
|
private class ButtonListener implements ActionListener { |
|
|
|
|||||||||
|
48 |
|
|
public void actionPerformed(ActionEvent e) { |
|||||||||||
|
49 |
|
|
|
// Get values from text fields |
||||||||||
|
50 |
|
|
|
double interest = |
||||||||||
get input |
51 |
|
|
|
|
Double.parseDouble(jtfAnnualInterestRate.getText() |
); |
|
|||||||
|
52 |
|
|
|
int year = |
||||||||||
|
53 |
|
|
|
|
Integer.parseInt(jtfNumberOfYears.getText()); |
|||||||||
|
54 |
|
|
|
double loanAmount = |
||||||||||
|
55 |
|
|
|
|
Double.parseDouble(jtfLoanAmount.getText()); |
|||||||||
|
56 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
|
|
|
// Create a loan object |
||||||||||
create loan |
58 |
|
|
|
Loan loan = new Loan(interest, year, loanAmount); |
|
|
|
|
|
|||||
|
59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
|
|
// Display monthly payment and total payment |
||||||||||
set result |
61 |
|
|
|
jtfMonthlyPayment.setText(String.format("%.2f", |
|
|
|
|
|
|
||||
|
62 |
|
|
|
|
loan.getMonthlyPayment())); |
|
|
|
|
|
|
|
|
|
|
63 |
|
|
|
jtfTotalPayment.setText(String.format("%.2f", |
||||||||||
|
64 |
|
|
|
|
loan.getTotalPayment())); |
|||||||||
|
65 |
} |
|
|
|
|
|
|
|
|
|
|
|
||
|
66 |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16.8 Window Events 549
68public static void main(String[] args) {
69LoanCalculator frame = new LoanCalculator();
70frame.pack();
71frame.setTitle("LoanCalculator");
72frame.setLocationRelativeTo(null); // Center the frame
73frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
74frame.setVisible(true);
75}
76}
The user interface is created in the constructor (lines 18–44). The button is the source of the event. A listener is created and registered with the button (line 43).
The listener class (lines 47–66) implements the actionPerformed method. When the button is clicked, the actionPerformed method is invoked to get the interest rate (line 51), number of years (line 53), and loan amount (line 55). Invoking jtfAnnualInterestRate.getText() returns the string text in the jtfAnnualInterestRate text field. The loan is used for computing the loan payments. This class was introduced in Listing 10.2, Loan.java. Invoking loan.getMonthlyPayment() returns the monthly payment for the loan. The String.format method uses the printf like syntax to format a number into a desirable format. Invoking the setText method on a text field sets a string value in the text field (line 61).
16.8 Window Events
The preceding sections used action events. Other events can be processed similarly. This section gives an example of handling WindowEvent. Any subclass of the Window class can fire the following window events: window opened, closing, closed, activated, deactivated, iconified, and deiconified. The program in Listing 16.7 creates a frame, listens to the window events, and displays a message to indicate the occurring event. Figure 16.10 shows a sample run of the program.
FIGURE 16.10 The window events are displayed on the console when you run the program from the command prompt.
LISTING 16.7 TestWindowEvent.java
1 import java.awt.event.*;
2 import javax.swing.JFrame;
3
4 public class TestWindowEvent extends JFrame {
5public static void main(String[] args) {
6TestWindowEvent frame = new TestWindowEvent();
7frame.setSize(220, 80);
8frame.setLocationRelativeTo(null); // Center the frame
9frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
10frame.setTitle("TestWindowEvent");
11frame.setVisible(true);
12}
13
14public TestWindowEvent() {
15addWindowListener(new WindowListener() {
16/**
17* Handler for window-deiconified event
550 Chapter 16 |
Event-Driven Programming |
|||||||
|
18 |
|
* Invoked when a window is changed from a minimized |
|||||
|
19 |
|
* to a normal state. |
|||||
|
20 |
*/ |
|
|
|
|
|
|
implement handler |
21 |
|
public void windowDeiconified(WindowEvent event) { |
|
||||
|
22 |
|
System.out.println("Window deiconified"); |
|||||
|
23 |
} |
|
|
|
|
|
|
|
24 |
|
|
|
|
|
|
|
|
25 |
/** |
|
|
|
|
|
|
|
26 |
|
* Handler for window-iconified event |
|||||
|
27 |
|
* Invoked when a window is changed from a normal to a |
|||||
|
28 |
|
* minimized state. For many platforms, a minimized window |
|||||
|
29 |
|
* is displayed as the icon specified in the window's |
|||||
|
30 |
|
* iconImage property. |
|||||
|
31 |
*/ |
|
|
|
|
|
|
implement handler |
32 |
|
public void windowIconified(WindowEvent event) { |
|
|
|||
|
33 |
|
System.out.println("Window iconified"); |
|||||
|
34 |
} |
|
|
|
|
|
|
|
35 |
|
|
|
|
|
|
|
|
36 |
/** |
|
|
|
|
|
|
|
37 |
|
* Handler for window-activated event |
|||||
|
38 |
|
* Invoked when the window is set to be the user's |
|||||
|
39 |
|
* active window, which means the window (or one of its |
|||||
|
40 |
|
* subcomponents) will receive keyboard events. |
|||||
|
41 |
*/ |
|
|
|
|
|
|
implement handler |
42 |
|
public void windowActivated(WindowEvent event) { |
|
|
|||
|
43 |
|
System.out.println("Window activated"); |
|||||
|
44 |
} |
|
|
|
|
|
|
|
45 |
|
|
|
|
|
|
|
|
46 |
/** |
|
|
|
|
|
|
|
47 |
|
* Handler for window-deactivated event |
|||||
|
48 |
|
* Invoked when a window is no longer the user's active |
|||||
|
49 |
|
* window, which means that keyboard events will no longer |
|||||
|
50 |
|
* be delivered to the window or its subcomponents. |
|||||
|
51 |
*/ |
|
|
|
|
|
|
implement handler |
52 |
|
public void windowDeactivated(WindowEvent event) { |
|
||||
|
53 |
|
System.out.println("Window deactivated"); |
|||||
|
54 |
} |
|
|
|
|
|
|
|
55 |
|
|
|
|
|
|
|
|
56 |
/** |
|
|
|
|
|
|
|
57 |
|
* Handler for window-opened event |
|||||
|
58 |
|
* Invoked the first time a window is made visible. |
|||||
|
59 |
*/ |
|
|
|
|
|
|
|
60 |
|
public void windowOpened(WindowEvent event) { |
|
|
|
|
|
|
61 |
|
System.out.println("Window opened"); |
|||||
|
62 |
} |
|
|
|
|
|
|
|
63 |
|
|
|
|
|
|
|
|
64 |
/** |
|
|
|
|
|
|
|
65 |
|
* Handler for window-closing event |
|||||
|
66 |
|
* Invoked when the user attempts to close the window |
|||||
|
67 |
|
* from the window's system menu. If the program does not |
|||||
|
68 |
|
* explicitly hide or dispose the window while processing |
|||||
|
69 |
|
* this event, the window-closing operation will be cancelled. |
|||||
|
70 |
*/ |
|
|
|
|
|
|
implement handler |
71 |
|
public void windowClosing(WindowEvent event) { |
|
|
|
|
|
|
72 |
|
System.out.println("Window closing"); |
|||||
|
73 |
} |
|
|
|
|
|
|
|
74 |
|
|
|
|
|
|
|
|
75 |
/** |
|
|
|
|
|
|
|
76 |
|
* Handler for window-closed event |
|||||
|
77 |
|
* Invoked when a window has been closed as the result |