The Java 2D Application Programming Interface (API) provides a powerful, flexible framework for using device- and resolution-independent graphics in Java programs. The Java 2D API extends the graphics and imaging classes defined by java.awt , while maintaining compatibility for existing programs. The Java 2D API enables developers to easily incorporate high-quality 2D graphics, text, and images in Java applications and applets.
Authored primarily by Sun and Adobe Systems Incorporated, the Java 2D API provides a two-dimensional imaging model for line art, text, and images that uniformly addresses color, spatial transformations, and compositing. With the Java 2D API, you use the same imaging model for both screen and print, which provides a highly WYSIWYG (What You See Is What You Get) experience for the user.
This paper covers the design goals for the Java 2D API, the benefits the API provides, and a technical overview. An expanded version of this paper is available online that contains code samples and a more detailed description of the Java 2D API. For more information, see: here
Along with the other Java Media APIs, the Java 2D API was architected to empower developers to create applications that incorporate advanced user interfaces. The design goals for the Java 2D API include:
The table below summarizes the features provided by the Java 2D API. Innovative features include extensive support for image compositing, alpha channel capability, accurate color-space definition and conversion, and a set of display-oriented imaging operators.
Richer rendering attributes
Arbitrary fill styles
Stroking parameters for lines and curves
|Text||Extended font support
Advanced text layout
|Images||Flexible in-memory image layouts
Extended imaging operations, such as convolution,
lookup tables, and affine transformations
|Devices||Hooks for supporting arbitrary graphics devices
such as printers and screens
|Color Management||ICC profile support
Color conversion from different color spaces
Arbitrary color spaces
Benefits for Developers
The Java 2D API provides many benefits to developers who want to incorporate graphics, text, and images into their applications and applets- in other words, the Java 2D API benefits virtually all Java developers. By enabling the incorporation of sophisticated graphics and text, the Java 2D API makes it possible to create Java programs that provide a richer end-user experience. With the Java 2D API, you have the necessary support to create real-world applications that meet the expectations of today's user for font, graphics, and image capabilities.
The Java 2D API is part of a set of class libraries that are designed to enable you to develop full-featured Java programs. With these libraries, developers have the essential tools to build applications that meet market needs. They make it possible to reach a broad audience running applications on any Java enabled platform.
Java has rapidly established itself as a platform for building portable Internet and intranet applications. The Java 2D API extends Java's strengths by allowing developers to incorporate high-quality graphics into their applications and applets.
The Java platform provides many advantages to developers who need high-quality graphics support:
The Java 2D API will become part of the java.awt and java.awt.image core class libraries. By extending the existing classes, the Java 2D API maintains compatibility for existing programs and allows programs to seamlessly integrate the features provided by java.awt and the Java 2D API.
Java Media comprises a set of class libraries that enhance and expand the media and communications capabilities within the Java environment. The Java 2D API is closely integrated with the Java Media APIs. Both the Java Animation API and Java Media Framework will leverage the 2D graphics features provided by the Java 2D API.
The Java 2D API handles arbitrary shapes, text, and images and provides a uniform mechanism for performing transformations such as rotation and scaling. The Java 2D API also provides comprehensive font and color support.
The Java 2D API uses the drawing model defined by the java.awt package for drawing to the screen: each Component object implements a paint method that is invoked automatically whenever something needs to be drawn. When paint is invoked, it is passed a Graphics object that knows how to draw into the component. The Java 2D API simply provides a subclass of Graphics, Graphics2D , with additional features for specifying fancy paint styles, defining complex shapes, and controlling the rendering process. The Java 2D API treats paths, text, and images uniformly; they can all be rotated, scaled, skewed, and composited using the methods introduced in the following sections.
The Java 2D API defines two coordinate spaces: the User Coordinate Space and the Device Coordinate Space. The origin of the Device Coordinate Space lies in the upper left-hand corner with x-coordinate values increasing to the right and y-coordinate values increasing downward.
Figure 1. Device Coordinate Space and default User Coordinate Space
All graphics objects are described in the device-independent User Coordinate Space until they are rendered on a device such as a screen or printer. The rendering state of a Graphics2D object associated with the target device includes a Transform object that converts the graphics object's User Space coordinates to the Device Space coordinates. The default Transform results in a default User Coordinate Space with the same orientation as the Device Coordinate Space.
The Java 2D API provides an implementation of the Path interface that can be used to define complex shapes. This class, BezierPath, allows you to describe a shape using a combination of lines and Bezier curves. Using BezierPath to define an object's shape allows you to control the location of the object (in User Coordinate Space) as well as its shape. The shape can be transformed to a different position, size, and orientation in Device Coordinate Space using the Graphics2D Transform.
The Java 2D API classes provide text handling support that ranges from the simple use of fonts to professional-quality management of character layout and font features.
Text is treated as a first-class citizen. It can be drawn, transformed, used as a clipping path, and composited just like any other graphic element.
The Java 2D API defines a Font class that provides greater control over fonts than the java.awt. Font class. It also allows you to retrievemore information about a font, such as the Bezier paths of individual character glyphs.
When you display text with the Java 2D API Font class you can specify detailed information, such as the Transform to apply to the font. This allows you to scale the font to any size you choose.
The information that describes a font, such as its name and style parameters, is contained in Font attributes and in FontFeature objects. Every Font object contains an array of FontFeatures describing the particular Font, as well as attributes for font name, size, and transform. The Font class defines several convenience methods that allow you to access this data directly.
The Font class also provides access to font metrics. Every font object contains the detailed metrics for the font. Font allows you to access metric and outline information through getDesignMetrics, getGlyphMetrics, and getGlyphOutline.
Before a piece of text can be displayed, it is necessary to determine exactly where each character should be placed. Most clients leave this layout process up to the system, which supplies a set of algorithms that compute the layout based on information contained in the font (such as the font metrics) and provided by the client (such as the text itself and the requested point size).
The Java 2D API provides text layout facilities that handle most common cases, including text strings with mixed fonts, mixed languages, and bi-directional text.
Advanced clients might want to compute the text layout themselves so that they can exercise detailed control over what glyphs are used and where they are placed. Using information such as glyph sizes, kerning tables, and ligature information, advanced clients can use their own algorithms to compute the text layout, bypassing the system's layout mechanism.
The Java 2D API provides a full range of features for handling images by supplementing the image-handling classes in java.awt and java.awt.image with several new classes, including: BufferedImage, Tile, Channel, ComponentColorModel and ColorSpace.
These classes give advanced Java programmers greater control over images. They allow you to create images in color spaces other than RGB and characterize colors for accurate reproduction. The Java 2D API BufferedImage class allows you to specify exactly how pixels are laid out in an in-memory image.
Like all other graphic elements, images are transformed by the Transform object associated with the Graphics2D object when they are drawn. This means that images can be scaled, rotated, skewed, or otherwise transformed just like text and paths. However, images maintain their own color information, represented by a color model for interpreting color data, rather than using the current color. Images can also be used as the rendering target of a Graphics2D.
The Java 2D API allows you to control how graphics primitives are rendered through a comprehensive set of attributes associated with the Graphics2D state. This allows you to specify characteristics such as the stroke width, join types, and color and texture fills, and also specify how the graphics are blended to the screen and whether or not they are antialiased.
The rendering process can be broken down into four stages. (Note that this process can be compressed to optimize rendering performance.)
The graphics object being rendered is converted to graphics primitives and transformed into the Device Space using the transform from the Graphics2D object associated with the target device. This determines where the graphics object should be rendered.
When a path is rendered it is converted to a BezierPath object. If the path is to be stroked, the stroke attributes are used to convert the path to a stroked path. This BezierPath is transformed into device coordinates using the transform associated with the target device.
When a text string is rendered, the layout of the glyphs is determined using the information in the fonts used by the string. The glyphs are then converted to outlines that are described by BezierPath objects. These BezierPath objects are transformed into device coordinates using the transform associated with the target device.
When an image is rendered, its bounding box (in user coordinates) is transformed into device coordinates using the transform associated with the target device.
Like the classes in java.awt, the Java 2D API classes can fill a shape with simple colors, but they also support more complex fills such as gradients and patterns. To facilitate the use of complex fills, the API defines a new interface called Paint and a Graphics2D method called setPaint. These features eliminate the time-consuming task of creating complex fills using simple solid-color paints.
Figure 2. Complex paint styles
Conceptually, all drawing is done with a Paint object. A Color object can be thought of as a very simple type of Paint object, and the setColor method as a special case of setPaint. In effect, setColor installs a Paint object for you that paints with a single color. You can even pass a Color to the setPaint method, because Color implements the Paint interface and is just another type of Paint object.
Once you call setPaint, everything you draw (such as text and paths) is painted using the specified Paint object.
When a Path object is drawn, it is first converted to an equivalent BezierPath. In the Java 2D API, all Graphics2D objects know how to stroke and fill a BezierPath. Stroking a BezierPath object is equivalent to running a logical pen along the segments of the BezierPath. The Stroke object encapsulates the characteristics of the mark drawn by the pen. The Java 2D API provides a BasicStroke class that contains characteristics such as the line width, end-cap style, segment join style, and the dashing pattern. The end-cap styles are chopped, round, and squared. The join styles are bevel, miter, and round.
Objects are processed by a Transform associated with the Graphics2D object before they are drawn. A Transform object takes a point or a path and transforms it to a new point or path. The default Transform object created when the Graphics2D object is constructed performs simple scaling to device space. To get effects such as rotation, translation, or custom scaling, you create Transform objects and apply them to the Graphics2D object. The most commonly used Transform is the AffineTransform, which performs simple transformations such as translation, rotation, scaling, and skewing. The effects of consecutive transforms are cumulative:
Figure 3. Transformation effects
The Transform interface can easily be implemented to provide other types of transformations, such as a non-linear perspective transformation.
When you combine images by blending or overlaying them, you must define how the colors of the images are blended. To do this with the Java 2D API, you create a Composite object that defines a transfer mode. The transfer mode specifies how the colors are blended.
The AlphaComposite class implements the Composite interface to support the most common composition styles. The most commonly used transfer mode supported by AlphaComposite is SRC_OVER . When AlphaComposite.SRC_OVER is applied, it indicates that the new color (the source color) should be blended over the existing color (the destination color). The alpha value indicates the transparency of the new color, as a percentage, indicating how much of the existing color should show through the new color. The alpha value can be derived from an instance of Color, Paint, or Image, depending on the rendering operation that is being performed. In addition, an AlphaComposite object can increase the transparency of everything that is drawn. To make all objects 50% more transparent, an AlphaComposite object could be created with an alpha value of 0.5. The alpha value of the Composite object is combined with the alpha value of the graphics object being drawn, decreasing the alpha of the graphics object by 50%. The first image in Figure 4-4 shows two overlapping rectangles drawn with an AlphaComposite.SRC_OVER object applied before the blue rectangle is drawn. In the second image, the text is drawn before the Composite object is created so that it is totally opaque. Then a AlphaComposite.SRC_OVER object is created that sets the transparency to 50% and the two overlapping rectangles are drawn.
Note that the red rectangle that used to be completely opaque is now partially transparent and the blue rectangle is even more transparent than before. This additional layer of transparency provided by the AlphaComposite class can be useful in a number of circumstances. New composition styles can be created by implementing the Composite and CompositeContext interfaces. A Composite object, once initiated, provides a CompositeContext object that actually holds the state and does the compositing work. Multiple CompositeContext objects can be created from one Composite object for the purpose of maintaining the separate states in a multi-threaded environment.
Transfer modes are implemented procedurally; methods are implemented to blend colors. Implementing transfer modes procedurally rather than declaratively allows new modes to be added simply by adding new code.
Images can carry transparency information for each pixel in the image. This information, often called an alpha channel, is used in conjunction with the current Composite object to blend the image with an existing drawing. Figure 4-5 contains three images with different transparency information. In each case, the image is displayed over a blue rectangle. This example assumes that an AlphaComposite object is installed that uses SRC_OVER as its transfer mode for compositing.
Figure 5. Transparency and images
In the first image, all pixels are fully opaque (the dog's body) or fully transparent (the background). You often see this effect used on web pages. The second image is rendered with uniform, non-opaque transparency for the dog's body. The third image has opaque values around the dog's face and increasingly transparent values as the distance from the dog's face increases.
The Java 2D API provides a standard, cross-platform interface for handling complex shapes, text, and images. Using the Java 2D API, developers will be able to easily incorporate high-quality 2D graphics, text, and images in their Java applications and applets. The Java 2D API: