Contents | Previous | Next |
The Java 2D™ API enhances the graphics, text, and imaging capabilities of the Abstract Windowing Toolkit (AWT), enabling the development of richer user interfaces and new types of Java™ applications.
Along with these richer graphics, font, and image APIs, the Java 2D API supports enhanced color definition and composition, hit detection on arbitrary geometric shapes and text, and a uniform rendering model for printers and display devices.
The Java 2D API also enables the creation of advanced graphics libraries, such as CAD-CAM libraries and graphics or imaging special effects libraries, as well as the creation of image and graphic file read/write filters.
When used in conjunction with the Java Media Framework and other Java Media APIs, the Java 2D APIs can be used to create and display animations and other multimedia presentations. The Java Animation and Java Media Framework APIs rely on the Java 2D API for rendering support.
Early versions of the AWT provided a simple rendering package suitable for rendering common HTML pages, but not full-featured enough for complex graphics, text, or imaging. As a simplified rendering package, the early AWT embodied specific cases of more general rendering concepts. The Java 2D™ API provides a more flexible, full-featured rendering package by expanding the AWT to support more general graphics and rendering operations.
For example, through the Graphics
class you can draw rectangles, ovals, and
polygons. Graphics2D
enhances the
concept of geometric rendering by providing a mechanism for
rendering virtually any geometric shape. Similarly, with the Java
2D API you can draw styled lines of any width and fill geometric
shapes with virtually any texture.
Geometric shapes are provided through
implementations of the Shape
interface,
for example Rectangle2D
and Ellipse2D
. Curves and arcs are also specific
implementations of Shape
.
Fill and pen styles are provided through
implementations of the Paint
and
Stroke
interfaces, for example
BasicStroke
, GradientPaint
, TexturePaint
, and Color
.
AffineTransform
defines
linear transformations of 2D coordinates, including scale,
translate, rotate, and shear.
Clip regions are defined by the same
implementations of the Shape
interface
that are used to define general clipping regions, for example
Rectangle2D
and GeneralPath
.
Color composition is provided by implementations
of the Composite
interface, for example
AlphaComposite
.
A Font
is defined by
collections of Glyphs
, which are in turn
defined by individual Shapes
.
The basic graphics rendering model has not changed
with the addition of the Java 2D™ APIs. To render a graphic,
you set up the graphics context and invoke a rendering method on
the Graphics
object.
The Java 2D API class Graphics2D
extends Graphics
to support more graphics attributes and
provide new rendering methods. Setting up a Graphics2D
context is described in “Rendering with Graphics2D” on
page 15.
The Java 2D API automatically compensates for differences in rendering devices and provides a uniform rendering model across different types of devices. At the application level, the rendering process is the same whether the target rendering device is a display or a printer.
With the JavaTM 2 SDK, version 1.3 relsease and later, the Java 2D API provides support for multi-screen environments. See Section 1.2.1, “Coordinate Systems” and “Rendering in a Multi-Screen Environment” on page 39 for more information.
The Java 2D API maintains two coordinate systems:
The Java 2D system automatically performs the necessary conversions between user space and the device space of the target rendering device. Although the coordinate system for a monitor is very different from the coordinate system for a printer, these differences are invisible to applications.
As shown in Figure 1-1, the user space origin is located in the upper-left corner of the space, with x values increasing to the right and y values increasing downward.
User space represents a uniform abstraction of all possible device coordinate systems. The device space for a particular device might have the same origin and direction as user space, or it might be different. Regardless, user space coordinates are automatically transformed into the appropriate device space when a graphic object is rendered. Often, the underlying platform device drivers are used to perform this conversion.
The Java 2D API defines three levels of configuration information that are maintained to support the conversion from user space to device space. This information is encapsulated by three classes:
GraphicsEnvironment
GraphicsDevice
GraphicsConfiguration
Between them, the GraphicsEnvironment
, GraphicsDevice
, and GraphicsConfiguration
represent all of the
information necessary for locating a rendering device or font on
the Java platform and for converting coordinates from user space to
device space. An application can access this information, but does
not need to perform any transformations between user space and
device space.
The GraphicsEnvironment
describes the collection of rendering devices visible to a Java
application on a particular platform. Rendering devices include
screens, printers, and image buffers. The GraphicsEnvironment
also includes a list of all of
the available fonts on the platform.
A GraphicsDevice
describes an application-visible rendering device, such as a screen
or printer. Each possible configuration of the device is
represented by a GraphicsConfiguration
.
For example, an SVGA display device can operate in several modes:
640x480x16 colors, 640x480x256 colors, and 800x600x256 colors. The
SVGA screen is represented by a GraphicsDevice
object and each of the modes is
represented by a GraphicsConfiguration
object.
A GraphicsEnvironment
can contain one or more GraphicsDevices
;
in turn, each GraphicsDevice
can have
one or more GraphicsConfigurations
.
The Java 2D API has a unified coordinate
transformation model. All coordinate transformations, including
transformations from user to device space, are represented by
AffineTransform
objects. AffineTransform
defines the rules for manipulating
coordinates using matrices.
You can add an AffineTransform
to the graphics context to rotate,
scale, translate, or shear a geometric shape, text, or image when
it is rendered. The added transform is applied to any graphic
object rendered in that context. The transform is performed when
user space coordinates are converted to device space
coordinates.
A string is commonly thought of in terms of the characters that comprise the string. When a string is drawn, its appearance is determined by the font that is selected. However, the shapes that the font uses to display the string don’t always correspond to individual characters. For example, in professional publishing, certain combinations of two or more characters are often replaced by a single shape called a ligature.
The shapes that a font uses to represent the
characters in the string are called glyphs. A font might represent a character such as
a lowercase a acute using multiple
glyphs, or represent certain character combinations such as the
fi in final with a single glyph. In the
Java 2D API, a glyph is simply a Shape
that can be manipulated and rendered in the same way as any other
Shape
.
A font can be thought
of as a collection of glyphs. A single font might have many
versions, such as heavy, medium, oblique, gothic, and regular.
These different versions are called faces. All of the faces in a font have a similar
typographic design and can be recognized as members of the same
family. In other words, a collection of
glyphs with a particular style forms a font face, a collection of
font faces forms a font family, and a collection of font families
forms the set of fonts available within a particular GraphicsEnvironment
.
In the Java 2D API, fonts are specified by a name that describes a particular font face—for example, Helvetica Bold. This is different from the JDK 1.1 software, in which fonts are described by logical names that map onto different font faces depending on which font faces are available on a particular platform. For backward compatibility, the Java 2D API supports the specification of fonts by logical name as well as by font face name.
Using the Java 2D API, you can compose and render
strings that contain multiple fonts of different families, faces,
sizes, and even languages. The appearance of the text is kept
logically separate from the layout of the text. Font
objects are used to describe the appearance,
and the layout information is stored in TextLayout
and TextAttributeSet
objects. Keeping the font and
layout information separate makes it easier to use the same fonts
in different layout configurations.
Images are collections of pixels organized spatially. A pixel defines the appearance of an image at a single display location. A two-dimensional array of pixels is called a raster.
The pixel’s appearance can be defined directly or as an index into a color table for the image.
In images that contain many colors (more than 256), the pixels usually directly represent the color, alpha, and other display characteristics for each screen location. Such images tend to be much larger than indexed-color images, but they look more realistic.
In an indexed-color image, the colors in the image are limited to the colors specified in the color table, often resulting in fewer colors that can be used in the image. However, an index typically requires less storage space than a color value, so images stored as a set of indexed colors are usually smaller. This pixel format is popular for images that contain only 16 or 256 colors.
Images in the Java 2D API have two primary components:
The rules for interpreting the pixel are
encapsulated by a ColorModel
object—for example, whether the values should be interpreted
as direct or indexed colors. For a pixel to be displayed, it must
be paired with a color model.
A band is one component of the color space for an image. For example, the Red, Green, and Blue components are the bands in an RGB image. A pixel in a direct color model image can be thought of as a collection of band values for a single screen location.
The java.awt.image
package contains several ColorModel
implementations, including those for packed and component pixel
representations.
A ColorSpace
object
encapsulates the rules that govern how a set of numeric
measurements corresponds to a particular color. The ColorSpace
implementations in the java.awt.color
represent the most popular color
spaces, including RGB and gray scale. Note that a color space is
not a collection of colors—it defines the rules for how to
interpret individual color values.
Separating the color space from the color model provides greater flexibility in how colors are represented and converted from one color representation to another.
With the Java 2D API, you can render Shapes
using different pen styles and fill patterns.
Because text is ultimately represented by a set of glyphs, text
strings can also be stroked and filled.
Pen styles are defined by objects that implement
the Stroke
interface. Strokes enable you
to specify different widths and dashing patterns for lines and
curves.
Fill patterns are defined by objects that
implement the Paint
interface. The
Color
class, which was available in
earlier versions of the AWT, is a simple type of Paint
object used to define solid-color fills. The
Java 2D API provides two additional Paint
implementations, TexturePaint
and GradientPaint
. TexturePaint
defines a fill pattern using a simple
image fragment that is repeated uniformly. GradientPaint
defines a fill pattern as a gradient
between two colors.
In Java 2D, rendering a shape’s outline and filling the shape with a pattern are two separate operations:
draw
methods
renders the shape’s contour or outline using the pen style
specified by the Stroke
attribute and
the fill pattern specified by the Paint
attribute.fill
method fills the
interior of the shape with the pattern specified by the
Paint
attribute.When a text string is rendered, the current
Paint
attribute is applied to the glyphs
that form the string. Note, however, that drawString
actually fills the glyphs that are
rendered. To stroke the outlines of the glyphs in a text string,
you need to get the outlines and render them as shapes using the
draw
method.
When you render an object that overlaps an
existing object, you need to determine how to combine the colors of
the new object with the colors that already occupy the area where
you are going to draw. The Java 2D API encapsulates rules for how
to combine colors in a Composite
object.
Primitive rendering systems provide only basic Boolean operators for combining colors. For example, a Boolean compositing rule might allow the source and destination color values to be ANDed, ORed, or XORed. There are several problems with this approach
The Java 2D API avoids these pitfalls by
implementing alpha-blending1 rules that take color model
information into account when compositing colors. An AlphaComposite
object includes the color model of
both the source and destination colors.
The Java 2D™ API maintains backward compatibility with JDK 1.1 software. It is also architected so that applications can maintain platform-independence.
To ensure backward compatibility, the functionality of existing JDK graphics and imaging classes and interfaces was maintained. Existing features were not removed and no package designations were changed for existing classes. The Java 2D API enhances the functionality of the AWT by implementing new methods in existing classes, extending existing classes, and adding new classes and interfaces that don’t affect the legacy APIs.
For example, much of the Java 2D API functionality
is delivered through an expanded graphics context, Graphics2D
. To provide this extended graphics
context while maintaining backward compatibility, Graphics2D
extends the Graphics
class from the JDK 1.1 release.
The usage model of the graphics context remains
unchanged. The AWT passes a graphics context to an AWT Component
through the following methods:
paint
paintAll
update
print
printAll
getGraphics
A JDK 1.1 applet interprets the graphics context
that’s passed in as an instance of Graphics
. To gain access to the new features
implemented in Graphics2D,
a Java 2D
API–compatible applet casts the graphics context to a
Graphics2D
object:
In some cases, rather than extending a legacy class, the Java 2D API generalizes it. Two techniques were used to generalize legacy classes:
For example, the Java 2D API generalizes the AWT
Rectangle
class using both of these
techniques. The hierarchy for rectangle now looks like:
java.lang.object | +-------java.awt.geom.RectangularShape | +---------java.awt.geom.Rectangle2D | +-------java.awt.Rectangle
In the JDK 1.1 software, Rectangle
simply extended Object
. It now extends the new Rectangle2D
class and implements both Shape
and Serializable
.
Two parent classes were added to the Rectangle
hierarchy: RectangularShape
and Rectangle2D
. Applets written for JDK 1.1 software
are unaware of the new parent classes and interface
implementations, but are unaffected because Rectangle
still contains the methods and members
that were present in earlier versions.
The Java 2D API adds several new classes and interfaces that are “orthogonal” to the legacy API. These additions do not extend or generalize existing classes—they are entirely new and distinct. These new classes and interfaces embody concepts that had no explicit representation in the legacy API.
For example, the Java 2D API implements several
new Shape
classes, including
Arc2D
, CubicCurve2D
, and QuadCurve2D
. Although early versions of the AWT
could render arcs using the drawArc
and
fillArc
methods, there was no general
curve abstraction and no discrete classes that embodied arcs. These
discrete classes could be added to the Java 2D API without
disrupting legacy applets because drawArc
and fillArc
are
still supported through the Graphics
class.
To enable the development of platform-independent applications, the Java 2D API makes no assumptions about the resolution, color space, or color model of the target rendering device. Nor does the Java 2D API assume any particular image file format.
Truly platform-independent fonts are possible only
when the fonts are built-in (provided as part of the JDK software),
or when they are mathematically or programmatically generated. The
Java 2D API does not currently support built-in or mathematically
generated fonts, but it does enable the programmatic definition of
entire fonts through their glyph set. Each glyph can in turn be
defined by a Shape
that consists of line
segments and curves. Many fonts of particular styles and sizes can
be derived from a single glyph set.
The Java 2D API classes are organized into the following packages:
java.awt
java.awt.geom
java.awt.font
java.awt.color
java.awt.image
java.awt.image.renderable
java.awt.print
Package java.awt
contains those Java 2D API classes and
interfaces that are general in nature or that enhance legacy
classes. (Obviously, not all of the classes in java.awt
are Java 2D classes.)
Package java.awt.geom
contains classes and interfaces
related to the definition of geometric primitives.
Many of the geometric primitives have
corresponding .Float
and .Double
implementations. This was done to enable
both floating single- and double-precision implementations.
Double-precision implementations provide greater rendering
precision at the expense of performance on some platforms.
Package java.awt.font
contains classes and interfaces
used for text layout and the definition of fonts.
Packagejava.awt.color
contains classes and interfaces
for the definition of color spaces and color profiles.
The java.awt.image
and >java.awt.image.renderable
packages
contain classes and interfaces for the definition and rendering of
images.
Package java.awt.print
contains classes and interfaces
that enable printing of all Java 2D–based text, graphics, and
images.
Contents | Previous | Next |