- •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
14.5 Example: The Comparable Interface 467
Tip
A constant defined in an interface can be accessed using the syntax InterfaceName. |
accessing constants |
CONSTANT_NAME (e.g., T.K). |
|
14.5 Example: The Comparable Interface
Suppose you want to design a generic method to find the larger of two objects of the same type, such as two students, two dates, two circles, two rectangles, or two squares. In order to accomplish this, the two objects must be comparable. So, the common behavior for the objects is comparable. Java provides the Comparable interface for this purpose. The interface is defined as follows:
// Interface for comparing objects, defined in java.lang |
java.lang.Comparable |
|||
package java.lang; |
|
|||
|
|
|||
public interface Comparable |
{ |
|
||
|
public int compareTo(Object o); |
|
|
|
} |
|
|
|
|
The compareTo method determines the order of this object with the specified object o and returns a negative integer, zero, or a positive integer if this object is less than, equal to, or greater than o.
Many classes in the Java library (e.g., String and Date) implement Comparable to define a natural order for the objects. If you examine the source code of these classes, you will see the keyword implements used in the classes, as shown below:
public class String extends Object implements Comparable {
// class body omitted
}
public class Date extends Object implements Comparable {
// class body omitted
}
Thus, strings are comparable, and so are dates. Let s be a String object and d be a Date object. All the following expressions are true.
s instanceof String |
|
d instanceof java.util.Date |
||
s instanceof |
Object |
|
d instanceof |
Object |
s instanceof |
Comparable |
|
d instanceof |
Comparable |
|
|
|
|
|
A generic max method for finding the larger of two objects can be defined, as shown in (a) or (b) below:
// Max.java: Find a maximum object public class Max {
/** Return the maximum of two objects */ public static Comparable max
(Comparable o1, Comparable o2) { if (o1.compareTo(o2) > 0)
return o1; else
return o2;
}
}
// Max.java: Find a maximum object public class Max {
/** Return the maximum of two objects */ public static Object max
(Object o1, Object o2) {
if (((Comparable)o1).compareTo(o2) > 0) return o1;
else
return o2;
}
}
(a) |
(b) |
468 Chapter 14 |
Abstract Classes and Interfaces |
(a) is simpler |
The max method in (a) is simpler than the one in (b). In the Max class in (b), o1 is declared |
|
as Object, and (Comparable)o1 tells the compiler to cast o1 into Comparable so that the |
|
compareTo method can be invoked from o1. However, no casting is needed in the Max class |
|
in (a), since o1 is declared as Comparable. |
(a) is more robust |
The max method in (a) is more robust than the one in (b). You must invoke the max method |
|
with two comparable objects. Suppose you invoke max with two noncomparable objects: |
|
Max.max(anyObject1, anyObject2); |
|
The compiler will detect the error using the max method in (a), because anyObject1 is not |
|
an instance of Comparable. Using the max method in (b), this line of code will compile fine |
|
but will have a runtime ClassCastException, because anyObject1 is not an instance of |
|
Comparable and cannot be cast into Comparable. |
|
From now on, assume that the max method in (a) is in the text. Since strings are compara- |
|
ble and dates are comparable, you can use the max method to find the larger of two instances |
|
of String or Date. Here is an example: |
String s1 = "abcdef";
String s2 = "abcdee";
String s3 = (String)Max.max(s1, s2);
Date d1 = new Date(); Date d2 = new Date();
Date d3 = (Date)Max.max(d1, d2);
The return value from the max method is of the Comparable type. So you need to cast it to String or Date explicitly.
You cannot use the max method to find the larger of two instances of Rectangle, because Rectangle does not implement Comparable. However, you can define a new rectangle class that implements Comparable. The instances of this new class are comparable. Let this new class be named ComparableRectangle, as shown in Listing 14.7.
LISTING 14.7 ComparableRectangle.java
|
1 |
public class ComparableRectangle extends Rectangle |
||||
implements Comparable |
2 |
|
|
implements Comparable |
{ |
|
|
3 |
|
/** Construct a ComparableRectangle with specified properties */ |
|||
|
4 |
|
public ComparableRectangle(double width, double height) { |
|||
|
5 |
|
|
super(width, height); |
||
|
6 |
} |
|
|
|
|
|
7 |
|
|
|
|
|
|
8 |
/** Implement the compareTo method defined in Comparable */ |
||||
implement compareTo |
9 |
|
public int compareTo(Object o) |
{ |
||
|
10 |
|
if (getArea() > ((ComparableRectangle)o).getArea()) |
|||
|
11 |
|
|
return 1; |
||
|
12 |
|
else if (getArea() < ((ComparableRectangle)o).getArea()) |
|||
|
13 |
|
|
return -1; |
||
|
14 |
|
else |
|||
|
15 |
|
|
return 0; |
||
|
16 |
} |
|
|
|
|
|
17 |
} |
|
|
|
|
ComparableRectangle extends Rectangle and implements Comparable, as shown in Figure 14.4. The keyword implements indicates that ComparableRectangle inherits all the constants from the Comparable interface and implements the methods in the interface. The compareTo method compares the areas of two rectangles. An instance of
ComparableRectangle is also an instance of Rectangle, GeometricObject, Object, and Comparable.
14.6 Example: The ActionListener Interface 469
Notation:
The interface name and the method names are italicized. The dashed lines and hollow triangles are used to point to the interface.
GeometricObject |
«interface» |
|
java.lang.Comparable |
|
+compareTo(o: Object): int |
Rectangle |
|
ComparableRectangle |
|
FIGURE 14.4 ComparableRectangle extends Rectangle and implements Comparable.
You can now use the max method to find the larger of two objects of ComparableRectangle. Here is an example:
ComparableRectangle rectangle1 = new ComparableRectangle(4, 5);
ComparableRectangle rectangle2 = new ComparableRectangle(3, 6);
System.out.println(Max.max(rectangle1, rectangle2));
An interface provides another form of generic programming. It would be difficult to use a benefits of interface generic max method to find the maximum of the objects without using an interface in this
example, because multiple inheritance would be necessary to inherit Comparable and another class, such as Rectangle, at the same time.
The Object class contains the equals method, which is intended for the subclasses of the Object class to override in order to compare whether the contents of the objects are the same. Suppose that the Object class contains the compareTo method, as defined in the Comparable interface; the new max method can be used to compare a list of any objects. Whether a compareTo method should be included in the Object class is debatable. Since the compareTo method is not defined in the Object class, the Comparable interface is defined in Java to enable objects to be compared if they are instances of the Comparable interface. It is strongly recommended (though not required) that compareTo should be consistent with equals. That is, for two objects o1 and o2, o1.compareTo(o2) == 0 if and only if o1.equals(o2) is true.
14.6 Example: The ActionListener Interface
Now you are ready to write a short program to address the problem proposed in the introduction of this chapter. The program displays two buttons in the frame, as shown in Figure 14.1. To respond to a button click, you need to write the code to process the button-clicking action. The button is a source object where the action originates. You need to create an object capable of handling the action event on a button. This object is called a listener, as shown in Figure 14.5.
Not all objects can be listeners for an action event. To be a listener, two requirements must be met:
1. |
The object must be an instance of the ActionListener interface. This interface |
ActionListener interface |
|
defines the common behavior for all action listeners. |
|
2. |
The ActionListener object listener must be registered with the source using the |
|
|
method source. addActionListener(listener). |
addActionListener |
|
|
|
|
|
|
|
|
|
|
|
|
|
(listener) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
button |
|
|
|
event |
|
|
|
listener |
|
|||
|
|
|
|
|
|
||||||||
|
|
|
|
|
|||||||||
|
|
|
|
|
|
||||||||
Clicking a button |
An event is |
The listener object |
|||||||||||
fires an action event |
|
an object |
processes the event |
FIGURE 14.5 A listener object processes the event fired from the source object.
470 Chapter 14 |
Abstract Classes and Interfaces |
||||||||||
|
The ActionListener interface contains the actionPerformed method for processing the |
||||||||||
|
event. Your listener class must override this method to respond to the event. Listing 14.8 gives |
||||||||||
|
the code that processes the ActionEvent on the two buttons. When you click the OK button, |
||||||||||
|
the message “OK button clicked” is displayed. When you click the Cancel button, the mes- |
||||||||||
|
sage “Cancel button clicked” is displayed, as shown in Figure 14.1. |
||||||||||
|
LISTING 14.8 HandleEvent.java |
||||||||||
|
1 |
import javax.swing.*; |
|||||||||
|
2 |
import java.awt.event.*; |
|||||||||
|
3 |
|
|
|
|
|
|
|
|
|
|
|
4 |
public class |
HandleEvent extends JFrame |
{ |
|||||||
|
5 |
public HandleEvent() { |
|||||||||
|
6 |
|
// Create two buttons |
||||||||
|
7 |
|
JButton jbtOK = new JButton("OK"); |
||||||||
|
8 |
|
JButton jbtCancel = new JButton("Cancel"); |
||||||||
|
9 |
|
|
|
|
|
|
|
|
|
|
|
10 |
|
// Create a panel to hold buttons |
||||||||
|
11 |
|
JPanel panel = new JPanel(); |
||||||||
|
12 |
|
panel.add(jbtOK); |
||||||||
|
13 |
|
panel.add(jbtCancel); |
||||||||
|
14 |
|
|
|
|
|
|
|
|
|
|
|
15 |
|
add(panel); // Add panel to the frame |
||||||||
|
16 |
|
|
|
|
|
|
|
|
|
|
|
17 |
|
// Register listeners |
||||||||
create listener |
18 |
|
OKListenerClass listener1 = new OKListenerClass(); |
|
|||||||
|
19 |
|
CancelListenerClass listener2 = new CancelListenerClass(); |
||||||||
register listener |
20 |
|
jbtOK.addActionListener(listener1); |
|
|
|
|||||
|
21 |
|
jbtCancel.addActionListener(listener2); |
||||||||
|
22 |
} |
|
|
|
|
|
|
|
|
|
|
23 |
|
|
|
|
|
|
|
|
|
|
|
24 |
public static void main(String[] args) { |
|||||||||
|
25 |
|
JFrame frame = new HandleEvent(); |
|
|
|
|
||||
|
26 |
|
frame.setTitle("Handle Event"); |
||||||||
|
27 |
|
frame.setSize(200, 150); |
||||||||
|
28 |
|
frame.setLocation(200, 100); |
||||||||
|
29 |
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
||||||||
|
30 |
|
frame.setVisible(true); |
||||||||
|
31 |
} |
|
|
|
|
|
|
|
|
|
|
32 |
} |
|
|
|
|
|
|
|
|
|
|
33 |
|
|
|
|
|
|
|
|
|
|
listener class |
34 |
class |
OKListenerClass implements ActionListener |
{ |
|
||||||
process event |
35 |
public void actionPerformed(ActionEvent e) { |
|||||||||
|
36 |
|
System.out.println("OK button clicked"); |
||||||||
|
37 |
} |
|
|
|
|
|
|
|
|
|
|
38 |
} |
|
|
|
|
|
|
|
|
|
|
39 |
|
|
|
|
|
|
|
|
|
|
listener class |
40 |
class |
CancelListenerClass implements ActionListener |
{ |
|
||||||
process event |
41 |
public void actionPerformed(ActionEvent e) { |
|||||||||
|
42 |
System.out.println("Cancel button clicked"); |
|||||||||
|
43 |
} |
|
|
|
|
|
|
|
|
|
|
44 |
} |
|
|
|
|
|
|
|
|
|
Two listener classes are defined in lines 34–44. Each listener class implements ActionListener to process ActionEvent. The object listener1 is an instance of OKListenerClass (line 18), which is registered with the button jbtOK (line 20). When the OK button is clicked, the actionPerformed(ActionEvent) method (line 36) in OKListenerClass is invoked to process the event. The object listener2 is an instance of CancelListenerClass (line 19), which is registered with the button jbtCancel in line 21. When the OK button is clicked, the