Welcome!

PowerBuilder Authors: Chris Pollach, Yeshim Deniz, Jayaram Krishnaswamy, Kevin Benedict, Avi Rosenthal

Related Topics: PowerBuilder

PowerBuilder: Article

Spice Up Your Applet With The Graphics Class

Spice Up Your Applet With The Graphics Class

Complex graphics programming is something we rarely do in PowerBuilder. Most of the programs we write include objects that interact with the user and usually don't require graphics.

The graphics that we do use are simple geometric features, such as lines and rectangles, to provide a bit of spice to our programs. However, Java works a bit differently since applets use a lot more graphics.

Most applets use both simple and complex graphics to add energy to the overall presentation. My next three articles will focus on adding simple (then complex) graphics and animation to your Java applets.

The Paint Method
In an applet the paint() method is automatically fired when it's rendered (Javaspeak for "displayed"). When the applet is loaded into the browser and the user resizes the browser, Java automatically fires this method. For PowerBuilder programmers this method acts more like an event. If necessary we can fire this method ourselves, but in general the method is automatically fired by Java.

Java passes us a graphics object as part of the paint method signature. This class contains basic geometric shapes as well as the methods to manipulate them.

The Coordinate System
Java uses the standard, two-dimensional computer graphics coordinate system. The first visible pixel in the upper-left corner of the applet canvas is (0, 0). Coordinates increase to the right and down (see Figure 1).

Graphics Objects
In Java most drawing takes place via a graphics object. This is an instance of the class java.awt.Graphics.

Initially, the graphics object you use will be the one passed as an argument to an applet's paint() method. Later, you'll see other graphics objects too. Everything you learn here about drawing in an applet transfers directly to drawing in other objects, such as panels, frames, buttons, canvases, and more. More about these classes in later articles.

Each graphics object has its own coordinate system and all the graphics' methods, including those for drawing Strings, lines, rectangles, circles, polygons, and more. Drawing in Java starts with a particular graphics object. Access it through the paint(Graphics g) method of your applet. Each draw method call looks like:

g.drawString("Hello World", 0, 50)
where g is the particular graphics object with which you're drawing. For the sake of convenience, in this article the variable g always refers to a preexisting object of the Graphics class. As with any other method you're free to use some other name for the particular graphics context, myGraphics or appletGraphics, perhaps.

Drawing Lines
Drawing straight lines with Java is easy, simply call:

g.drawLine(x1, y1, x2, y2)
where (x1, y1) and (x2, y2) are the endpoints of your lines and g is the graphics object you're drawing with. This program draws a line diagonally across the applet:
import java.applet.*;
import java.awt.*;

public class SimpleLine extends
Applet {

public void paint(Graphics g) {
g.drawLine(0, 0,
this.getSize().width,
this.getSize().height);
}

}

Drawing Rectangles
Drawing rectangles is simple. Start with a graphics object g and call its drawRect() method:

public void drawRect(int x, int y,
int width, int height)
As the variable names suggest, the first int is the left side of the rectangle, the second is the top, the third is the width, and the fourth is the height, in contrast to some APIs where the four sides of the rectangle are given. This uses drawRect() to draw a rectangle around the sides of an applet:
import java.applet.*;
import java.awt.*;

public class RectangleApplet extends
Applet {
public void paint(Graphics g)  {
g.drawRect(0, 0,
this.getSize().width - 1,
this.getSize().height - 1);
}
}
Remember that getSize().width is the width of the applet and getSize().height is its height. Why was the rectangle drawn only to getSize().height-1 and getSize().width-1?

Remember that the upper-left corner of the applet starts at (0, 0), not (1, 1). This means that a 100x200 pixel applet includes the points with x coordinates between 0 and 99, not between 0 and 100. Similarly the y coordinates are between 0 and 199 inclusive, not 0 and 200.

There's no separate drawSquare() method. A square is just a rectangle with equal length sides. To draw a square, call drawRect() and pass the same number for both the height and width arguments.

Filling Rectangles
The drawRect() method draws an open rectangle, a box if you prefer. If you want to draw a filled rectangle, use the fillRect() method; otherwise, the syntax is identical.

This program draws a filled square in the center of the applet. This requires you to separate the applet width and height from the rectangle width and height. Listing 1 provides the code.

Clearing Rectangles
It's also possible to clear a rectangle that you've drawn. The syntax is exactly what you'd expect:

public abstract void clearRect(int x,
int y, int width, int height)
This program uses clearRect() to blink a rectangle on the screen (see Listing 2).

Ovals and Circles
Java has methods to draw outlined and filled ovals. As you probably guessed, these methods are called drawOval() and fillOval(), respectively. As you might not have guessed, they take identical arguments to drawRect() and fillRect(), for example:

public void drawOval(int
left, int top, int width, int height)
public void fillOval(int
left, int top, int width, int height)
Instead of the dimensions of the oval itself, the dimensions of the smallest rectangle that can enclose the oval are specified. The oval is drawn as large as it can be in order to touch the rectangle's edges at their centers. Figure 2 may help.

The arguments to drawOval() are the same as the ones to drawRect(). The first int is the left-side of the enclosing rectangle, the second is the top, the third is the width, and the fourth is the height. There's no special method to drawing a circle. Just draw an oval inside a square.

Java also has methods to draw outlined and filled arcs. They're similar to drawOval() and fillOval(), but you must also specify a starting and ending angle for the arc. Angles are given in degrees. The signatures are:

public void drawArc(int
left, int top, int width, int height, int star-
tangle, int stopangle)
public void fillArc(int left, int
top, int width, int height, int
startangle, int stopangle)
The rectangle is filled with an arc of the largest circle that could be enclosed within it. The location of 0 degrees and whether the arc is drawn clockwise or counterclockwise are currently platform-dependent.

Bullseye
This is a simple applet that draws a series of filled, concentric circles alternating red and white, in other words, a bullseye (see Listing 3).

The .class file that draws this image is only 684 bytes. The equivalent GIF image is 1,850 bytes, almost three times larger.

Almost all work in this applet consists of centering the enclosing rectangles inside the applet. The lines in bold do that. The first two lines set the height and the width of the rectangle to the appropriate fraction of the applet's height and width. The next two lines set the position of the upper-left corner. Once the rectangle is positioned, drawing the oval is easy.

Polygons
In Java, rectangles are defined by the position of their upper-left corner, their height, and their width. However, it's implicitly assumed that there is, in fact, an upper-left corner. Not all rectangles have one. For instance consider the rectangle in Figure 3.

Where is its upper-left corner? What's been assumed so far is that the sides of the rectangle are parallel to the coordinate axes. You can't yet handle a rectangle that's been rotated at an arbitrary angle.

There are also other things you can't handle - triangles, stars, rhombuses, kites, octagons, and more. To take care of this broad class of shapes, Java has a Polygon class. Polygons are defined by their corners. No assumptions are made about them except that they lie in a 2D plane. The basic constructor for the Polygon class is:

public Polygon(int[] xpoints, int[]
ypoints, int npoints)

xpoints is an array that contains the x coordinates of the polygon; ypoints contains the y coordinates. Both should have the length npoints. Thus, to construct a 3-4-5 right triangle with the right angle on the origin, type:

int[] xpoints = {0, 3, 0};
int[] ypoints = {0, 0, 4};
Polygon myTriangle = new
Polygon(xpoints, ypoints, 3);
To actually draw the polygon use java.awt.Graphics's drawPolygon(Poly- gon p) method within your paint() method:
g.drawPolygon(myTriangle);
You can pass the arrays and number of points directly to the drawPolygon() method if you prefer:
g.drawPolygon(xpoints, ypoints,
xpoints.length);
There's also a polymorphic fillPolygon() method. The syntax is exactly what you'd expect:
g.fillPolygon(myTriangle);
g.fillPolygon(xpoints, ypoints,
xpoints.length());
Polylines Java automatically closes the polygons it draws. That is, it draws polygons that look like the one on the right rather than the one on the left (see Figure 4).

Next Month
As you can see, using basic shapes in Java is much different than it is in PowerBuilder. In PowerBuilder, using simple shapes is easy; we just drag-and-drop them in our window or DataWindow. Applets on the other hand require a bit of work. These basic shapes should give you enough to work on for now. Next month I'll show you how to use images within your applet.

More Stories By Bob Hendry

Bob Hendry is a PowerBuilder instructor for Envision Software Systems and a frequent speaker at national and international PowerBuilder conferences. He specializes in PFC development and has written two books on the subject, including Programming with the PFC 6.0.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.