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
Shapeis to be stroked, theStrokeaspect in theGraphics2Dcontext is used to generate a newShapethat 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 theGraphics2Dcontext. - The
Shape's path is clipped using the clip attribute in theGraphics2Dcontext. - The remaining
Shape, if whatever, is filled using thePaintandCompositeattributes in theGraphics2Dcontext.
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
Strokeis applied to the rectangle'due south outline. - The stroked outline is converted to a
Shapeobject. - The
Paintis 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
Pigmentobject. - 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
Paintobject'southwardcreateContextmethod is called to create aPaintContext. ThePaintContextstores the contextual information most the current rendering operation and the information necessary to generate the colors. ThecreateContextmethod is passed the bounding boxes of the graphics object being filled in user space and in device space, theColorModelin which the colors should exist generated, and the transform used to map user space into device space. TheColorModelis treated as a hint because not allPaintobjects can back up an capriciousColorModel. (For more than data nighColorModels, see "Colour" on page 89.") - The
getColorModelmethod is called to get theColorModelof 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
JComponentat non-nil translation from its parent's origin - Scaling upward a component for easier viewing.
- Whatsoever other situation in which the supplier of a
Graphics2Dobject 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
GradientPaintobject. - 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
TexturePaintobject. - 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
Shapethat represents the expanse y'all desire to render. - Phone call
Graphics2D.setClipto use the shape equally the clipping path for theGraphics2Dcontext.
To shrink the clipping path:
- Create a
Shapethat intersects the current clipping path. - Call
clipto 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
Graphics2Dtransform before performing any transformations. Ever phone callgetTransformon theGraphics2Dearlier 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.transformto add the new transform to the transformation pipeline. Never use thesetTransformmethod to add a new coordinate transform consideringsetTransformwill overwrite the electric current transform in the graphics context. - Create a
Rectangle2D.Floatobject. - Call
Graphics2D.describeto return the rectangle. - Subsequently you have rendered your transformed rectangle, reset the transform of the
Graphics2Dback to the original transform that you saved in Step i by callingsetTransformwith 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
AlphaCompositeobject by callinggetInstanceand specifying theSRC_OVERrule. -
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
- Telephone call
setCompositeto add theAlphaCompositeobject to theGraphics2Dcontext.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 theStrokeandPaintobjects in theGraphics2Dcontext. -
fill—fills aShapeusing thePaintin theGraphics2Dcontext. -
drawString—renders the specified text string using thePaintin theGraphics2Dcontext. -
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
BasicStrokeobject - 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.setColororGraphics2D.setPaint. - Create the
Shape. - Telephone call
Graphics2D.fillto 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