Chapter 14 - The java.awt Package: Painting
Chapter 14: The java.awt Package: Painting 
Objectives 
This chapter helps you to prepare for the exam by covering the following objectives: 
Know how the AWT supports painting, repainting, and clipping operations.
. 
A general knowledge of how the AWT supports painting, repainting, and clipping is required 
for the certification exam. 
Know how the Canvas and Graphics classes are used to implement drawing and painting 
operations.
. 
The Canvas and Graphics classes are fundamental to painting. You need to know the 
relationship between these classes and the types of methods that are available for drawing 
shapes, text, and images. 
Know how text is drawn using the Font, FontMetrics, and Graphics classes. 
. 
The Font and FontMetrics classes are used to draw text on a Graphics object. A 
general understanding of how this occurs is useful for developing painting-based applets 
and applications. 
Know how images are created and displayed.
. 
The certification exam requires a basic understanding of how images are created and 
displayed using a Graphics object. 
Study Strategies 
As you read through this chapter, you should concentrate on the following key items: 
. 
How the Canvas and Graphics classes relate to each other 
. 
How painting and repainting occurs 
. 
What types of methods are provided by the Graphics class 
. 
How geometric shapes are drawn using a Graphics object 
. 
How the Font, FontMetrics, and Graphics classes are used to draw text 
. 
How images are created and displayed 
. 
How clipping works 
Chapter Introduction 
The Canvas, Graphics, and Image classes of the java.awt package are fundamental to AWT 
painting and drawing. You''ll learn how to use these classes to display bitmapped images and draw 
geometric shapes. You'll also learn how to use the Font class to control the way text is displayed. 
Understanding these classes is essential to developing GUI-based applets and applications. The 
certification exam may have a few questions that will call upon your knowledge of these classes. By 
studying the class descriptions of this chapter and working the programming examples, you should be 
able to do well on related exam questions. 
The Canvas and Graphics Classes 
The Canvas class of java.awt provides a general GUI component (it extends Component) for 
drawing images and text (or anything else) on the screen. It does not support any drawing methods of 
its own, but provides access to a Graphics object via its paint() method. 
The paint() method is invoked upon the creation and update of a Canvas object. It enables the 
Graphics object associated with the Canvas object to be updated. The paint() method should not 
be directly invoked, but it can be indirectly accessed using the repaint() method. The AWT creates a 
background thread that automatically causes the paint() methods of Canvas, Frame, Panel, 
Applet, and other GUI components as required to update any areas that need repainting. You can 
implement custom drawing and painting operations in your applet or application by extending the 
Canvas class and overriding its paint() method. 
- 238 
Note 
Graphics Context A Graphics object is sometimes referred to as a graphics 
context. 
Note 
Graphics Object A Graphics object is also available via the paint()
methods of the Applet, Frame, Panel, and other classes that extend 
Component. 
The Graphics class is where all the low-level drawing methods are implemented. These methods can 
be used directly to draw objects and text or can be combined to display more elaborate screen objects. 
The Graphics drawing methods enable you to draw and fill a number of geometrical shapes, including 
lines, arcs, ovals, rectangles, rounded rectangles, and polygons. A special draw3DRect() method is 
provided for drawing rectangles that are shaded to give them a three-dimensional appearance. The 
Graphics class also provides the capability to draw bitmapped images and text on the canvas. Some 
of the important Graphics drawing methods are as follows: 
. 
draw3DRect() and fill3DRect()—Draws/fills a 3D rectangle 
. 
drawArc() and fillArc()—Draws/fills an arc 
. 
drawImage()—Draws an image on the screen 
. 
drawLine()—Draws a line segment 
. 
drawOval() and fillOval()—Draws/fills an oval 
. 
drawPolygon() and fillPolygon()—Draws/fills a polygon 
. 
drawPolyline() and fillPolyline()—Draws/fills a sequence of line segments 
. 
drawRect() and fillRect()—Draws/fills a rectangle 
. 
drawRoundRect() and fillRoundRect()—Draws/fills a rounded rectangle 
. 
drawString()—Draws a String of text at a specified location 
. 
getColor() and setColor()—Gets and sets the drawing (foreground) color 
. 
getFont() and setFont()—Gets and sets the current font 
Note 
The update() Method The AWT invokes an object's update() method 
(inherited from Component) when the object's repaint() method is invoked. 
The update() method fills the component with its background color, set the 
component's foreground color, and then invokes the component's paint()
method. 
Note 
The repaint() Method When an object's repaint() method is invoked, the 
AWT schedules a repaint operation. Repainting typically occurs every .1 seconds. 
Multiple repaint() requests that occur within this interval are combined. This 
prevents repainting from consuming all the processing resources of an applet or 
application. 
Note 
Colors Colors are available via the Color class. This class defines constants, 
such as Color.red, Color.white, and Color.blue, that can be used to 
identify colors by name. Colors can also be created using their red, blue, and 
green color values. 
We'll cover shape drawing, text drawing, and image drawing the following sections. 
Drawing Shapes
Some programs, such as the Microsoft Windows Paint program, are used to construct images by 
painting on the screen. These paint programs create an image array of color pixels and update the array 
based on user paint commands. These commands may consist of pixel-level drawing operations or 
more general operations that draw geometrical objects such as circles, rectangles, and lines. Painting 
programs are characterized by the fact that the pixel array is the focus for the drawing that takes place. 
Drawing programs, such as CorelDRAW, support drawing operations using a more object-oriented 
approach. When you draw a circle or line with a drawing program, you do not merely update the pixels 
of the canvas—you add an object to the list of objects that are displayed on the canvas. Because 
drawing programs operate at a higher object level, you can select, move, resize, group, and perform 
other operations on the objects that you've drawn. 
The Graphics class is oriented toward providing the methods that are needed to support higher-level 
drawing programs rather than lower-level painting programs. However, it does support important 
painting operations, such as displaying bitmapped images, as you'll see in the ImageApp program later 
in this chapter. 
When using the Graphics class to support graphical operations, you will generally maintain a list of the 
objects that you've drawn and use that list of objects to repaint the screen, as required. 
- 239 
The DrawApp Program 
The DrawApp program shows how the higher-level drawing operations of the Graphics class are used 
to display and maintain a list of the objects that are drawn on a canvas. The source code of the 
DrawApp program is shown in Listing 14.1. 
DrawappListing 14.1: The Source Code for the Program 
import java.awt.*; 
import java.awt.event.*; 
import java.util.*; 
public class DrawApp extends Frame { 
// Create buttons 
Button lineButton = new Button("Line"); 
Button ovalButton = new Button("Oval"); 
Button rectButton = new Button("Rectangle"); 
Button clearButton = new Button("Clear"); 
// Create Canvas object 
MyCanvas canvas = new MyCanvas(TwoPointObject.LINE); 
public static void main(String[] args) { 
 DrawApp app = new DrawApp(); 
} 
public DrawApp() {
 super("DrawApp")
; 
add("Center",canvas)
; 
setupButtons()
; 
addWindowListener(new WindowEventHandler())
; 
pack()
; 
setSize(400,400)
; 
show()
; 
} 
 void setupButtons() { 
// Connect event handlers 
- 240 
lineButton.addActionListener(new ButtonHandler())
; 
ovalButton.addActionListener(new ButtonHandler())
; 
rectButton.addActionListener(new ButtonHandler())
; 
clearButton.addActionListener(new ButtonHandler())
; 
Panel panel = new Panel()
; 
panel.add(lineButton)
; 
panel.add(ovalButton)
; 
panel.add(rectButton)
; 
panel.add(clearButton)
; 
add("North",panel)
; 
} 
class ButtonHandler implements ActionListener 
{ 
 public void actionPerformed(ActionEvent ev)
{ 
// Handle button clicks 
String s=ev.getActionCommand()
; 
if(s.equals("Clear")) canvas.clear()
; 
else if(s.equals("Line")
) 
 canvas.setTool(TwoPointObject.LINE)
; 
else if(s.equals("Oval")
) 
canvas.setTool(TwoPointObject.OVAL)
; 
else if(s.equals("Rectangle")
) 
canvas.setTool(TwoPointObject.RECTANGLE)
; 
} 
} 
class WindowEventHandler extends WindowAdapter{ 
 public void windowClosing(WindowEvent e) 
{ 
System.exit(0)
; 
} 
} 
} 
class MyCanvas extends Canvas { 
- 241 
// Define the default drawing tool 
int tool = TwoPointObject.LINE; 
Vector objects = new Vector()
; 
TwoPointObject current; 
boolean newObject = false; 
public MyCanvas(int toolType) 
{ 
 super()
; 
tool = toolType; 
// Handle mouse clicking and movement 
addMouseListener(new MouseHandler())
; 
addMouseMotionListener(new MouseMotionHandler())
; 
} 
public void setTool(int toolType) 
{ 
tool = toolType; 
} 
public void clear() 
{ 
 objects.removeAllElements()
; 
repaint()
; 
} 
public void paint(Graphics g) 
{ 
 // Draw/redraw canvas 
int numObjects = objects.size()
; 
for(int i=0;i
 TwoPointObject obj = (TwoPointObject) objects.elementAt(i)
; 
obj.draw(g)
; 
} 
if(newObject) current.draw(g)
; 
} 
class MouseHandler extends MouseAdapter { 
public void mousePressed(MouseEvent e){ 
// Handle mouse down 
- 242 
current = new TwoPointObject(tool,e.getX(),e.getY()); 
 newObject = true; 
} 
public void mouseReleased(MouseEvent e){ 
 // Handle mouse up 
if(newObject) 
{ 
objects.addElement(current)
; 
newObject = false; 
} 
} 
} 
class MouseMotionHandler extends MouseMotionAdapter { 
 public void mouseDragged(MouseEvent e){ 
// Handle mouse movement 
int x = e.getX(); 
int y = e.getY(); 
if(newObject) { 
int oldX = current.endX; 
int oldY = current.endY; 
if(tool != TwoPointObject.LINE) 
{ 
 if(x > current.startX) current.endX = x; 
if(y > current.startY) current.endY = y; 
int width = Math.max(oldX,current.endX) - current.startX + 1; 
int height = Math.max(oldY,current.endY) - current.startY + 1; 
repaint(current.startX,current.startY,width,height)
;
 }else{ 
current.endX = x; 
current.endY = y; 
int startX = Math.min(Math.min(current.startX,current.endX),oldX); 
int startY = Math.min(Math.min(current.startY,current.endY),oldY); 
int endX = Math.max(Math.max(current.startX,current.endX),oldX); 
- 243 
int endY = Math.max(Math.max(current.startY,current.endY),oldY); 
repaint(startX,startY,endX-startX+1,endY-startY+1); 
} 
} 
} 
} 
} 
class TwoPointObject 
{ 
 // Encapsulates objects that can be described using two points 
public static int LINE = 0; 
public static int OVAL = 1; 
public static int RECTANGLE = 2; 
public int type, startX, startY, endX, endY; 
public TwoPointObject(int objectType,int x1,int y1,int x2,int y2) 
{ 
type = objectType; 
startX = x1; 
startY = y1; 
endX = x2; 
endY = y2; 
} 
public TwoPointObject(int objectType,int x,int y) 
{ 
 this(objectType,x,y,x,y)
; 
} 
public TwoPointObject() 
{
 this(LINE,0,0,0,0)
; 
} 
public void draw(Graphics g) 
{ 
 if(type == LINE) g.drawLine(startX,startY,endX,endY)
; 
 else{ 
int w = Math.abs(endX - startX)
; 
int l = Math.abs(endY - startY)
; 
- 244 
if(type == OVAL) g.drawOval(startX,startY,w,l); 
else g.drawRect(startX,startY,w,l); 
} 
} 
} 
Figure 14.1: The DrawApp opening window. 
When you run DrawApp, you will see the opening window shown in Figure 14.1. 
The DrawApp program is initially configured for you to draw lines in its window area. You can draw a 
line by clicking the left mouse button and dragging the mouse. When you have finished drawing the line, 
release the left mouse button and the drawn line will be completed. The coordinate where you press the 
left mouse button is the beginning of the line, and the coordinate where you release the left mouse 
button is the end of the line. Go ahead and draw several lines, as shown in Figure 14.2. 
Figure 14.2: Drawing lines with DrawApp. 
The DrawApp program supports the drawing of lines, ovals, and rectangles. Click the Oval button to 
change the drawing tool to draw ovals. You draw an oval in the same way that you draw a line. When 
you click the left button of your mouse, you mark the upper-left corner of an invisible bounding box 
surrounding the oval. Drag the mouse to where you want the lower-right corner of the oval's bounding 
box and release the left mouse button. Try drawing a few ovals, as shown in Figure 14.3. 
- 245 
Figure 14.3: Drawing ovals with DrawApp. 
Now click the Rectangle button to begin drawing rectangles. You draw rectangles in the same way that 
you draw ovals. Go ahead and draw a rectangle, as shown in Figure 14.4. 
Figure 14.4: Drawing rectangles with DrawApp. 
You can experiment with the program before going on to find out how it works. If you want to clear the 
drawing screen, click the Clear button. 
The DrawApp program is a little longer than the programs you've seen so far in this book. It consists of 
three major classes and three event-handling inner classes. The DrawApp class is the main class used 
to implement the program. The MyCanvas class is used to implement the program's main canvas 
component. The TwoPointObject class is used to implement the line, oval, and rectangle objects that 
are drawn on the screen. It is called TwoPointObject because it supports objects that can be 
characterized by a starting point (mouse down) and an ending point (mouse up). 
DrawApp declares the canvas variable to refer to the MyCanvas object that implements the drawing. 
This object is constructed by passing the TwoPointObject.LINE constant as an argument. This tells 
the constructed object that the line tool should be initially used to support drawing. The height and width 
of the DrawApp window is set to 400 pixels. 
The actionPerformed() method of the ButtonHandler class handles the clicking of the buttons. 
The Clear button is handled by invoking the clear() method of the MyCanvas class to clear the 
canvas to a blank state. The Line, Oval, and Rectangle buttons are handled by invoking the 
setTool() method of the MyCanvas class to set the current drawing tool. It uses the LINE, OVAL, and 
RECTANGLE constants defined in the TwoPointObject class. 
MyCanvas
The MyCanvas class extends the Canvas class to provide custom drawing capabilities. The tool 
variable is used to identify the current drawing tool that is in effect. The objects variable is declared as 
a Vector. It is used to store all the objects drawn by the user. The current variable is used to refer to 
the current TwoPointObject object being drawn by the user. The newObject flag is used to track 
whether the user has begun drawing a new object. 
- 246 
The MyCanvas constructor invokes the constructor of the Canvas class using the superclass 
constructor call statement, and then sets the tool variable to the toolType argument passed to the 
constructor. 
The setTool() method changes the tool used to draw an object. 
The clear() method invokes the removeAllElements() method of the Vector class to remove all 
drawing objects stored in the Vector referenced by the objects variable. 
The paint() method is used to paint and repaint the screen. It uses the size() method of the 
Vector class to determine how many objects are stored in the objects vector and sets the 
numObjects variable to this value. It then iterates through each object stored in objects and draws 
each one on the canvas. The elementAt() method of the Vector class is used to retrieve an object 
from the objects vector. The object is cast into an object of class TwoPointObject and assigned to 
the obj variable. The draw() method of the TwoPointObject class is invoked to draw the object on 
the current Graphics context. 
Notice that the paint() method does not have to know how to support limited area repainting. Only full 
canvas painting needs to be implemented by paint(). Support of limited area repainting is provided by 
the local AWT implementation. 
The MouseHandler and MouseMotionHandler inner classes handle the events associated with 
pressing, releasing, and dragging the mouse. They do this by extending the MouseAdapter and 
MouseMotionAdapter classes of java.awt.event. The MouseHandler class handles the pressing 
and releasing of the mouse button via the mousePressed() and mouseReleased() methods. The 
MouseMotionHandler class handles the dragging of the mouse via the mouseDragged() method. 
The mousePressed() method handles the event that is generated when the user clicks the left mouse 
button in the canvas. The method is called by the Java runtime system with the position of the mouse 
click. A new TwoPointObject object is created, with the tool variable and the position of the mouse 
click as its arguments. The newly created object is assigned to the current variable, and the 
newObject flag is set to true. 
The mouseReleased() method is used to handle the event that is generated when the user releases 
the left mouse button. This action marks the completion of the drawing of an object. The event is 
handled by adding the object referenced by the current variable to the objects vector. The 
newObject flag is then set to False. The object referenced by the current variable is updated with its 
ending position during the processing of the mouseDragged() event-handling method. The 
newObject flag is checked to make sure that the mouse was not clicked outside of the current window 
and then released. 
The mouseDragged() method performs somewhat more sophisticated event-handling than the 
mousePressed() and mouseReleased() methods. It checks the newObject flag to make sure that 
an object is currently being drawn. It then sets the oldX and oldY variables to the ending position of 
the object being drawn. These variables will be used to determine which portion of the canvas needs to 
be repainted. Repainting of the entire canvas is not visually appealing because it causes previously 
drawn objects to flicker. 
If the current drawing tool is not a line, then an oval or a rectangle is the object being drawn by the user. 
The x,y coordinates of the mouse motion are provided via the MouseEvent argument to the 
mouseDragged() method. These coordinates are checked to determine whether the mouse was 
dragged below and to the right of the object being drawn. If this is the case, the ending position of the 
current object is updated. If the mouse is dragged to the left or above the starting point of the object, the 
current position of the mouse is ignored. This is to ensure that the starting position of the oval or 
rectangle is indeed its upper-left corner. The new width and height of the area to be repainted are 
calculated as the maximum area covered by the previous ending position and the current object ending 
position. This is to ensure that the repaint operation will erase any previous boundaries of the object 
being drawn. The max() method of the java.lang.Math class is used to determine this maximum 
area. The repaint() method of the Component class is then used to repaint the area updated as the 
result of the mouse drag. This version of the repaint() method takes as its parameters the x,y 
coordinate of the upper-left corner of the area to be redrawn and the width and height of this area. 
Line drawing is not restricted in the same manner as oval and rectangle drawing. If it were, you would 
not be able to draw lines that go up and to the right or down and to the left. The else part of the if 
statement updates the starting position of the area to be repainted as the upper-leftmost point of the line 
being redrawn. It then updates the ending position of the area to be repainted as the lower-rightmost 
point of the line. The canvas is then repainted using the starting coordinates and the updated width and 
height of the repaint area. 
To get a better feel for the process of local screen repainting, try experimenting with the way the 
repaint() method is used to update the canvas display. 
- 247 
TwoPointObject
The TwoPointObject class is used to keep track of the objects drawn by the user. It records the type 
of object and its starting and ending coordinates. It also draws the objects on a Graphics object 
passed as a parameter. 
TwoPointObject defines the LINE, OVAL, and RECTANGLE constants, which are also used by the 
MyCanvas class. The type variable is used to record the type of object being drawn. The startX, 
startY, endX, and endY variables identify the starting and ending coordinates of the object. 
Three TwoPointObject constructors are declared. The first constructor takes as its parameters the 
type of object being drawn and its starting and ending coordinates. The second constructor leaves out 
the ending coordinate and sets them to be the same as the starting coordinate. The last constructor 
takes no parameters and creates a line at the coordinate 0,0. 
The draw() method checks the type variable to determine which type of object is to be drawn. If the 
object is a line, it uses the drawLine() method of the Graphics class to draw a line from its starting 
to ending coordinate. If the object is an oval or a line, the w and l variables are assigned the width and 
length of the object to be drawn. The drawOval() and drawRect() methods are used to draw an 
oval or rectangle, respectively. 
Drawing Text
The Font class of java.awt provides a platform-independent method of specifying and using fonts. 
The Font class constructor creates Font objects using the font's name, style (PLAIN, BOLD, ITALIC, 
or BOLD + ITALIC), and point size. Java's fonts are named in a platform-independent manner and 
then mapped to local fonts that are supported by the operating system on which it executes. The 
getName() method returns the logical Java font name of a particular font, and the getFamily()
method returns the operating system-specific name of the font. You'll learn the name of the standard 
Java fonts in the next programming example of this chapter. 
The FontMetrics class is used to return the specific parameters for a particular Font object. An 
object of this class is created using the getFontMetrics() methods supported by the Componentclass and other classes, such as 
the Graphics class. The FontMetrics class provides access to the 
details of the implementation of a Font object. 
When text characters are displayed, they are displayed relative to a baseline. The baseline is the line 
drawn through the bottom of nondescending characters. For example, if you drew a line at the bottom of 
most text displayed on this line, you would get the text's baseline. Some characters, such as g and y, 
descend below the baseline. The number of pixels that the characters of a font descend below the 
baseline is known as the font's descent. The number of pixels that the characters of a font extend above 
the baseline is known as the font's ascent. 
Figure 14.5: Font parameters. 
In addition to a font's ascent and descent, a third parameter, referred to as the font's leading, is used to 
describe the amount of vertical spacing, in pixels, used between the descent of a line of text and the 
ascent of the line of text below it. The overall height of a font is the sum of its leading, ascent, and 
descent, and is equal to the distance between baselines (in pixels) of vertically adjacent lines of text. 
The getLeading(), getAscent(), getDescent(), and getHeight() methods of the 
FontMetrics class are used to access these important font-related parameters. Figure 14.5 provides 
a graphical description of these parameters. 
The getMaxAdvance(), getMaxAscent(), and getMaxDescent() methods are provided for 
backward-compatibility with earlier Java versions. 
The FontApp Program 
The FontApp program illustrates the use of the Font and FontMetrics classes and shows how to 
draw text on a Graphics object. Its source code is shown in Listing 14.2. 
FontappListing 14.2: The Source Code of the Program 
- 248 
import java.awt.*; 
import java.awt.event.*; 
public class FontApp extends Frame { 
int screenWidth = 400; 
int screenHeight = 400; 
Font defaultFont; 
// Declare & create FontCanvas object 
FontCanvas fontCanvas = new FontCanvas(); 
String fontNames[]; 
int fontIndex = 0; 
public static void main(String[] args) { 
 FontApp app = new FontApp()
; 
} 
public FontApp() 
{ 
 super("FontApp")
; 
setupFontNames()
; 
Button nextButton = new Button("Next Font")
; 
nextButton.addActionListener(new ButtonHandler())
; 
Panel panel = new Panel()
; 
panel.add(nextButton)
; 
add("North",panel)
; 
add("Center",fontCanvas)
; 
addWindowListener(new WindowEventHandler())
; 
pack()
; 
setSize(screenWidth,screenHeight)
; 
show()
; 
} 
 void setupFontNames() 
{ 
// Get font names from local graphics environment 
GraphicsEnvironment ge 
= 
- 249 
GraphicsEnvironment.getLocalGraphicsEnvironment(); 
 fontNames = ge.getAvailableFontFamilyNames(); 
} 
class ButtonHandler implements ActionListener { 
 public void actionPerformed(ActionEvent ev){ 
// Switch fonts 
int numFonts = fontNames.length; 
if(numFonts > 1) fontIndex = (fontIndex + 1) % numFonts; 
fontCanvas.repaint(); 
} 
} 
class WindowEventHandler extends WindowAdapter{ 
 public void windowClosing(WindowEvent e) { 
System.exit(0); 
} 
} 
class FontCanvas extends Canvas { 
 // Extend Canvas to display fonts 
 public int displayFontName(Graphics g) { 
String text = fontNames[fontIndex]; 
if(defaultFont == null) defaultFont = getFont(); 
FontMetrics fm = g.getFontMetrics(defaultFont); 
int x = (screenWidth - fm.stringWidth(text))/2; 
int y = 10 + fm.getLeading()+fm.getAscent(); 
g.setFont(defaultFont); 
g.drawString(text,x,y); 
return y+fm.getHeight(); 
} 
 public void paint(Graphics g) { 
// Display U.S. alphabet 
String text = "abcdefghijklmnopqrstuvwxyz"; 
- 250 
int sizes[] = {12,14,18,24}
; 
int y = displayFontName(g)
; 
for(int i=0;i
 Font currentFont = 
 new Font(fontNames[fontIndex],Font.PLAIN,sizes[i]); 
g.setFont(currentFont); 
FontMetrics fm = g.getFontMetrics(currentFont); 
int x = (screenWidth - fm.stringWidth(text))/2; 
g.drawString(text,x,y+fm.getLeading()+fm.getAscent()); 
y += fm.getHeight(); 
} 
} 
} 
} 
The FontApp program enables you to display a sample of the fonts that are available on your system. 
Figure 14.6 shows a possible display output. The program displays the name of a font and then a 
sample of how the font renders the lowercase letters a-z in 12, 14, 18, and 24 point sizes. Click the Next 
Font button and the next font supported by your system is displayed. 
The FontApp class declares a number of field variables. The defaultFont variable identifies the 
default font used by the program. The fontNames[] array is used to store the names of the fonts that 
are accessible to Java. 
The setupFonts() method obtains the local GraphicsEnvironment object using the static 
getLocalGraphicsEnvironment() method of the GraphicsEnvironment class. It then uses the 
getAvailableFontFamilyNames() method to obtain the names of all the fonts supported by the 
system. 
The paint() method of the FontCanvas class is where the primary processing of interest takes 
place. It invokes the displayFontName() method to display the name of the next font to be 
displayed. The displayFontName() method returns the vertical offset where the next text line should 
be displayed. The paint() method uses a for statement to loop through the sizes array and display 
a line at each point size. Note how the getLeading(), getAscent(), and getHeight() methods 
are used to determine the vertical position of the text. 
- 251 
Figure 14.6: The FontApp program's output. 
Displaying Bitmapped Images
The drawImage() method of the Graphics class is used to display bitmapped images. It has a 
number of forms that take various arguments. In its simplest form, it takes as its arguments an object of 
the Image class, an object that implements the ImageObserver interface, the x,y-coordinate where 
the image is to be displayed. 
The Image class is an abstract class that provides format-independent access to graphical images. 
Image objects are created by invoking methods of other classes that create images. Examples of these 
image-creating methods are the createImage() methods of the Component and Toolkit classes 
and the getImage() methods of the Toolkit and Applet classes. The getImage() methods are 
best methods for retrieving an image that is stored in a disk file or at a URL. Java currently supports 
GIF- and JPEG-formatted images through these methods. 
The ImageObserver interface is defined in the java.awt.image package. This interface provides a 
set of constants and methods that support the creation and loading of images. The Component class 
implements the ImageObserver interface; and in most cases, the ImageObserver object used as the 
parameter to the drawImage() method can be supplied using the this identifier to reference the 
current Canvas or Frame object being painted. 
The ImageAppProgram 
The ImageApp program shows how bitmapped images can be drawn in a program window using the 
drawImage() method of the Graphics class. Its source code is shown in Listing 14.3. 
ImageappListing 14.3: The Program 
import java.awt.*; 
import java.awt.event.*; 
public class ImageApp extends Frame { 
Image image; 
public static void main(String[] args) { 
 ImageApp app = new ImageApp(); 
} 
public ImageApp() {
 super("ImageApp"); 
- 252 
setBackground(Color.white)
; 
// Use Toolkit to load image file 
Toolkit toolkit = Toolkit.getDefaultToolkit()
; 
image = toolkit.getImage("test.gif")
; 
addWindowListener(new WindowEventHandler())
; 
pack()
; 
setSize(400,400)
; 
show()
; 
} 
public void paint(Graphics g) 
{ 
 g.drawImage(image,0,0,this)
; 
} 
class WindowEventHandler extends WindowAdapter{ 
 public void windowClosing(WindowEvent e) { 
System.exit(0); 
} 
} 
} 
Before running the ImageApp program, copy the test.gif image from the \jc2\ch14 directory of 
the CD-ROM to your jc2\ch07 directory. The ImageApp program displays the image in the test.gif 
file. 
When you run the ImageApp program, it will display the bitmapped image shown in Figure 14.7. 
Figure 14.7: The ImageApp program. 
- 253 
The functionality of the ImageApp program isn't all that astounding. Its purpose is to illustrate the use of 
the methods involved in loading and displaying image files. You can easily upgrade the program to 
display arbitrary GIF or JPEG files by passing the image file name as a program argument. 
The setBackground() method of the Component class sets the program background to white. The 
getImage() method of the Toolkit class is used to load the image in the test.gif file and assign 
it to the image variable. 
The paint() method draws the image referenced by the image variable on the default Graphicsobject of the program window. It 
accomplishes this using the drawImage() method of the Graphicsclass. The arguments to drawImage() include the image to be 
displayed, the x,y coordinate where the 
image is to be drawn, and the object implementing the ImageObserver interface associated with the 
image. The this identifier is used to indicate that the program window is the ImageObserver. 
Clipping
The AWT supports a painting feature known as clipping. Clipping enables you to restrict painting (or 
drawing) operations to a particular shape. The Shape interface is implemented by classes that define 
geometric shapes, such as Rectangle and Polygon. The setClip() method of the Graphics class 
is used to specify a clipping region. It takes a Shape object as an argument. (Another version of the 
setClip() method takes x, y, width, and height arguments.) When a clipping region is specified, 
painting of a Graphics object is limited to the clipping region. The ClipApp program of Listing 14.4 
shows how clipping works. This program creates a Rectangle object that is set as the clipping area. It 
is located at (100,100) and is 200 pixels wide and high. Figure 14.8 shows the image displayed as the 
result of clipping. 
Note Clipping and Repainting When the AWT background thread invokes the 
paint() methods of GUI objects to support repainting, it sets the clipping region 
to the limited area of the applet or application window that requires repainting. 
This speeds up the repaint operation and conserves processing resources. 
Figure 14.8: The ClipApp program limits the painting area. 
Listing 14.4: The Clipapp Program 
import java.awt.*; 
import java.awt.event.*; 
public class ClipApp extends Frame { 
Image image; 
public static void main(String[] args) { 
 ClipApp app = new ClipApp(); 
- 254 
} 
 public ClipApp() { 
super("ClipApp"); 
setBackground(Color.white); 
Toolkit toolkit = Toolkit.getDefaultToolkit(); 
image = toolkit.getImage("test.gif"); 
addWindowListener(new WindowEventHandler()); 
pack(); 
setSize(400,400); 
show(); 
} 
 public void paint(Graphics g) { 
// Set clipping region 
g.setClip(new Rectangle(100,100,200,200)); 
g.drawImage(image,0,0,this); 
} 
class WindowEventHandler extends WindowAdapter{ 
public void windowClosing(WindowEvent e) { 
System.exit(0); 
} 
} 
} 
Chapter Summary 
This chapter covered the classes and interfaces of java.awt that are used to implement drawing and 
painting. You were introduced to the Canvas, Graphics, Image, and Font classes and learned how 
they are used in conjunction with the paint() method. You also built several small Java applications 
that provided concrete painting examples. You should now be prepared to test your knowledge of these 
topics. The following review questions and exam questions will let you know how well you understand 
this material and will give you an idea of how you'll do in related exam questions. They'll also indicate 
which material you need to study further. 
Key Terms
.. Painting 
.. Repainting 
.. Drawing 
- 255 
. 
Clipping 
Review Questions 
1. 
What is the relationship between the Canvas class and the Graphics class? 
2. 
Name three Component subclasses that support painting. 
3. 
What is the difference between the paint() and repaint() methods? 
4. 
What is the difference between the Font and FontMetrics classes? 
5. 
What is clipping? 
6. 
What is the relationship between clipping and repainting? 
Exam Questions 
1. Which of the following are passed as an argument to the paint() method? 
A. A Canvas object 
B. A Graphics object 
C. An Image object 
D. A Paint object 
2. 
Which of the following methods are invoked by the AWT to support paint and repaint 
operations? 
A. 
paint()
B. 
repaint()
C. 
draw()
D. 
redraw()
3. 
Which of the following classes have a paint() method? 
A. 
Canvas 
B. 
Image
C. 
Frame 
D. 
Graphics
4. 
Which of the following are methods of the Graphics class? 
A. 
drawRect()
B. 
drawImage()
C. 
drawPoint()
D. 
drawString()
5. 
Which Font attributes are available through the FontMetrics class? 
A. ascent 
B. leading 
C. 
case 
D. height 
6. 
Which of the following are valid forms of the drawImage() method of the Graphics 
class? 
A. 
drawImage(Image image, int x, int y, ImageObserverobserver)
B. 
drawImage(Image image)
C. 
drawImage(Image image, int x, int y)
D. 
drawImage()
7. 
When the clipping region is set for a Graphics object, which of the following are true? 
A. 
Painting is restricted to the clipping region. 
B. 
Painting is excluded from the clipping region. 
C. 
All painting is prohibited. 
D. 
Painting takes place inside of and outside of the clipping region. 
8. 
Which of the following are true? 
A. 
The AWT automatically causes a window to be repainted when a portion of 
a window has been minimized and then maximized. 
B. 
The AWT automatically causes a window to be repainted when a portion of 
a window has been covered and then uncovered. 
- 256 
C. 
The AWT automatically causes a window to be repainted when application 
data is changed. 
D. 
The AWT does not support repainting operations. 
Answers to Review Questions 
1. 
A Canvas object provides access to a Graphics object via its paint() method. 
2. 
The Canvas, Frame, Panel, and Applet classes support painting. 
3. 
The paint() method supports painting via a Graphics object. The repaint()
method is used to cause paint() to be invoked by the AWT painting thread. 
4. 
The FontMetrics class is used to define implementation-specific properties, such as 
ascent and descent, of a Font object. 
5. 
Clipping is the process of confining paint operations to a limited area or shape. 
6. 
When a window is repainted by the AWT painting thread, it sets the clipping regions to 
the area of the window that requires repainting. 
Answers to Exam Questions 
1. 
B. The paint() method has a Graphics argument. 
2. 
A. The AWT causes the paint() method to be invoked. 
3. 
A and C. The Canvas and Frame classes inherit paint() from Component. 
4. 
A, B, and D. The Graphics class supports all the methods except drawPoint(). 
5. 
A, B, and D. Ascent, leading, and height are available through FontMetrics. 
6. 
A. The first form is the simplest form of drawImage(). 
7. 
A. The purpose of clipping is to restrict painting operations to the clipping region. 
8. 
A and B. The AWT automatically repaints portions of a window that require repainting as 
the result of window movement and resizing operations.
 
No comments:
Post a Comment