As we've just seen, the Java 2D Stroke attribute turns the task of drawing a line into the task of filling an area. Prior to Java 2D, an area could be filled only with a solid color, specified by passing a Color object to the setColor() method of a Graphics object. In Java 2D, this color attribute has been generalized to a paint attribute: you pass a Paint object to the setPaint() method of a Graphics2D object. The specified Paint object is used to generate the pixel values used to fill areas.
The most common way to fill an area, however, is still to use a solid color. So another change in Java 2D is that the java.awt.Color class now implements the java.awt.Paint interface. All Color objects are perfectly legal Paint objects and can be used to draw lines and fill areas with a solid color.
Java 2D also defines two more complex Paint implementations. The java.awt. TexturePaint class uses a tiled image for its filling operations. The image is specified as a java.awt.image.BufferedImage. This is a Java 2D simplification of the java.awt.Image class; we'll discuss it in more detail later in the chapter. When you create a TexturePaint object, you must also specify a java.awt.geom.Rectangle2D object (java.awt.Rectangle is a kind of Rectangle2D). The purpose of this rectangle is to specify an initial position and horizontal and vertical repetition intervals for the tiled image. Typically, you can just specify a rectangle based at 0,0 with the same width and height as the image. If you are not using the default coordinate system, things are a little trickier, since image dimensions are always measured in pixels, but you must specify your rectangle dimensions in user-space coordinates.
The java.awt.GradientPaint class fills an area with a color gradient. The fill color varies linearly between a color C1 and a color C2, along the line between point P1 and point P2. You may also specify whether the gradient is cyclic or acyclic. If the gradient is cyclic, the line between P1 and P2 is extended infinitely in both directions, and the color cycles smoothly along this line from C1 to C2 and back to C1 again. If the gradient is defined to be acyclic, however, the color remains fixed at C1 beyond P1 and at C2 beyond P2.
Here's an example of creating and using a GradientPaint:
Graphics2D g; // Initialized elsewhere Paint p = new GradientPaint(0, 0, Color.red, 100, 100, Color.pink, true); g.setPaint(p); g.fillRect(0, 0, 300, 300);
Both TexturePaint and GradientPaint objects are immutable: they have no set() methods that allow their attributes to be changed. This is important because it means that a Graphics2D object can use a Paint object without worrying about its attributes being changed concurrently (i.e., the Graphics2D object does not have to make a private copy of its Paint attribute).
Copyright © 2001 O'Reilly & Associates. All rights reserved.