Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
The graphics toolbox within the Abstract Windowing Toolkit (or AWT) makes it possible for a Java programmer to draw simple geometric shapes, print text, and position images within the borders of a component, such as a frame, panel, or canvas.
This column is my first on the topic of graphics. It will focus on the
Graphics class and its methods for drawing simple geometric shapes, and will introduce the process by which painting (and repainting)
Let's begin at center stage -- the
It's essential that programmers understand the
Graphics class before they attempt to draw images via Java. The
Graphics class provides the framework for all graphics operations within the AWT. It plays two different, but related, roles. First,
it is the graphics context. The graphics context is information that will affect drawing operations. This includes the background
and foreground colors, the font, and the location and dimensions of the clipping rectangle (the region of a component in which
graphics can be drawn). It even includes information about the eventual destination of the graphics operations themselves
(screen or image). Second, the
Graphics class provides methods for drawing simple geometric shapes, text, and images to the graphics destination. All output to the
graphics destination occurs via an invocation of one of these methods.
In order to draw, a program requires a valid graphics context (represented by an instance of the
Graphics class). Because the
Graphics class is an abstract base class, it cannot be instantiated directly. An instance is typically created by a component, and
handed to the program as an argument to a component's update() and paint() methods. These two methods, along with the repaint() method, are discussed in the next section.
The following three methods are involved in displaying graphics. Default versions of each are provided by class
Component. Methods update() and paint() should be redefined to perform the desired graphics operations.
Read more about Core Java in JavaWorld's Core Java section.
The repaint() method requests that a component be repainted. The caller may request that repainting occur as soon as possible, or may specify a period of time in milliseconds. If a period of time is specified, the painting operation will occur before the period of time elapses. The caller may also specify that only a portion of a component be repainted. This technique is useful if the paint operation is time-consuming, and only a portion of the display needs repainting. The code in Listing 1 illustrates how the repaint() method might be used in a program.
Listing 1: Mouse-down event handler
The code in the mouseDown() event handler recalculates the position of an object in a display based on the position of the mouse and calls the repaint() method to indicate that the display should be repainted as soon as possible.
The update() method is called in response to a repaint() request, or in response to a portion of the component being uncovered or displayed for the first time. The method's sole argument is an instance of the
Graphicsinstance is valid only within the context of the update() method (and any methods it calls), but is disposed of soon after the update() method returns. The default implementation provided by the
Componentclass erases the background and calls the paint() method (below).
The paint() method is called from an update() method, and is responsible for actually drawing the graphics. The method's sole argument is an instance of the
Graphicsclass. The default implementation provided by class
To reduce the time required to repaint the display, the AWT takes two shortcuts:
The applet in Figure 1 allows you to observe this process as it occurs. Ignore the text area at the top of the applet for a moment, and watch only the colored portion of the display. Using another window, momentarily cover and then uncover part of the applet. Notice that only the portion of the applet that was covered is repainted. Furthermore, only those components that were covered are repainted, no matter what their position in the component hierarchy. By deliberately using different colors, the applet makes this subtle effect noticeable. The source code for this figure is available here.
The methods described in the following section take, as parameters, values that specify how a shape is to be drawn. For example, the drawLine() method expects four parameters. The first two parameters specify the location of the beginning of the line, and the last two parameters specify the location of the end of the line. The exact values to be passed to the drawLine() method are determined by the coordinate system in effect.
A coordinate system is a method for unambiguously specifying the location of points in space. In the case of the AWT, this space is a two-dimensional surface called a plane. Each location in a plane can be specified by two integers, called the x and y coordinates. The values of the x and y coordinates are calculated in terms of the point's respective horizontal and vertical displacement from the origin. In the case of the AWT, the origin is always the point in the upper-left corner of the plane. It has the coordinate values 0 (for x) and 0 (for y). The illustration in Figure 2 shows two points -- one located at the origin, and another located at a position seven across and five down from the origin.
Figure 2: The coordinate plane
This section introduces methods for drawing lines, rectangles, ovals and arcs, and polygons. Since these methods work only when invoked on a valid
Graphicsinstance, they may be used only within the scope of a component's update() and paint() methods. Most of the methods that follow come in pairs. One method (the drawX() method) draws only the outline of the specified shape, and the other method (the fillX() method) draws a filled version of the specified shape.
This is the simplest of all graphics methods. It draws a straight line, a single pixel wide, between the specified beginning and ending points. The resulting line will be clipped to fit within the boundaries of the current clipping region. The line will be drawn in the current foreground color.
The applet in Figure 3 demonstrates the drawLine() method in action. The source code is available here. This applet and the applets in Figures 4, 6, and 7 require the services of two support classes: the NewCanvas class, and the Figure interface. The NewCanvas class extends class Canvas, and provides a specialized drawing surface for figures. The source code for the NewCanvas class is available here. The Figure interface defines the methods a figure must provide in order to be used with NewCanvas. The source code for the Figure interface is available here.
Figure 3: Line drawing demonstration
Each of these graphics methods require, as parameters, the x and y coordinates at which to begin the rectangle, and the width and the height of the rectangle. Both the width and the height must be positive integers. The resulting rectangle will be clipped to fit within the boundaries of the current clipping region. The rectangle will be drawn in the current foreground color. Rectangles come in three different styles: plain, with rounded corners, and with a slight (but often hard-to-see) three-dimensional effect.
The rounded-rectangle graphics methods require two additional parameters, an arc width and an arc height, both of which control the rounding of the corners. The three-dimensional rectangle methods require an additional parameter that indicates whether or not the rectangle should be sunken or raised.
The applet in Figure 4 demonstrates these methods in action. The source code is available here.
Figure 4: Rectangle drawing demonstration
ovals and arcs
Each of these graphics methods require, as parameters, the x and y coordinates of the center of the oval or arc, and the width and height of the oval or arc. Both the width and the height must be positive integers. The resulting shape will be clipped to fit within the boundaries of the current clipping region. The shape will be drawn in the current foreground color.
The arc graphics methods require two additional parameters, a start angle and an arc angle, to specify the beginning of the arc and the size of the arc in degrees (not radians). Figure 5 illustrates how angles are specified.
Figure 5: Angle specification
The applet in Figure 6 demonstrates these methods in action. The source code is available here.
Figure 6: Oval and arc drawing demonstration
Polygons are shapes formed from a sequence of line segments. Each of the polygon graphics methods require, as parameters, the coordinates of the endpoints of the line segments that make up the polygon. These endpoints can be specified in either one of two ways: as two parallel arrays of integers, one representing the successive x coordinates and the other representing the successive y coordinates; or with an instance of the
Polygonclass provides the method addPoint(), which allows a polygon definition to be assembled point by point. The resulting shape will be clipped to fit within the boundaries of the current clipping region.
The applet in Figure 7 demonstrates these methods in action. The source code is available here.
Figure 7: Polygon drawing demonstration
Believe it or not, these few simple graphics primitives, combined with all we've covered in the last several months (the AWT, event handling, observers, etc.) are all that you need to write a heap of useful applications, ranging from games to CAD systems. Next month, I'll put all of these bits and pieces together and show you what I mean.