- •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
510 Chapter 15 |
Graphics |
|
|||||
|
49 |
|
Math.cos(5 * 2 * Math.PI / 6)), (int)(yCenter – radius * |
|
|||
|
50 |
|
Math.sin(5 * 2 * Math.PI / 6))); |
|
|||
|
51 |
|
|
|
|
|
|
|
52 |
// Draw the polygon |
|
||||
draw polygon |
53 |
|
g.drawPolygon(polygon); |
|
|
|
|
|
54 |
} |
|
|
|
|
|
|
55 |
} |
|
|
|
|
|
|
|
|
|
|
|
(x, y) |
|
|
|
|
|
|
|
x is xCenter radius cos(2 |
/6) |
|
|
|
|
|
|
y is yCenter radius sin(2 |
/6) |
|
|
|
2 |
|
|
||
|
|
6 |
|
|
radius
(xCenter, yCenter)
FIGURE 15.16 The program uses the drawPolygon method to draw a polygon.
15.8 Centering a String Using the FontMetrics Class
You can display a string at any location in a panel. Can you display it centered? To do so, you need to use the FontMetrics class to measure the exact width and height of the string for a particular font. FontMetrics can measure the following attributes for a given font (see Figure 15.17):
■Leading, pronounced ledding, is the amount of space between lines of text.
■Ascent is the distance from the baseline to the ascent line. The top of most characters in the font will be under the ascent line, but some may extend above the ascent line.
■Descent is the distance from the baseline to the descent line. The bottom of most descending characters (e.g., j, y, and g) in the font will be above the descent line, but some may extend below the descent line.
■Height is the sum of leading, ascent, and descent.
Leading
Ascent line
Height |
By |
Ascent |
Baseline |
Descent |
Descent line
FIGURE 15.17 The FontMetrics class can be used to determine the font properties of characters for a given font.
FontMetrics is an abstract class. To get a FontMetrics object for a specific font, use the following getFontMetrics methods defined in the Graphics class:
■ public FontMetrics getFontMetrics(Font font)
Returns the font metrics of the specified font.
■ public FontMetrics getFontMetrics()
Returns the font metrics of the current font.
15.8 Centering a String Using the FontMetrics Class 511
You can use the following instance methods in the FontMetrics class to obtain the attributes of a font and the width of a string when it is drawn using the font:
public int getAscent() // Return the ascent public int getDescent() // Return the descent public int getLeading() // Return the leading public int getHeight() // Return the height
public int stringWidth(String str) // Return the width of the string
Listing 15.6 gives an example that displays a message in the center of the panel, as shown in Figure 15.18.
This is a MessagePanel object
stringWidth()
getHeight() stringAscent()
(xCoordinate, yCoordinate)
xCoordinate = getWidth / 2 - stringWidth / 2; yCoordinate = getHeight / 2 - stringAscent / 2;
FIGURE 15.18 The program uses the FontMetrics class to measure the string width and height and displays it at the center of the panel.
LISTING 15.6 TestCenterMessage.java
1 import javax.swing.*;
2 import java.awt.*;
3
4 public class TestCenterMessage extends JFrame{
5public TestCenterMessage() {
6 |
CenterMessage messagePanel = new CenterMessage(); |
create a message panel |
7 |
add(messagePanel); |
add a message panel |
8 |
messagePanel.setBackground(Color.WHITE); |
set background |
9 |
messagePanel.setFont(new Font("Californian FB", Font.BOLD, 30)); |
set font |
10 |
} |
|
11 |
|
|
12/** Main method */
13public static void main(String[] args) {
14TestCenterMessage frame = new TestCenterMessage();
15frame.setSize(300, 150);
16frame.setLocationRelativeTo(null); // Center the frame
17frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
18frame.setVisible(true);
19}
20}
21
22 class CenterMessage extends JPanel {
23 /** Paint the message */
24 protected void paintComponent(Graphics g) { override paintComponent
25 super.paintComponent(g);
512 Chapter 15 |
Graphics |
|
|
|
|
|
|
|
26 |
|
|
|
|
|
|
|
27 |
// Get font metrics for the current font |
|||||
get FontMetrics |
28 |
FontMetrics fm = g.getFontMetrics(); |
|
||||
|
29 |
|
|
|
|
|
|
|
30 |
// Find the center location to display |
|||||
|
31 |
int stringWidth = |
fm.stringWidth("Welcome to Java") |
; |
|||
|
32 |
int stringAscent = |
fm.getAscent() |
; |
|
|
|
|
33 |
|
|
|
|
|
|
|
34 |
// Get the position of the leftmost character in the baseline |
|||||
|
35 |
int xCoordinate = getWidth() / 2 - stringWidth / 2; |
|||||
|
36 |
int yCoordinate = getHeight() / 2 + stringAscent / 2; |
|||||
|
37 |
|
|
|
|
|
|
38g.drawString("Welcome to Java", xCoordinate, yCoordinate);
39}
40}
The methods getWidth() and getHeight() (lines 35–36) defined in the Component class return the component’s width and height, respectively.
Since the message is centered, the first character of the string should be positioned at (xCoordinate, yCoordinate), as shown in Figure 15.18.
Video Note
The MessagePanel class
15.9 Case Study: The MessagePanel Class
This case study develops a useful class that displays a message in a panel. The class enables the user to set the location of the message, center the message, and move the message with the specified interval. The contract of the class is shown in Figure 15.19.
Let us first write a test program in Listing 15.7 that uses the MessagePanel class to display four message panels, as shown in Figure 15.20.
javax.swing.JPanel |
|
|
|
|
The get and set methods for these |
|
|
|
|
|
data fields are provided in the class, but |
MessagePanel |
|
omitted in the UML diagram for brevity. |
|
|
|
|
|
|
-xCoordinate: int |
|
The x-coordinate for the message. |
-yCoordinate: int |
|
The y-coordinate for the message. |
-centered: boolean |
|
Specifies whether the message is displayed centered. |
-message: String |
|
The message to be displayed. |
-interval: int |
|
The interval to move the message in the panel. |
|
|
|
+MessagePanel() |
|
Constructs a default message panel. |
+MessagePanel(message: String) |
|
Constructs a message panel with a specified string. |
+moveLeft(): void |
|
Moves the message to the left. |
+moveRight(): void |
|
Moves the message to the right. |
+moveUp(): void |
|
Moves the message up. |
+moveDown(): void |
|
Moves the message down. |
|
|
|
FIGURE 15.19 MessagePanel displays a message on the panel.
15.9 Case Study: The MessagePanel Class 513
FIGURE 15.20 TestMessagePanel uses MessagePanel to display four message panels.
LISTING 15.7 TestMessagePanel.java
1 import java.awt.*;
2 import javax.swing.*;
3
4 public class TestMessagePanel extends JFrame {
5public TestMessagePanel() {
6 |
MessagePanel messagePanel1 = |
new |
MessagePanel("Wecome to Java") |
; |
create message panel |
|
7 |
MessagePanel |
messagePanel2 = new |
MessagePanel("Java is fun"); |
|
||
8 |
MessagePanel |
messagePanel3 = new |
MessagePanel("Java is cool"); |
|
9MessagePanel messagePanel4 = new MessagePanel("I love Java");
10 |
messagePanel1.setFont(new Font("SansSerif", Font.ITALIC, 20)); |
set font |
11messagePanel2.setFont(new Font("Courier", Font.BOLD, 20));
12messagePanel3.setFont(new Font("Times", Font.ITALIC, 20));
13messagePanel4.setFont(new Font("Californian FB", Font.PLAIN, 20));
14 |
messagePanel1.setBackground(Color.RED); |
set background |
15messagePanel2.setBackground(Color.CYAN);
16messagePanel3.setBackground(Color.GREEN);
17messagePanel4.setBackground(Color.WHITE);
18messagePanel1.setCentered(true);
19 |
|
|
20 |
setLayout(new GridLayout(2, 2)); |
|
21 |
add(messagePanel1); |
add message panel |
22add(messagePanel2);
23add(messagePanel3);
24add(messagePanel4);
25}
26
27public static void main(String[] args) {
28TestMessagePanel frame = new TestMessagePanel();
29frame.setSize(300, 200);
30frame.setTitle("TestMessagePanel");
31frame.setLocationRelativeTo(null); // Center the frame
32frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
33frame.setVisible(true);
34}
35}
The rest of this section explains how to implement the MessagePanel class. Since you can use
the class without knowing how it is implemented, you may skip the implementation if you wish. skip implementation? The MessagePanel class is implemented in Listing 15.8. The program seems long but is
actually simple, because most of the methods are get and set methods, and each method is relatively short and easy to read.
LISTING 15.8 MessagePanel.java
1 import java.awt.FontMetrics;
2 import java.awt.Dimension;
3 import java.awt.Graphics;
514 Chapter 15 Graphics
4 import javax.swing.JPanel;
5
6 public class MessagePanel extends JPanel {
|
7 |
|
/** The message to be displayed */ |
||||
|
8 |
|
private String message = "Welcome to Java"; |
||||
|
9 |
|
|
|
|
|
|
|
10 |
|
/** The x-coordinate where the message is displayed */ |
||||
|
11 |
|
private int xCoordinate = 20; |
||||
|
12 |
|
|
|
|
|
|
|
13 |
|
/** The y-coordinate where the message is displayed */ |
||||
|
14 |
|
private int yCoordinate = 20; |
||||
|
15 |
|
|
|
|
|
|
|
16 |
|
/** Indicate whether the message is displayed in the center */ |
||||
|
17 |
|
private boolean centered; |
||||
|
18 |
|
|
|
|
|
|
|
19 |
|
/** The interval for moving the message horizontally and |
||||
|
20 |
|
vertically */ |
||||
|
21 |
|
private int interval = 10; |
||||
|
22 |
|
|
|
|
|
|
|
23 |
|
/** Construct with default properties */ |
||||
|
24 |
|
public MessagePanel() |
{ |
|||
|
25 |
} |
|
|
|
|
|
|
26 |
|
|
|
|
|
|
|
27 |
|
/** Construct a message panel with a specified message */ |
||||
|
28 |
|
public MessagePanel(String message) |
{ |
|||
|
29 |
|
this.message = message; |
||||
|
30 |
} |
|
|
|
|
|
|
31 |
|
|
|
|
|
|
|
32 |
|
/** Return message */ |
||||
|
33 |
|
public String getMessage() { |
||||
|
34 |
|
return message; |
||||
|
35 |
} |
|
|
|
|
|
|
36 |
|
|
|
|
|
|
|
37 |
/** Set a new message */ |
|||||
|
38 |
public void setMessage(String message) { |
|||||
|
39 |
|
this.message = message; |
||||
repaint panel |
40 |
|
|
repaint(); |
|
|
|
|
41 |
} |
|
|
|
|
|
|
42 |
|
|
|
|
|
|
|
43 |
/** Return xCoordinator */ |
|||||
|
44 |
public int getXCoordinate() { |
|||||
|
45 |
|
return xCoordinate; |
||||
|
46 |
} |
|
|
|
|
|
|
47 |
|
|
|
|
|
|
|
48 |
/** Set a new xCoordinator */ |
|||||
|
49 |
public void setXCoordinate(int x) { |
|||||
|
50 |
|
this.xCoordinate = x; |
||||
repaint panel |
51 |
|
repaint(); |
||||
|
52 |
} |
|
|
|
|
|
|
53 |
|
|
|
|
|
|
|
54 |
/** Return yCoordinator */ |
|||||
|
55 |
public int getYCoordinate() { |
|||||
|
56 |
|
return yCoordinate; |
||||
|
57 |
} |
|
|
|
|
|
|
58 |
|
|
|
|
|
|
|
59 |
/** Set a new yCoordinator */ |
|||||
|
60 |
public void setYCoordinate(int y) { |
|||||
|
61 |
|
this.yCoordinate = y; |
|
15.9 |
Case Study: The MessagePanel Class 515 |
62 |
repaint(); |
repaint panel |
63 |
} |
|
64 |
|
|
65/** Return centered */
66public boolean isCentered() {
67return centered;
68}
69
70/** Set a new centered */
71public void setCentered(boolean centered) {
72this.centered = centered;
73 |
repaint(); |
repaint panel |
74 |
} |
|
75 |
|
|
76/** Return interval */
77public int getInterval() {
78return interval;
79}
80
81/** Set a new interval */
82public void setInterval(int interval) {
83this.interval = interval;
84 |
repaint(); |
repaint panel |
||
85 |
} |
|
|
|
86 |
|
|
|
|
87 |
/** Paint the message */ |
|
||
88 |
protected void paintComponent(Graphics g) { |
override paintComponent |
||
89 |
super.paintComponent(g); |
|
||
90 |
|
|
|
|
91 |
|
if (centered) |
{ |
check centered |
92// Get font metrics for the current font
93FontMetrics fm = g.getFontMetrics();
94
95// Find the center location to display
96int stringWidth = fm.stringWidth(message);
97int stringAscent = fm.getAscent();
98// Get the position of the leftmost character in the baseline
99xCoordinate = getWidth() / 2 - stringWidth / 2;
100yCoordinate = getHeight() / 2 + stringAscent / 2;
101}
102
103g.drawString(message, xCoordinate, yCoordinate);
104}
105
106/** Move the message left */
107public void moveLeft() {
108xCoordinate -= interval;
109repaint();
110}
111
112/** Move the message right */
113public void moveRight() {
114xCoordinate += interval;
115repaint();
116}
117
118/** Move the message up */
119public void moveUp() {
120yCoordinate -= interval;