- •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
502 Chapter 15 Graphics
corner, and ah is the vertical diameter of the arcs at the corner (see Figure 15.8(a)). In other words, aw and ah are the width and the height of the oval that produces a quarter-circle at each corner.
|
|
aw/2 |
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
(x, y) |
|
|
|
(x, y) |
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
ah/2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
h |
|
|
|
|
|
|
|
h |
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
(a) drawRoundRect |
|
|
(b) |
drawOval |
|||||||||||||||
|
FIGURE 15.8 (a) The drawRoundRect(x, y, w, h, aw, ah) method draws a round- |
||||||||||||||||||||||
|
cornered rectangle. (b) The drawOval(x, y, w, h) method draws an oval based on its |
||||||||||||||||||||||
|
bounding rectangle. |
|
|
|
|
|
|
|
|
|
|
||||||||||||
draw3DRect |
The draw3DRect(int x, int y, int w, int h, boolean raised) method draws a |
||||||||||||||||||||||
fill3DRect |
3D rectangle and the fill3DRect(int x, int y, int |
w, int h, boolean raised) |
|||||||||||||||||||||
|
method draws a filled 3D rectangle. The parameters x, y, w, and h are the same as in the |
||||||||||||||||||||||
|
drawRect method. The last parameter, a Boolean value, indicates whether the rectangle is |
||||||||||||||||||||||
|
raised above the surface or sunk into the surface. |
|
|
|
|
|
|
|
|
|
|
||||||||||||
|
Depending on whether you wish to draw an oval in outline or filled solid, you can use |
||||||||||||||||||||||
drawOval |
either the drawOval(int x, int y, int w, int h) method or the fillOval(int x, int |
||||||||||||||||||||||
fillOval |
y, int w, int h) method. An oval is drawn based on its bounding rectangle. Parameters x |
||||||||||||||||||||||
|
and y indicate the top-left corner of the bounding rectangle, and w and h indicate the width |
||||||||||||||||||||||
|
and height, respectively, of the bounding rectangle, as shown in Figure 15.8(b). |
Video Note
The FigurePanel class
create figures
15.5 Case Study: The FigurePanel Class
This example develops a useful class for displaying various figures. The class enables the user to set the figure type and specify whether the figure is filled, and it displays the figure on a panel. The UML diagram for the class is shown in Figure 15.9. The panel can display lines, rectangles, round-cornered rectangles, and ovals. Which figure to display is decided by the type property. If the filled property is true, the rectangle, round-cornered rectangle, and oval are filled in the panel.
The UML diagram serves as the contract for the FigurePanel class. The user can use the class without knowing how the class is implemented. Let us begin by writing a program in Listing 15.2 that uses the class to display six figure panels, as shown in Figure 15.10.
LISTING 15.2 TestFigurePanel.java
1 import java.awt.*;
2 import javax.swing.*;
3
4 public class TestFigurePanel extends JFrame {
5public TestFigurePanel() {
6 setLayout(new GridLayout(2, 3, 5, 5));
7add(new FigurePanel(FigurePanel.LINE));
8add(new FigurePanel(FigurePanel.RECTANGLE));
9 add(new FigurePanel(FigurePanel.ROUND_RECTANGLE));
10add(new FigurePanel(FigurePanel.OVAL));
11add(new FigurePanel(FigurePanel.RECTANGLE, true));
15.5 Case Study: The FigurePanel Class 503
12add(new FigurePanel(FigurePanel.ROUND_RECTANGLE, true));
13}
14
15public static void main(String[] args) {
16TestFigurePanel frame = new TestFigurePanel();
17frame.setSize(400, 200);
18frame.setTitle("TestFigurePanel");
19frame.setLocationRelativeTo(null); // Center the frame
20frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
21frame.setVisible(true);
22}
23}
javax.swing.JPanel
FigurePanel
+LINE = 1 +RECTANGLE = 2
+ROUND_RECTANGLE = 3 +OVAL = 4
-type: int -filled: boolean
+FigurePanel() +FigurePanel(type: int)
+FigurePanel(type: int, filled: boolean) +getType(): int
+setType(type: int): void +isFilled(): boolean +setFilled(filled: boolean): void
LINE, RECTANGLE, ROUND_RECTANGLE, and OVAL are constants, indicating the figure type.
Specifies the figure type (default: 1).
Specifies whether the figure is filled (default: false).
Creates a default figure panel.
Creates a figure panel with the specified type.
Creates a figure panel with the specified type and filled property. Returns the figure type.
Sets a new figure type.
Checks whether the figure is filled with a color.
Sets a new filled property.
FIGURE 15.9 FigurePanel displays various types of figures on the panel.
FIGURE 15.10 Six FigurePanel objects are created to display six figures.
The FigurePanel class is implemented in Listing 15.3. Four constants—LINE, RECTANGLE, ROUND_RECTANGLE, and OVAL—are declared in lines 6–9. Four types of figures are drawn according to the type property (line 37). The setColor method (lines 39, 44, 53, 62) sets a new color for the drawing.
LISTING 15.3 FigurePanel.java
1 import java.awt.*;
2 import javax.swing.JPanel;
3
4 public class FigurePanel extends JPanel {
504 Chapter 15 |
Graphics |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
// Define constants |
||||||||||||
constants |
6 |
public static final int LINE = 1; |
||||||||||||
|
7 |
public static final int RECTANGLE = 2; |
||||||||||||
|
8 |
public static final int ROUND_RECTANGLE = 3; |
||||||||||||
|
9 |
public static final int OVAL = 4; |
||||||||||||
|
10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
private int type = 1; |
||||||||||||
|
12 |
private boolean filled = false; |
||||||||||||
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
/** Construct a default FigurePanel */ |
||||||||||||
|
15 |
public FigurePanel() { |
||||||||||||
|
16 |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
/** Construct a FigurePanel with the specified type */ |
||||||||||||
|
19 |
public FigurePanel(int type) { |
||||||||||||
|
20 |
this.type = type; |
||||||||||||
|
21 |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
/** Construct a FigurePanel with the specified type and filled */ |
||||||||||||
|
24 |
public FigurePanel(int type, boolean filled) { |
||||||||||||
|
25 |
this.type = type; |
||||||||||||
|
26 |
this.filled = filled; |
||||||||||||
|
27 |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
/** Draw a figure on the panel */ |
||||||||||||
override |
30 |
protected void paintComponent(Graphics g) { |
||||||||||||
paintComponent(g) |
31 |
super.paintComponent(g); |
||||||||||||
|
32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
// Get the appropriate size for the figure |
||||||||||||
|
34 |
int width = getWidth(); |
||||||||||||
|
35 |
int height = getHeight(); |
||||||||||||
|
36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
check type |
37 |
|
switch (type) |
{ |
||||||||||
|
38 |
|
case LINE: // Display two cross lines |
|||||||||||
|
39 |
|
|
g.setColor(Color.BLACK); |
|
|||||||||
draw lines |
40 |
|
|
g.drawLine( |
10, 10, width - 10, height - 10); |
|||||||||
|
41 |
|
|
g.drawLine(width - 10, 10, 10, height - 10); |
||||||||||
|
42 |
|
break; |
|||||||||||
|
43 |
|
case RECTANGLE: // Display a rectangle |
|||||||||||
|
44 |
|
g.setColor(Color.BLUE); |
|||||||||||
|
45 |
|
|
if (filled) |
|
|
||||||||
fill a rectangle |
46 |
|
|
|
g.fillRect(( |
int)(0.1 * width), (int)(0.1 * height), |
||||||||
|
47 |
|
|
|
(int)(0.8 * width), (int)(0.8 * height)); |
|||||||||
|
48 |
|
else |
|||||||||||
draw a rectangle |
49 |
|
|
|
g.drawRect(( |
int)(0.1 * width), (int)(0.1 * height), |
||||||||
|
50 |
|
|
|
(int)(0.8 * width), (int)(0.8 * height)); |
|||||||||
|
51 |
|
break; |
|||||||||||
|
52 |
|
case ROUND_RECTANGLE: // Display a round-cornered rectangle |
|||||||||||
|
53 |
|
g.setColor(Color.RED); |
|||||||||||
|
54 |
|
|
if (filled) |
|
|
|
|||||||
fill round-cornered rect |
55 |
|
|
|
g.fillRoundRect(( |
int)(0.1 * width), (int)(0.1 * height), |
||||||||
|
56 |
|
|
|
(int)(0.8 * width), (int)(0.8 * height), 20, 20); |
|||||||||
|
57 |
|
else |
|||||||||||
draw round-cornered rect |
58 |
|
|
|
g.drawRoundRect |
((int)(0.1 * width), (int)(0.1 * height), |
||||||||
|
59 |
|
|
|
(int)(0.8 * width), (int)(0.8 * height), 20, 20); |
|||||||||
|
60 |
|
break; |
|||||||||||
|
61 |
|
case OVAL: // Display an oval |
|||||||||||
|
62 |
|
g.setColor(Color.BLACK); |
|||||||||||
|
63 |
|
|
if (filled) |
|
|
|
|
|
|||||
fill an oval |
64 |
|
|
|
g.fillOval(( |
int)(0.1 * width), (int)(0.1 * height), |
15.5 Case Study: The FigurePanel Class 505
65(int)(0.8 * width), (int)(0.8 * height));
66else
67 |
g.drawOval((int)(0.1 * width), (int)(0.1 * height), |
draw an oval |
68(int)(0.8 * width), (int)(0.8 * height));
69}
70}
71
72/** Set a new figure type */
73public void setType(int type) {
74this.type = type;
75 |
repaint(); |
repaint panel |
76 |
} |
|
77 |
|
|
78/** Return figure type */
79public int getType() {
80return type;
81}
82
83/** Set a new filled property */
84public void setFilled(boolean filled) {
85this.filled = filled;
86 |
repaint(); |
repaint panel |
87 |
} |
|
88 |
|
|
89/** Check if the figure is filled */
90public boolean isFilled() {
91return filled;
92}
93 |
|
|
|
|
94 |
/** Specify preferred size */ |
|
||
95 |
public Dimension getPreferredSize() { |
override |
||
96 |
|
return new Dimension(80, 80); |
|
getPreferredSize() |
97}
98}
The repaint method (lines 75, 86) is defined in the Component class. Invoking repaint causes the paintComponent method to be called. The repaint method is invoked to refresh the viewing area. Typically, you call it if you have new things to display.
Caution
The paintComponent method should never be invoked directly. It is invoked either by the JVM whenever the viewing area changes or by the repaint method. You should override the paintComponent method to tell the system how to paint the viewing area, but never override the repaint method.
don’t invoke paintComponent
Note
The repaint method lodges a request to update the viewing area and returns immediately. Its effect is asynchronous, meaning that it is up to the JVM to execute the paintComponent method on a separate thread.
The getPreferredSize() method (lines 95–97), defined in Component, is overridden in FigurePanel to specify the preferred size for the layout manager to consider when laying out a FigurePanel object. This property may or may not be considered by the layout manager, depending on its rules. For example, a component uses its preferred size in a container with a FlowLayout manager, but its preferred size may be ignored if it is placed in a container with a GridLayout manager. It is a good practice to override getPreferredSize() in a subclass of JPanel to specify a preferred size, because the default preferred size for a
JPanel is 0 by 0.
request repaint using repaint()
getPreferedSize()