Java G2d Draw Outline Doesn t Drawstring Again
Affiliate 2
Rendering with Graphics2D
Graphics2D
extends java.awt.Graphics
to provide more sophisticated control over the presentation of shapes, text, and images. The Java 2nd™ rendering process is controlled through the Graphics2D
object and its country attributes.
The Graphics2D
country attributes, such as line styles and transformations, are applied to graphic objects when they are rendered. The collection of state attributes associated with a Graphics2D
is referred to as the Graphics2D
context. To return text, shapes, or images, you gear up the Graphics2D
context and then telephone call one of the Graphics2D
rendering methods, such equally draw
or fill
.
2.i Interfaces and Classes
The following tables list the interfaces and classes used in conjunction with the Graphics2D
context, including the classes that represent state attributes. Most of these classes are part of the java.awt
package.
Interface | Description |
---|---|
Composite | Defines methods to compose a draw primitive with the underlying graphics area. Implemented past AlphaComposite . |
CompositeContext | Defines the encapsulated and optimized environment for a composite operation. Used by programmers implementing custom compositing rules. |
Paint | Extends: Transparency Defines colors for a draw or fill performance. Implemented by Color , GradientPaint and TexturePaint . |
PaintContext | Defines the encapsulated and optimized environment for a paint performance. Used by programmers implementing custom paint operations. |
Stroke | Generates a Shape that encloses the outline of the Shape to be rendered. Implemented by BasicStroke . |
Form | Clarification |
---|---|
AffineTransform (java.awt.geom) | Represents a 2nd affine transform, which performs a linear mapping from second coordinates to other 2D coordinates. |
AlphaComposite | Implements: Composite Implements basic alpha blended rules for shapes, text, and images. |
BasicStroke | Implements: Stroke Defines the "pen fashion" to be applied to the outline of a Shape . |
Color | Implements: Paint Defines a solid colour fill for a Shape . |
GradientPaint | Implements: Paint Defines a linear color gradient make full design for a Shape . This fill up pattern changes from color C1 at point P1 to color C2 at bespeak P2. |
Graphics2D | Extends: Graphics Cardinal grade for 2D rendering. Extends the original java.awt.Graphics course. |
TexturePaint | Implements: Paint Defines a texture or pattern fill for a Shape . The texture or pattern is generated from a BufferedImage . |
2.2 Rendering Concepts
To render a graphic object using the Coffee 2D™ API, yous set up the Graphics2D
context and pass the graphic object to one of the Graphics2D
rendering methods.
You can modify the state attributes that form the Graphics2D
context to:
- Vary the stroke width.
- Change how strokes are joined together.
- Set up a clipping path to limit the area that is rendered.
- Translate, rotate, scale, or shear objects when they are rendered.
- Define colors and patterns to make full shapes with.
- Specify how multiple graphics objects should be composed.
Graphics2D
defines several methods for adding and changing attributes in the graphics context. Well-nigh of these methods take an object that represents a particular attribute, such as a Paint
or Stroke
object.
The Graphics2D
context holds references to these aspect objects: they are non cloned. If y'all modify an attribute object that is role of the Graphics2D
context, you lot need to telephone call the appropriate set
method to notify the context. Modifying an aspect object during a rendering functioning will cause unpredictable and perchance unstable behavior.
2.2.1 Rendering Process
When a graphic object is rendered, the geometry, image, and attribute information are combined to calculate which pixel values must be changed on the brandish.
The rendering process for a Shape
tin be broken downward into four steps:
- If the
Shape
is to be stroked, theStroke
aspect in theGraphics2D
context is used to generate a newShape
that encompasses the stroked path. - The coordinates of the
Shape
's path are transformed from user infinite into device space according to the transform attribute in theGraphics2D
context. - The
Shape
's path is clipped using the clip attribute in theGraphics2D
context. - The remaining
Shape
, if whatever, is filled using thePaint
andComposite
attributes in theGraphics2D
context.
Rendering text is similar to rendering a Shape
, since the text is rendered as individual glyphs and each glyph is a Shape
. The only difference is that the Java 2D API must decide what Font
to use to the text and get the advisable glyphs from the Font
before rendering.
Images are handled differently, transformations and clipping operations are performed on the prototype's bounding box. The color information is taken from the paradigm itself and its alpha aqueduct is used in conjunction with the current Composite
aspect when the epitome pixels are composited onto the rendering surface.
2.2.2 Decision-making Rendering Quality
The Java 2nd API lets you indicate whether y'all want objects to be rendered as quickly every bit possible, or whether you prefer that the rendering quality exist every bit high as possible. Your preferences are specified equally hints through the RenderingHints
aspect in the Graphics2D
context. Not all platforms support modification of the rendering fashion so specifying rendering hints does not guarantee that they will be used.
The RenderingHints
form supports the following types of hints:
- Alpha interpolation—tin be set to default, quality, or speed.
- Antialiasing—can be ready to default, on, or off.
- Color Rendering–can be set to default, quality, or speed.
- Dithering—tin can be set to default, disable, or enable.
- Fractional Metrics—tin exist set to default, on, or off.
- Interpolation—tin exist ready to nearest-neighbor, bilinear, or bicubic.
- Rendering—tin exist ready to default, quality, or speed.
- Text antialiasing—can exist ready to default, on, or off.
To set or alter the RenderingHints
aspect in the Graphics2D
context, you call setRenderingHints
. When a hint is set to default, the platform rendering default is used is used.
Antialiasing
When graphics primitives are rendered on raster-graphics display devices, their edges can announced jagged because of aliasing. Arcs and diagonal lines take on a jagged appearance because they are approximated by turning on the pixels that are closest to the path of the line or bend. This is peculiarly noticeable on low-resolution devices, where the jagged edges appear in stark contrast to the smooth edges of horizontal or vertical lines.
Antialiasing is a technique used to render objects with smoother-actualization edges. Instead of but turning on the pixel that is closest to the line or curve, the intensity of surrounding pixels is set in proportion to the amount of area covered by the geometry existence rendered. This softens the edges and spreads the on-off transition over multiple pixels. However, antialiasing requires additional calculating resources and can reduce rendering speed
.
ii.2.3 Stroke Attributes
Stroking a Shape
such as a GeneralPath
object is equivalent to running a logical pen along the segments of the GeneralPath
. The Graphics2D
Stroke
aspect defines the characteristics of the mark drawn by the pen.
A BasicStroke
object is used to define the stroke attributes for a Graphics2D
context. BasicStroke
defines characteristics such as the line width, endcap style, segment join-manner, and the dashing pattern. To gear up or alter the Stroke
attribute in the Graphics2D
context, you call setStroke
.
Effigy 2-ane endcap styles supported past BasicStroke
Figure 2-2 Bring together styles supported by BasicStroke
For example, the first image in Figure 2-3 uses the miter join-style; the second image uses a circular join-way, a circular endcap mode, and a dashing pattern.
The Graphics2D
rendering methods that apply the Stroke
aspect are draw
, drawArc
, drawLine
, drawOval
, drawPolygon
, drawPolyline
, drawRect
, and drawRoundRect
.When ane of these methods is called, the outline of the specified Shape
is rendered. The Stroke
aspect defines the line characteristics and the Pigment
attribute defines the colour or pattern of the marker drawn by the pen.
For example, when draw(myRectangle)
is called:
- The
Stroke
is applied to the rectangle'due south outline. - The stroked outline is converted to a
Shape
object. - The
Paint
is applied to the pixels that lie within the contour of the outlineShape
.
This process is illustrated in Effigy 2-4:
Figure 2-4 Stroking a Shape
two.2.4 Fill Attributes
The fill attribute in the Graphics2D
context is represented by a Pigment
object. You add a Pigment
to the Graphics2D
context past calling setPaint
.
When a Shape
or glyph is fatigued (Graphics2D.draw
, Graphics2D.drawString
), the Paint
is applied to all of the pixels that lie inside of the Shape
that represents the object'southward stroked outline. When a Shape
is filled (Graphics2D.fill up
), the Paint
is applied to all of the pixels that lie within the Shape
's
contour.
Uncomplicated solid color fills can be ready with the setColor
method. Color
is the simplest implementation of the Paint
interface.
To fill Shapes
with more than complex paint styles such every bit gradients and textures, you use the Coffee second Paint
classes GradientPaint
and TexturePaint
. These classes eliminate the fourth dimension-consuming task of creating complex fills using unproblematic solid-colour paints. Figure 2-5 illustrates 2 fills that could hands be defined by GradientPaint
and TexturePaint
.
Figure 2-five Complex Make full Styles
When fill
is called to render a Shape
, the system:
- Determines what pixels contain the
Shape
. - Gets the color of each pixel from the
Pigment
object. - Converts the colour to an appropriate pixel value for the output device.
- Writes the pixel to that device.
Batch Processing
To streamline the processing of pixels, the Java 2d API processes them in batches. A batch can be either a contiguous set of pixels on a given scanline or a cake of pixels. This batch processing is done in two steps:
- The
Paint
object'southwardcreateContext
method is called to create aPaintContext
. ThePaintContext
stores the contextual information most the current rendering operation and the information necessary to generate the colors. ThecreateContext
method is passed the bounding boxes of the graphics object being filled in user space and in device space, theColorModel
in which the colors should exist generated, and the transform used to map user space into device space. TheColorModel
is treated as a hint because not allPaint
objects can back up an capriciousColorModel
. (For more than data nighColorModels
, see "Colour" on page 89.") - The
getColorModel
method is called to get theColorModel
of the generated pigment color from thePaintContext
.
The getRaster
method is and then called repeatedly to become the Raster
that contains the actual color data for each batch. This information is passed to the next stage in the rendering pipeline, which draws the generated color using the current Composite
object.
2.2.5 Clipping Paths
A clipping path identifies the portion of a Shape
or Image
that needs to exist rendered. When a clipping path is part of the Graphics2D
context, just those parts of a Shape
or Image
that prevarication within the path are rendered.
To add a clipping path to the Graphics2D
context, you telephone call setClip
. Any Shape
tin be used to define the clipping path.
To change the clipping path, you can either use setClip
to specify a new path or telephone call prune
to alter the clipping path to the intersection of the old clipping path and a new Shape
.
2.2.6 Transformations
The Graphics2D
context contains a transform that is used to transform objects from user space to device space during rendering. To perform boosted transformations, such as rotation or scaling, you lot can add other transforms to the Graphics2D
context. These additional transforms become role of the pipeline of transformations practical during rendering.
Graphics2D
provides several dissimilar means to modify the transform in the Graphics2D
context. The simplest is to call one of the Graphics2D
transformation methods: rotate
, scale
, shear
, or translate
. Y'all specify the characteristics of the transform that you want to exist applied during rendering, and Graphics2D
automatically makes the advisable changes.
Y'all can besides explicitly concatenate an AffineTransform
with the current Graphics2D
transform. An AffineTransform
performs a linear transformation such as translation, scaling, rotation, or shearing on a set of graphics primitives. When a transform is concatenated with an existing transform, the last transform specified is the first to be applied. To concatenate a transform with the current transform, you laissez passer an AffineTransform
to Graphics2D.transform
.
The Graphics2D
class also contains a setTransform
method, but this method should never be used to concatenate another coordinate transform onto of an existing transform. The setTransform
method overwrites the Graphics2D
object'due south current transform, which is needed for other purposes, such as:
- Applying a scaling transform to adjust for printer resolution.
- Painting a
JComponent
at non-nil translation from its parent's origin - Scaling upward a component for easier viewing.
- Whatsoever other situation in which the supplier of a
Graphics2D
object might want to transform the rendering for effect .
The setTransform
method is intended for setting the Graphics2D
object back to the original transform subsequently rendering the transformed graphics, text or images:
AffineTransform aT = g2d.getTransform(); g2d.transform(...);g2d.draw(...); g2d.setTransform(aT);
Graphics2D
also provides a version of drawImage
that takes an AffineTransform
as a parameter. This enables you to use a transformation to an epitome object when it is drawn without permanently modifying the transformation pipeline. The image is fatigued every bit if yous had concatenated the transform with the current transform in the Graphics2D
context.
Affine Transforms
The Java 2D API provides one transform class, AffineTransform
. AffineTransforms
are used to transform text, shapes, and images when they are rendered. You tin can likewise apply transforms to Font
objects to create new font derivations, as discussed in "Creating Font Derivations" on page 65.
An affine transformation performs a linear transformation on a set of graphics primitives. It e'er transforms straight lines into directly lines and parallel lines into parallel lines; nevertheless, the distance betwixt points and the angles between nonparallel lines might exist altered.
Affine transformations are based on two-dimensional matrices of the following class:
where
and
Transforms tin can exist combined, finer creating a series or pipeline of transformations that can be applied to an object. This combination is referred to as concatenation. When a transform is concatenated with an existing transform, such as with AffineTransform.concatenate
, the terminal transform specified is the starting time to exist applied. A transform can too be pre-concatenated with an existing transform. In this case, the last transform specified is the last to be applied.
Pre-concatenation is used to perform transformations relative to device space instead of user space. For example, you lot could use AffineTransform.preConcatenate
to perform a translation relative to absolute pixel space.
2.2.6.one Constructing an AffineTransform
AffineTransform
provides a ready of convenience methods for constructing AffineTransform
objects:
-
getTranslateInstance
-
getRotateInstance
-
getScaleInstance
-
getShearInstance
To utilize these methods, y'all specify the characteristics of the transform you want to create and AffineTransform
generates the advisable transform matrix. Yous can also construct an AffineTransform
by straight specifying the elements of the transformation matrix.
two.ii.seven Composite Attributes
When two graphic objects overlap, it is necessary to determine what colors to render the overlapping pixels. For example, if a blood-red rectangle and a blue rectangle overlap, the pixels that they share could be rendered cherry-red, blue, or some combination of the two. The colour of the pixels in the overlapping area will determine which rectangle appears to be on elevation and how transparent it looks. The procedure of determining what color to return pixels shared by overlapping objects is chosen compositing.
2 interfaces form the basis of the Java 2D compositing model: Composite
and CompositeContext
.
To specify the compositing style that should be used, you lot add an AlphaComposite
object to the Graphics2D
context past calling setComposite
. AlphaComposite
, an implementation of the Composite
interface, supports a number of different compositing styles. Instances of this class embody a compositing dominion that describes how to blend a new color with an existing one.
One of the about unremarkably used compositing rules in the AlphaComposite
class is SRC_OVER, which indicates that the new color (the source color) should be blended over the existing color (the destination color).
AlphaComposite Composition Rule | Clarification |
---|---|
CLEAR | Clear |
DEST_IN | Destination In |
DEST_OUT | Destination Out |
DEST_OVER | Destination Over |
SRC | Source |
SRC_IN | Source In |
SRC_OUT | Source Out |
SRC_OVER | Source Over |
2.two.7.i Managing Transparency
A colour's alpha value is a measure of its transparency: it indicates, equally a percent, how much of a previously rendered color should show through when colors overlap. Opaque colors (alpha=1.0
) don't allow whatever of the underlying color to show through, while transparent colors (blastoff=0.0
) let all of it testify through.
When text and Shapes
are rendered, the blastoff value is derived from the Paint
attribute in the Graphics2D
context. When Shapes
and text are antialiased, the alpha value from the Paint
in the Graphics2D
context is combined with pixel coverage data from the rasterized path. Images maintain their own alpha data—see "Transparency and Images" on page 26 for more information.
When you construct an AlphaComposite
object, you lot tin can specify an additional blastoff value. When you lot add together this AlphaComposite
object to the Graphics2D
context, this extra blastoff value increases the transparency of whatsoever graphic objects that are rendered—the blastoff value of each graphic object is multiplied by the AlphaComposite
's alpha value.
2.ii.7.2 Transparency and Images
Images can comport transparency data for each pixel in the prototype. This information, called an alpha channel, is used in conjunction with the Composite
object in the Graphics2D
context to alloy the epitome with existing drawings.
For example, Figure 2-6 contains iii images with unlike transparency data. In each case, the image is displayed over a blue rectangle. This example assumes that the Graphics2D
context contains an AlphaComposite
object that uses SRC_OVER as the compositing operation.
Figure ii-6 Transparency and Images
In the starting time image, all of the pixels are either fully opaque (the dog's body) or fully transparent (the groundwork). This consequence is often used on Web pages. In the second epitome, all of the pixels in the canis familiaris'due south body are rendered using a uniform, non-opaque alpha value, assuasive the blue background to show through. In the third image, the pixels around the dogs face are fully opaque (alpha=ane.0), but as the distance from its face increases, the alpha values for the pixels decrease.
2.3 Setting Up the Graphics2D Context
To configure the Graphics2D
context for rendering, you use the Graphics2D
set methods to specify attributes such as the RenderingHints
, Stroke
, Pigment
, clipping path, Composite
, and Transform
.
2.3.1 Setting Rendering Hints
A RenderingHints
object encapsulates all of your preferences apropos how an object is rendered. To fix the rendering hints in the Graphics2D
context, yous create a RenderingHints
object and pass it into Graphics2D.setRenderingHints
.
Setting a rendering hint does not guarantee that a detail rendering algorithm will be used: non all platforms back up modification of the rendering mode.
In the following case, antialiasing is enabled and the rendering preference is set to quality:
qualityHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); qualityHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2.setRenderingHints(qualityHints);
2.3.2 Specifying Stroke Attributes
A BasicStroke
defines the characteristics applied to a Shape
's outline, including its width and dashing pattern, how line segments are joined together, and the decoration (if any) applied to the terminate of a line. To set up the stroke attributes in the Graphics2D
context, you create a BasicStroke
object and laissez passer it into setStroke
.
2.3.2.1 Setting the Stroke Width
To set the stroke width, you create a BasicStroke
object with the desired width and call setStroke
.
In the following example, the stroke width is set to twelve points and the defaults are used for the join and endcap decorations:
wideStroke = new BasicStroke(12.0f); g2.setStroke(wideStroke);
2.iii.two.2 Specifying Join and Endcap Styles
To set the join and endcap styles, you create a BasicStroke
object with the desired attributes.
In the following example, the stroke width is set to twelve points and the round bring together and endcap styles are used instead of the defaults:
roundStroke = new BasicStroke(four.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); g2.setStroke(roundStroke);
2.3.2.three Setting the Dashing Blueprint
Complex dashing patterns tin easily be divers with a BasicStroke
object. When you create a BasicStroke
object, y'all tin specify two parameters that control the dashing blueprint:
-
dash
—an array that represents the dashing pattern. Alternating elements in the array represent the dash size and the size of the space between dashes. Element 0 represents the first dash, element 1 represents the first space. -
dash_phase
—an start that defines where the dashing design starts.
In the following example, ii different dashing patterns are practical to a line. In the starting time, the size of the dashes and the infinite between them is abiding. The second dashing pattern is more than circuitous, using a six-chemical element assortment to define the dashing pattern.
float dash1[] = {10.0f}; BasicStroke bs = new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f); g2.setStroke(bs); Line2D line = new Line2D.Float(20.0f, x.0f, 100.0f, 10.0f); g2.draw(line); float[] dash2 = {vi.0f, 4.0f, 2.0f, iv.0f, 2.0f, 4.0f}; bs = new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash2, 0.0f); g2.setStroke(bs); g2.depict(line);
Both dashing patterns utilise a nuance phase of zero, causing the dashes to be drawn starting at the beginning of the dashing pattern. The 2 dashing patterns are shown in Effigy Effigy 2-seven
.
Figure 2-vii Dashing Patterns
2.three.3 Specifying Fill Attributes
The Paint
attribute in the Graphics2D
context determines the fill color or pattern that is used when text and Shapes
are rendered.
2.iii.three.i Filling a Shape with a Slope
The GradientPaint
class provides an like shooting fish in a barrel manner to fill a shape with a slope of one colour to another. When you lot create a GradientPaint
, you specify a commencement position and color, and an catastrophe position and color. The fill color changes proportionally from one color to the other along the line connecting the two positions, equally shown in Effigy 2-8.
Effigy 2-eight Creating Gradient Fills
In the third star in Figure 2-8, both points lie within the shape. All of the points along the slope line extending beyond P1 take the beginning color, and the points along the gradient line extending beyond P2 accept the catastrophe colour.
To fill a shape with a slope of one color to some other:
- Create a
GradientPaint
object. - Phone call
Graphics2D.setPaint.
- Create the
Shape
. - Call
Graphics2D.fill(shape)
.
In the post-obit example, a rectangle is filled with a blue-green slope.
GradientPaint gp = new GradientPaint(fifty.0f, l.0f, Color.blueish fifty.0f, 250.0f, Color.green); g2.setPaint(gp); g2.fillRect(50, 50, 200, 200);
two.3.3.2 Filling a Shape with a Texture
The TexturePaint
grade provides an easy way to fill a shape with a repeating blueprint. When you create a TexturePaint
, you specify a BufferedImage
to use as the pattern. You likewise laissez passer the constructor a rectangle to define the repetition frequency of the pattern, as shown in Figure two-9.
Figure ii-ix Creating Texture Paints
To fill a shape with a texture:
- Create a
TexturePaint
object. - Call
Graphics2D.setPaint.
- Create the
Shape
. - Call
Graphics2D.fill(shape)
.
In the post-obit instance, a rectangle is filled with a simple texture created from a buffered paradigm.
// Create a buffered paradigm texture patch of size 5x5 BufferedImage bi = new BufferedImage(five, 5, BufferedImage.TYPE_INT_RGB); Graphics2D big = bi.createGraphics(); // Render into the BufferedImage graphics to create the texture large.setColor(Color.dark-green); big.fillRect(0,0,five,v); large.setColor(Color.lightGray); big.fillOval(0,0,5,5); // Create a texture paint from the buffered paradigm Rectangle r = new Rectangle(0,0,5,5); TexturePaint tp = new TexturePaint(bi,r,TexturePaint.NEAREST_NEIGHBOR); // Add the texture paint to the graphics context. g2.setPaint(tp); // Create and return a rectangle filled with the texture. g2.fillRect(0,0,200,200); }
2.3.four Setting the Clipping Path
To define a clipping path:
- Create a
Shape
that represents the expanse y'all desire to render. - Phone call
Graphics2D.setClip
to use the shape equally the clipping path for theGraphics2D
context.
To shrink the clipping path:
- Create a
Shape
that intersects the current clipping path. - Call
clip
to change the clipping path to the intersection of the current clipping path and the newShape
.
In the following example, a clipping path is created from an ellipse and then modified past calling clip
.
public void pigment(Graphics 1000) { Graphics2D g2 = (Graphics2D) g; // The width and height of the canvas int w = getSize().width; int h = getSize().height; // Create an ellipse and apply information technology every bit the clipping path Ellipse2D eastward = new Ellipse2D.Float(westward/four.0f,h/4.0f, w/2.0f,h/2.0f); g2.setClip(e); // Fill the sail. Only the area within the clip is rendered g2.setColor(Color.cyan); g2.fillRect(0,0,westward,h); // Change the clipping path, setting it to the intersection of // the current clip and a new rectangle. Rectangle r = new Rectangle(west/four+x,h/four+10,westward/2-xx,h/2-twenty); g2.clip(r); // Fill the canvas. Only the area inside the new clip // is rendered g2.setColor(Colour.magenta); g2.fillRect(0,0,due west,h); }
2.iii.5 Setting the Graphics2D Transform
To transform a Shape,
text cord, or Prototype
you add together a new AffineTransform
to the transformation pipeline in the Graphics2D
context before rendering. The transformation is applied when the graphic object is rendered.
For example, to draw a rectangle that is rotated 45 degrees:
- Get the current
Graphics2D
transform before performing any transformations. Ever phone callgetTransform
on theGraphics2D
earlier calculation a transform to the graphics context because the graphics context might already have a transform that is needed for other reasons, such as positioning Swing and lightweight components inside a window. - Become a rotation transform by calling
AffineTransform. getRotateInstance
. - Phone call
Graphics2D.transform
to add the new transform to the transformation pipeline. Never use thesetTransform
method to add a new coordinate transform consideringsetTransform
will overwrite the electric current transform in the graphics context. - Create a
Rectangle2D.Float
object. - Call
Graphics2D.describe
to return the rectangle. - Subsequently you have rendered your transformed rectangle, reset the transform of the
Graphics2D
back to the original transform that you saved in Step i by callingsetTransform
with the original transform.
In the post-obit instance, an instance of AffineTransform
is used to rotate a rectangle 45 degrees when information technology is rendered.
AffineTransform aT = g2.getTransform();Rectangle2D rect = new Rectangle2D.Float(1.0,one.0,2.0,iii.0); AffineTransform rotate45 = AffineTransform.getRotateInstance(Math.PI/iv.0,0.0,0.0) g2.transform(rotate45); g2.draw(rect);g2.setTransform(aT);
In this example, an AffineTransform
is used to rotate a text string effectually a heart signal:
// Define the rendering transform AffineTransform at = new AffineTransform(); // Use a translation transform to make room for the // rotated text. at.setToTranslation(400.0, 400.0); g2.transform(at); // Create a rotation transform to rotate the text at.setToRotation(Math.PI / 2.0); // Render four copies of the string "Coffee" at 90 caste angles for (int i = 0; i < iv; i++) { g2.drawString("Java", 0.0f, 0.0f); g2.transform(at); }
You tin transform an paradigm in the aforementioned way—the transform in the Graphics2D
context is practical during rendering regardless of the type of graphic object beingness rendered.
To apply a transform to an paradigm without changing the transform in the Graphics2D
context, you can pass an AffineTransform
to drawImage
:
AffineTransform rotate45 = AffineTransform.getRotateInstance(Math.PI/4.0,0.0,0.0) g2.drawImage(myImage, rotate45);
Transforms can also be applied to a Font
to create a modified version of the Font
, for more than information meet "Creating Font Derivations" on page 65.
2.three.six Specifying a Limerick Way
An AlphaComposite
encapsulates composition rules that make up one's mind how colors should be rendered when one object overlaps another. To specify the composition fashion for the Graphics2D
context, you lot create an AlphaComposite
and laissez passer it into setComposite
. The most normally used is limerick style is SRC_OVER
.
2.three.6.1 Using the Source Over Compositing Dominion
The SRC_OVER
compositing rule composites the source pixel over the destination pixel such that the shared pixel takes the colour of the source pixel. For instance, if you return a blue rectangle and then render a red rectangle that partially overlaps it, the overlapping area will be carmine. In other words, the object that is rendered terminal will appear to be on top.
To employ the SRC_OVER
composition rule:
- Create an
AlphaComposite
object by callinggetInstance
and specifying theSRC_OVER
rule. -
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
- Telephone call
setComposite
to add theAlphaComposite
object to theGraphics2D
context.g2.setComposite(air-conditioning);
One time the composite object is set, overlapping objects will be rendered using the specified composition rule.
2.3.6.2 Increasing the Transparency of Composited Objects
AlphaComposite
allows y'all to specify an additional constant alpha value that is multiplied with the alpha of the source pixels to increase transparency.
For example, to create an AlphaComposite
object that renders the source object 50% transparent, specify an alpha of .5:
AlphaComposite air conditioning = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f);
In the following example, a source over alpha composite object is created with an alpha of .five and added to the graphics context, causing subsequent shapes to be rendered 50% transparent.
public void pigment(Graphics chiliad) { Graphics2D g2 = (Graphics2D) g; g2.setColor(Color.red); g2.translate(100,fifty); // radians=degree * pie / 180 g2.rotate((45*java.lang.Math.PI)/180); g2.fillRect(0,0,100,100); g2.setTransform(new AffineTransform()); // prepare to identity // Create a new alpha composite AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.5f); g2.setComposite(air conditioning); g2.setColor(Color.green); g2.fillRect(50,0,100,100); g2.setColor(Color.blue); g2.fillRect(125,75,100,100); g2.setColor(Color.yellow); g2.fillRect(50,125,100,100); g2.setColor(Color.pink); g2.fillRect(-25,75,100,100); }
2.iv Rendering Graphics Primitives
Graphics2D
provides rendering methods for Shapes
, Text
, and Images
:
-
draw
—strokes aShape
's path using theStroke
andPaint
objects in theGraphics2D
context. -
fill
—fills aShape
using thePaint
in theGraphics2D
context. -
drawString
—renders the specified text string using thePaint
in theGraphics2D
context. -
drawImage
—renders the specified image.
To stroke and fill a shape, y'all must call both the depict
and fill up
methods.
Graphics2D
also supports the describe and fill methods from previous versions of the JDK software, such as drawOval
and fillRect
.
two.4.i Drawing a Shape
The outline of any Shape
can be rendered with the Graphics2D.describe
method. The draw methods from previous versions of the JDK software are also supported: drawLine
, drawRect
, drawRoundRect
, drawOval
, drawArc
, drawPolyline
, drawPolygon
, draw3DRect
.
When a Shape
is fatigued, its path is stroked with the Stroke
object in the Graphics2D
context. (See "Stroke Attributes" on folio nineteen for more than data.) By setting an appropriate BasicStroke
object in the Graphics2D
context, y'all can describe lines of any width or design. The BasicStroke
object also defines the line'due south endcap and join attributes.
To render shape'due south outline:
- Create a
BasicStroke
object - Call
Graphics2D.setStroke
- Create the
Shape
. - Telephone call
Graphics2D.describe(shape)
.
In the following example, a GeneralPath
object is used to define a star and a BasicStroke
object is added to the Graphics2D
context to ascertain the star's line with and join attributes.
public void pigment(Graphics one thousand) { Graphics2D g2 = (Graphics2D) thousand; // create and set the stroke g2.setStroke(new BasicStroke(four.0f)); // Create a star using a general path object GeneralPath p = new GeneralPath(GeneralPath.NON_ZERO); p.moveTo(- 100.0f, - 25.0f); p.lineTo(+ 100.0f, - 25.0f); p.lineTo(- 50.0f, + 100.0f); p.lineTo(+ 0.0f, - 100.0f); p.lineTo(+ 50.0f, + 100.0f); p.closePath(); // translate origin towards eye of sheet g2.translate(100.0f, 100.0f); // render the star'southward path g2.draw(p); }
2.4.2 Filling a Shape
The Graphics2D.fill
method can exist used to fill whatsoever Shape
. When a Shape
is filled, the expanse within its path is rendered with the Graphics2D
context's current Paint
attribute—a Color
, TexturePaint
, or GradientPaint
.
The fill up methods from previous versions of the JDK software are too supported: fillRect
, fill3DRect
, fillRoundRect
, fillOval
, fillArc
, fillPolygon
, clearRect
.
To fill a Shape
:
- Fix the fill colour or pattern on the graphics context using
Graphics2D.setColor
orGraphics2D.setPaint.
- Create the
Shape
. - Telephone call
Graphics2D.fill
to render theShape
.
In the post-obit case, setColor
is called to define a green fill for a Rectangle2D
.
public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) one thousand; g2.setPaint(Color.green); Rectangle2D r2 = new Rectangle2D.Bladder(25,25,150,150); g2.fill(r2); }
2.4.3 Rendering Text
To return a text string, you telephone call Graphics2D.drawString
, passing in the cord that you want to render. For more information nigh rendering text and selecting fonts, meet "Fonts and Text Layout" on folio 45.
2.four.4 Rendering Images
To return an Image
, you create the Image
and telephone call Graphics2D.drawImage
. For more than information almost processing and rendering images, see "Imaging" on page 67.
two.5 Defining Custom Composition Rules
You can create an entirely new type of compositing operation by implementing the Composite
and CompositeContext
interfaces. A Composite
object provides a CompositeContext
object that really holds the state and performs the compositing work. Multiple CompositeContext
objects tin be created from i Composite
object to maintain the separate states in a multithreaded surroundings.
ii.6 Rendering in a Multi-Screen Environs
With the release of the JavaTM 2 SDK, version 1.3 and later versions, the Java 2DTM API supports 3 different multi-screen configurations that tin possibly exist configured by a native platform:
- Two or more contained screens
- 2 or more screens where 1 screen is the main screen and the other screens display copies of what appears on the primary screen.
- Two or more screens that form a virtual desktop, which is also chosen a virtual device.
The Java 2D API enables you lot to create Frame
, JFrame
, Window
, or JWindow
objects with a GraphicsConfiguration
to target a screen device for rendering.
In all three configurations, each screen device is represented by a GraphicsDevice.
A GraphicsDevice
can have multiple GraphicsConfiguration
objects associated with it.
When two or more than screens are used to form a virtual device, a virtual coordinate system that exists outside of the concrete screens is used to represent the virtual device. The bounds of each GraphicsConfiguration
in this multi-screen configuration are relative to the virtual coordinate arrangement. One screen in this environment is identified equally the main screen, which is located at (0, 0) in the virtual coordinate organization. Depending on the location of the primary screen, the virtual device might accept negative coordinates, as shown in Figure two-10:
Figure ii-ten Example of a virtual device environs
To decide if your surroundings is a virtual device surround in which a Window
or a Frame
tin span two or more physical screens, call getBounds
on each GraphicsConfiguration
in your organisation and check to run into if the origin is something other than (0, 0). The getBounds
method of a GraphicsConfiguration
returns a Rectangle
in the virtual coordinate system. And then, if whatever of the origins are non (0, 0), your surround is a virtual device environment.
In a virtual device environment, the coordinates of the GraphicsConfiguration
objects are relative to the virtual coordinate organisation. So, you must use virtual coordinates when calling the setLocation
method of a Frame
or Window
. For example, this code sample gets the bounds of a GraphicsConfiguration
and uses the bounds to set the location of a Frame
at (x, 10) relative to the origin of the physical screen of the corresponding GraphicsConfiguration
.
Frame f = new Frame(GraphicsConfiguration gc); Rectangle bounds = gc.getBounds(); f.setLocation(10 + bounds.10, ten + bounds.y);
If the bounds of the GraphicsConfiguration
are not taken into business relationship, the Frame
is displayed at (10, x) on the primary physical screen, which might be unlike from the physical screen of the specified GraphicsConfiguration
.
The getBounds
method tin also exist used to determine the bounds of the virtual device. Telephone call getBounds
on each GraphicsConfiguration
in your system. To determine the premises of the virtual device, calculate the union of all the bounds. This technique is used in the following sample.
Rectangle virtualBounds = new Rectangle(); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] gs = ge.getScreenDevices(); for (int j = 0; j < gs.length; j++) { GraphicsDevice gd = gs[j]; GraphicsConfiguration[] gc = gd.getConfigurations(); for (int i = 0; i < gc.length; i++) { virtualBounds = virtualBounds.union(gc[i].getBounds()); } }
The post-obit applet creates a JFrame
with every GraphicsConfiguration
of every GraphicsDevice
in the GraphicsEnvironment
. Each JFrame
displays a set of red, green and blueish stripes, the screen number, the GraphicsConfiguration
number and the bounds of the GraphicsConfiguration.
import java.applet.Applet; import java.awt.*; import javax.swing.*; public form MultiFrameApplet extends Applet { public MultiFrameApplet() { main(goose egg); } public static void main(String[] argv) { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] gs = ge.getScreenDevices(); for (int j = 0; j < gs.length; j++) { GraphicsDevice gd = gs[j]; GraphicsConfiguration[] gc = gd.getConfigurations(); for (int i=0; i < gc.length; i++) { JFrame f = new JFrame(gs[j].getDefaultConfiguration()); GCCanvas c = new GCCanvas(gc[i]); Rectangle gcBounds = gc[i].getBounds(); int xoffs = gcBounds.x; int yoffs = gcBounds.y; f.getContentPane().add(c); f.setTitle("Screen# "+Integer.toString(j)+", GC# "+Integer.toString(i)); f.setSize(300, 150); f.setLocation((i*50)+xoffs, (i*60)+yoffs); f.evidence(); } } } } class GCCanvas extends Canvas { GraphicsConfiguration gc; Rectangle bounds; public GCCanvas(GraphicsConfiguration gc) { super(gc); this.gc = gc; bounds = gc.getBounds(); } public Dimension getPreferredSize() { return new Dimension(300, 150); } public void paint(Graphics one thousand) { grand.setColor(Color.red); g.fillRect(0, 0, 100, 150); g.setColor(Colour.green); 1000.fillRect(100, 0, 100, 150); g.setColor(Color.blue); g.fillRect(200, 0, 100, 150); g.setColor(Color.blackness); g.drawString("ScreenSize="+ Integer.toString(bounds.width)+ "Ten"+ Integer.toString(bounds.tiptop), 10, 15); g.drawString(gc.toString(), 10, 30); } }
Source: https://munier.perso.univ-pau.fr/temp/jdk-7u45-apidocs/technotes/guides/2d/spec/j2d-awt.html
0 Response to "Java G2d Draw Outline Doesn t Drawstring Again"
Post a Comment