- Using Visual J++ -

Chapter 14

Adding Graphics


In this chapter, you'll learn how to use graphics in your Visual J++ programs. More importantly, you'll have fun! Everybody agrees that writing programs with graphics is cool and you'll see that the Visual J++ support routines makes graphics creation simple.

This chapter introduces you to the graphics coordinate system that acts like a grid on which you lay out graphic shapes. After you learn how to specify grid locations, you learn how to draw different kinds of shapes on the screen and color those shapes to make them more appealing to your end-users.

Introduction to Visual J++ Graphics

"A picture is worth a thousand words," and that sage is certainly true in the business and scientific world where vast numeric trends can easily be analyzed by looking at graphics. Computers are visual tools, whereas just a few years ago, computers were textual only. The Windows operating environments make graphics more important than ever. The Web sites you frequently visit are graphical because Web designers know the importance of eye-catching displays that keep users coming back.

This and the next chapter introduce you to Visual J++'s graphics capabilities. The Java language supports primitive drawing tools with which you can color your applets and draw lines that demonstrate your artistic abilities! The graphics classes let you add artwork to your tables and charts and produce colorful figures to illustrate a point.

 
This chapter teaches you about primitive graphics methods you can use to add simple art to your applets such as dots, lines, circles, and colors. Chapter 15, "Displaying Graphic Images," goes into more detail about adding graphic images and animation to your programs.
 
 
As chapter 6, "Reviewing the Sample Code," explains, you can study the GraphicsText sample project that comes with Visual J++ to get an in-depth look at the graphics classes described in this chapter.

Understanding the Graphic Coordinate

Figure 14.1 shows how the graphics class methods view your applet's window. The classes use x- and y-coordinate pairs (also called Cartesian coordinates) to indicate the number of pixels (picture elements or dots on your screen) down and to the right of your applet window. The upper-left corner is often called the window's home position. Figure 14.1 shows two points, each defined by their coordinate pair, at 100, 200, which literally means (in Visual J++ lingo) that the point is 100 pixels down from the home position and 200 pixels to the right, and 415, 370. (Graphics coordinates can never be negative and go from 0 to the highest numbered row and column pixel on your screen.)


FIG. 14.1

All coordinates start in the upper-left corner.

Understanding the graphics coordinate system is critical before you begin to learn the graphics methods, because you draw graphics at these coordinate locations. In other words, if you want to draw a diagonal line from the applet window's home position, you specify the 0, 0 coordinate when you call line-drawing methods.

 
Place graphics routines inside the paint() method so the graphics appear every time your applet window appears. Although the graphics routines can go in other methods, you should use paint() when learning graphics to ensure that graphics always appear when you run the applet. The New Project Wizard always includes the paint() method in the wizard's generated code.

Preliminary Routines

The graphics methods that you learn in this chapter are sometimes called primitive graphics methods. The methods form the building blocks for artwork you place on your applet windows. The next chapter shows you how you can extend these routines and take advantage of more powerful routines to produce more complex graphic images. The starting point for learning about graphics are these primitive routines because you master the coordinate system in this chapter and get a good grasp of the tools you can use.

The following are the most common primitive graphics that you can draw:

Each of the following sections explain these graphic elements.

 
All of the graphics class methods appear in the Java.awt class package as explained in chapter 19, "Visual J++ Applet and AWT Class Reference."

Drawing Lines and Setting Points

The smallest addressable screen graphic element is the pixel, which represents one dot, or point, on your screen. A collection of points next to one another forms a line. In other words, to draw a line, you must tell your applet to draw, or turn on, a bunch of pixels that fall next to each other.

Here is the general format of the drawLine() method that draws lines on your applet's window:

graphicsContext.drawLine(int x1, int y1, int x2, int y2);

The graphicsContext is the applet's window, often passed to paint() with the name, g, as you've seen already. The x1 and y1 parameters define the line's starting point, and x2 and y2 define the line's terminating point. The applet draws a line by turning on all pixels in a straight line between the two coordinate pairs. (Depending on the line's angle and the screen's resolution, the line may appear slightly crooked in places.)

Assume that an applet's window is 400 pixels wide (the x-coordinate distance) by 300 pixels tall (the y-coordinate distance). The minimum coordinate pair (the home position) is 0, 0 and the maximum coordinate possible is 399, 299. The following statement draws a line from the upper-left corner to the lower-right corner of that applet's window:

g.drawLine(0, 0, 399, 299); // Draws a diagonal line

 
The drawLine()'s coordinates can appear in any order. In other words, you can draw the line from any point to any other point, not just from left-to-right and top-to-bottom.

Although the lines appear chaotic, the following paint() method generates the lines in figure 14.2.


public void paint(Graphics g)
{
g.drawLine(0, 0, 399, 299); // Draw diagonal lines
g.drawLine(20, 40, 6, 19);
g.drawLine(100, 200, 125, 250);
g.drawLine(50, 300, 5, 200);
g.drawLine(200, 15, 195, 60);
g.drawLine(125, 50, 175, 100);
g.drawLine(150, 10, 10, 180);
g.drawLine(399, 0, 0, 299);
g.drawLine(200, 50, 25, 80);
}


FIG. 14.2

Use drawLine() to draw lines on your applet's screen.

Use drawLine() to turn on individual pixel points. Java's AWT class library does not support a single pixel-painting method, so you must draw a line between two identical coordinate pairs if you want to turn on a single pixel. The following drawLine() method turns on the point at 50, 50:

g.drawLine(50, 50, 50, 50); // Turns on a single pixel

If you need to work with pixels, you may want to write a new pixel() method that accepts a single coordinate pair and passes that pair two times to the drawLine() method. Here is a sample:


public void paint(int x, int y)
{
g.drawLine(x, y, x, y); // Turn on a single pixel point
}

 
To erase a pixel, line, or any other graphic element you've drawn, you can redraw the element after coloring the element the same color as the screen's background color. The last section in this chapter, "Working with Colors," explains how to use color with your graphics.
 
 
You'll find a Point() method listed in chapter 20's Java.awt reference section. Point() constructs an object that contains two coordinate pairs. In more advanced graphics programming, you can utilize OOP concepts that work with these point objects. For now, such discussion would only cloud the graphics programming methods. (Despite its name, the Point() constructor method does not turn on or off points, but merely constructs individual point objects.)

Drawing Rectangles

The drawRect() method draws simple rectangles on your screen. You define a rectangle by its upper-left and lower-right corners' coordinates and then specify the width and height of the rectangle (in pixels). Here's the general format for drawRect():

graphicsContext.drawRect(int x, int y, int width, int height);

The following statement draws a 200-pixel wide and 150-pixel high rectangle that begins at coordinate 40, 50:

g.drawRect(40, 50, 200, 150); // Draws a rectangle

 
Be careful that your drawRect() method's last two parameters specify width and height and not ending pixel coordinates as they do with the drawLine() method.

Obviously, you can draw squares by specifying the same width and height parameters.

Instead of drawing empty rectangles, you can draw solid rectangles by using the fillRect() method, which has this format:

graphicsContext.fillRect(int x, int y, int width, int height);

The rectangle appears solid because your applet draws the rectangle with the current active drawing color (which is black by default). The clearRect() method also comes in handy when drawing rectangles. clearRect() draws a filled rectangle with the same color as your applet's background (gray by default), which appears to erase the rectangular region. Although you cannot adjust the line width of your rectangles, you can draw a filled rectangle and then use the clearRect(), whose format is as follows, to erase the center portion:

graphicsContext.clearRect(int x, int y, int width, int height);

The following two lines produced figure 14.3:


g.fillRect(20, 20, 175, 125); // Draw a filled rectangle
g.clearRect(30, 30, 155, 105); // Erase the center

Figure 14.3 shows how you can combine fillRect() and clearRect() to produce a thick-lined rectangle.


FIG. 14.3

Use fillRect() and clearRect() to draw thick rectangles.

Java.awt supports additional rectangle methods you can use to produce different kinds of rectangular effects. The draw3DRect() and fill3DRect() methods produce a three-dimensional effect by raising or lowering two sides of a rectangle. Here are the formats for draw3DRect() and fill3DRect():


graphicsContext.draw3DRect(int x, int y, int width, int height, boolean raise);
graphicsContext.fill3DRect(int x, int y, int width, int height, boolean raise);

The raise parameter, which must be true or false, determines if the applet raises the rectangle or lowers (depresses) the rectangle on the screen. Before getting the raised or depressed appearance, you should set the drawing color to the same color as the background color (see this chapter's last section) or the rectangles will not produce their desired 3D effects. The default black drawing color produces no real 3D effect.

All of the rectangular methods you've seen produce squared rectangles. You can draw rectangles with rounded corners by using the following methods that mirror the ones you've learned so far:


graphicsContext.drawRoundRect(int x, int y, int width, int height, int
[ic:ccc]arcWidth, int arcHeight);
graphicsContext.fillRoundRect(int x, int y, int width, int height, int
[ic:ccc]arcWidth, int arcHeight);

The extra parameters, arcWidth and arcHeight, determine how rounded your rectangle's corners appear. The arcWidth parameter trims arcWidth pixels from the left and right of each corner while arcHeight trims arcHeight pixels from the top and bottom of each corner. Figure 14.4 shows a rounded rectangle produced from the following statement:

g.fillRoundRect(20, 20, 200, 200, 30, 30); // Draw a filled rounded rectangle


FIG. 14.4

Round out your rectangles with drawRoundRect() and fillRoundRect().

Drawing Polygons

A polygon is a multi-sided figure. Therefore, a rectangle is a four-sided polygon. Visual J++ supplies polygon methods. The distinguishing characteristic of the polygon methods are that you pass an array of points to the polygon methods so that Visual J++ can play connect-the-dots and produce the figure.

 
If you want your polygon to be enclosed, make sure that the last coordinate pair in the polygon's coordinate array matches the first pair.

Here are the two most common polygon-related methods:


graphicsContext.drawPolygon(int x[], int y[], int points);
graphicsContext.fillPolygon(int x[], int y[], int points);

The x[] and y[] integer array parameters contain the polygon's coordinate pairs and the points parameter determines how many of the points the method is to draw. If the arrays contain more points than you specify in the points parameter, the method draws only a partial polygon.

The following paint() method defines and draws figure 14.5's five-pointed star:


public void paint(Graphics g)
{
int x[] = {75, 150, 225, 0, 300, 75}; // Defines a 6 element array
int y[] = {300, 0, 300, 100, 100, 300}; // Defines a 6 element array
g.fillPolygon(x, y, 6); // Draws a star
}


FIG. 14.5

Use the polygon methods to draw any shape.

 
Visual J++ filled in the star only partially due to the nature of pixel graphics. The inside edge points of this particular star do not exactly meet so the applet did not fill in the center of the star. The applet thought that the star's center was unconnected at the five inside points.

Visual J++ lets you create a polygon object (as well as rectangles, lines, and circles), which sometimes makes drawing your polygons easier. The following paint() method produces the same output as figure 14.5:


public void paint(Graphics g)
{
int x[] = {75, 150, 225, 0, 300, 75}; // Defines a 6 element array
int y[] = {300, 0, 300, 100, 100, 300}; // Defines a 6 element array
Polygon starPolygon = new Pol;ygon(x, y, 6); // Creates a polygon object
g.fillPolygon(starPolygon); // Draws the star
}

Although the routine seems more complicated, the rectangle object streamlines subsequent polygon drawings you might make of the star.

Drawing Ovals and Circles

An ellipse is a round shape, whether that shape makes an oval or a perfect circle. An ellipse's width value specifies the number of pixels wide the ellipse appears at its widest point and the height value specifies the number of pixels tall the ellipse appears at its tallest point. As with other shapes, you can draw both ellipse outlines and filled ellipses.

 
If you need to draw a perfect circle, use the same width and height ellipse values.

Here are the primary ellipse method formats:


graphicsContext.drawOval(int x, int y, int width, int height);
graphicsContext.fillOval(int x, int y, int width, int height);

The x and y parameters specify the location of the ellipse if the ellipse were placed inside a rectangle. In other words, you must picture a rectangle around the ellipse that you want to draw and locate that rectangle's upper-left corner at the x- and y-coordinates that you specify.

The following paint() method draws figure 14.6's ellipses:


public void paint(Graphics g)
{
g.drawOval(5, 5, 40, 50); // Oval
g.drawOval(125, 5, 100, 100); // Circle
g.fillOval(250, 5, 100, 25); // Wide oval
g.fillOval(5, 125, 100, 100); // Circle
g.fillOval(125, 125, 40, 50); // Oval
g.drawOval(250, 125, 40, 100); // Tall oval
}


FIG. 14.6

Draw ellipses and circles with the drawOval() and fillOval() methods.

Working with Colors

If you've never programmed computer colors before, you may think the methods described here are a little more complex than they should be. The problem is that computers are capable of displaying millions of colors covering the entire color spectrum, and specifying a simple color, such as orange, requires that you tell the computer which hue and shade of orange you prefer.

 
Fortunately, the Java.awt class package does contain a set of pre-defined colors constants you can use as long as you're happy with the pre-defined color hues and shades. If you want to use a different color, you will not be able to use the pre-defined colors.

Table 14.1 lists the pre-defined color constants, found in the java.awt.Color class, that you can use if you want to color a drawing with one of the pre-defined colors.

Table 14.1 The Pre-Defined Colors and Their RGB Combination Equivalents

Color RGB Equivalent Value
Color.black 0, 0, 0
Color.blue 0, 0, 255
Color.cyan 0, 255, 255
Color.darkGray 64, 64, 64
Color.gray 128, 128, 128
Color.green 0, 255, 0
Color.lightGray 192, 192, 192
Color.magenta 255, 0, 255
Color.orange 255, 200, 0
Color.pink 255, 175, 175
Color.red 255, 0, 0
Color.white 255, 255, 255
Color.yellow 255, 255, 0

When you want to draw a shape with a certain color, you must first determine the drawing color with the setColor() method, which has this format:

graphicsContext.setColor(Color colorRGBValue);

The colorRGBValue must be a special RGB color combination. RBG stands for Red/Green/Blue and the numbers representing a combination of red and green and blue elements produce the exact color you want to display. Each red, green, and blue component can range from 0 to 255.

The pre-defined colors are the simplest to work with. For example, to draw a red square, you can do this:


g.setColor(Color.red); // Set the drawing color to red
g.drawRect(40, 50, 100, 100); // Draws a rectangle

 
setColor() sets the color for subsequent drawing but does not change existing colors. Therefore, if you call setColor() with a different color value before drawing each one of five ovals, all five ovals will appear with a different color.

setColor() changes the foreground color, which is the color for objects appearing on your screen, such as the shapes you've learned to draw in this chapter. If you want to set the background color, use the setBackground() method, which has this format:

graphicsContext.setBackground(Color colorRGBValue);

The background is the backdrop on which your shapes appear. (In this book, the foreground color is the black of the text and the background is the white of the page.)

If you don't use one of the pre-defined colors, the setColor() and setBackground() methods get kind of confusing. You must know the RGB combination for the color you desire. You then must list the three values for the color-setting methods, such as this:

g.setColor(new Color(45, 87, 192));

The embedded Color() method is a constructor that constructs a color from the three RGB values. You can define your colors ahead of time by instantiating color objects. The following two statements are equivalent to the previous one:


Color myColor = new Color(45, 87, 192); // Creates a color object
g.setColor(myColor); // Sets the new color

If you are going to work with your own color in more than one method, instantiating the color value first increases the efficiency of your program and makes programming simpler and less error-prone.

 
Instead of using RGB integer combinations that range from 0 to 255, you can use floating-point values that range from 0.0 to 1.0, representing the percentage of each color component that you want to use. Therefore, setColor(new Color(0, 255, 0)); is identical to setColor(new Color(0.0, 1.0, 0.0));.

Summary

The goal of this chapter was to demonstrate how easy graphics shapes are to draw. By adding colorful graphics to your programs, you increase the programs' appeal and add more eye-catching pizazz to your applets.

Visual J++ includes many other graphics commands that you can use for drawing and coloring shapes on your applet's screen. Visual J++ includes methods that test for graphic locations, move graphics from one pixel location to another, and produce various overlays and combinations.

The next chapter picks up where this one leaves off by demonstrating how to insert and manipulate graphic images on your applet's screen.

Here are the points this chapter covered:


Previous Page TOC Next Page

| Previous Chapter | Next Chapter |

| Table of Contents | Book Home Page |

| Que Home Page | Digital Bookshelf | Disclaimer |


To order books from QUE, call us at 800-716-0044 or 317-361-5400.

For comments or technical support for our books and software, select Talk to Us.

© 1996, QUE Corporation, an imprint of Macmillan Publishing USA, a Simon and Schuster Company.