Color makes life interesting, so we'll add some colors to PaintApp. Specifically, we'll set the colors of the foreground, background, and the border of the drawing area. Later, PaintApp will allow the user (i.e. the one building the Web page) to change these colors using applet parameters, but for now, these values will be hard-coded into the program.
To keep things simple, PaintApp will only support a single drawing color.
We use three private
fields to store these colors, named backColor
, foreColor
, and borderColor
. These are all objects of class Color
. Add the following line marked blue to the Fields section of PaintApp
:
// // Fields // private Dimension size; private Color backColor, foreColor, borderColor; private Image drawImage; private Graphics gDraw;
The fields are set to their initial values in the init()
method. Add the marked lines below:
public void init() { size = size(); backColor = getBackground(); foreColor = Color.black; borderColor = Color.black; clearImage(); }
The Applet class's getBackground()
method returns the background color, and we assign this to backColor
. We then set foreColor
and borderColor
to black. Color.black
is a constant defined in the Color
class.
We also need to change our clearImage()
method to use these colors. Add the marked lines below:
private void clearImage() { drawImage = createImage(size.width, size.height); gDraw = drawImage.getGraphics(); gDraw.setColor(backColor); gDraw.fillRect(0, 0, size.width, size.height); gDraw.setColor(borderColor); gDraw.drawRect(0, 0, size.width - 1, size.height - 1); gDraw.setColor(foreColor); }
What does all this mean?
clearImage
in DetailWe finally get to use some graphics routines! After the drawing buffer is created, we draw the background and the border. This is where gDraw
, our Graphics
object linked to the drawing buffer, comes into play. We'll be setting the drawing color and drawing rectangles. Obviously, we need to tell Java where to draw them! The Graphics
class provides methods that let us draw onto it.
Look at these lines:
gDraw.setColor(backColor); gDraw.fillRect(0, 0, size.width, size.height);
Using the Graphics
class's setColor()
method, the first statement sets the drawing color of gDraw
to the background color. Then it draws a filled rectangle, using fillRect()
, that covers the entire applet area. The rectangle's origin is at (0, 0), the upper-left corner, and its size is equal to the size of the applet, which we previously stored in size
.
Then next two lines then draw the border:
gDraw.setColor(borderColor); gDraw.drawRect(0, 0, size.width - 1, size.height - 1);
We set the drawing color to the border color, and then draw a hollow rectangle that stretches from the upper-left corner to the lower-right corner. We need to subtract one from each dimension; otherwise, the right and lower edges of the rectangle would wind up one pixel too far outside the applet area, and they wouldn't show up. (We didn't need to subtract one when we filled the rectangle.)
Finally, we set the drawing color to the foreground color, in preparation for some scribbling:
gDraw.setColor(foreColor);
There is a change we need to make to the way Java paints our applet. Add the following methods after the init()
method:
public void paint(Graphics g) { g.drawImage(drawImage, 0, 0, null); } public void update(Graphics g) { // Override-don't erase background paint(g); }
The paint()
method is where all our drawing to the screen takes place. This method is called whenever the applet needs to be redrawn. It has a single argument, a Graphics
object. Whatever is drawn onto this object appears on the screen.
Here, we simply call the Graphics
class's drawImage()
method to copy our entire drawing buffer onto the screen. The drawImage()
method draws the given Image
object with its upper-left corner at the given coordinates, which in this case is (0, 0). Don't worry about the last argument now; just pass null
.
We also need to override the update()
method, or change its behavior. Java calls the update()
method whenever the applet needs repainting. Normally, update()
clears the applet area and then calls paint()
. In PaintApp, though, this will cause flickering as the applet is erased and then repainted repeatedly. As shown in the code above, we leave out the erase part and simply call paint()
. This is a handy technique whenever you use drawing buffers.
You can compile PaintApp now and test it. You should see a rectangle with a black border. In the next step, we'll finally get to draw something!