|
jfreechart example source code file (SWTGraphics2D.java)
The jfreechart SWTGraphics2D.java source code/* =========================================================== * JFreeChart : a free chart library for the Java(tm) platform * =========================================================== * * (C) Copyright 2000-2009, by Object Refinery Limited and Contributors. * * Project Info: http://www.jfree.org/jfreechart/index.html * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. * * [Java is a trademark or registered trademark of Sun Microsystems, Inc. * in the United States and other countries.] * * ------------------ * SWTGraphics2D.java * ------------------ * (C) Copyright 2006-2008, by Henry Proudhon and Contributors. * * Original Author: Henry Proudhon (henry.proudhon AT ensmp.fr); * Contributor(s): Cedric Chabanois (cchabanois AT no-log.org); * David Gilbert (for Object Refinery Limited); * Ronnie Duan (see bug report 2583891); * * Changes * ------- * 14-Jun-2006 : New class (HP); * 29-Jan-2007 : Fixed the fillRect method (HP); * 31-Jan-2007 : Moved the dummy JPanel to SWTUtils.java, * implemented the drawLine method (HP); * 07-Apr-2007 : Dispose some of the swt ressources, * thanks to silent for pointing this out (HP); * 23-May-2007 : Removed resource leaks by adding a resource pool (CC); * 15-Jun-2007 : Fixed compile error for JDK 1.4 (DG); * 22-Oct-2007 : Implemented clipping (HP); * 22-Oct-2007 : Implemented some AlphaComposite support (HP); * 23-Oct-2007 : Added mechanism for storing RenderingHints (which are * still ignored at this point) (DG); * 23-Oct-2007 : Implemented drawPolygon(), drawPolyline(), drawOval(), * fillOval(), drawArc() and fillArc() (DG); * 27-Nov-2007 : Implemented a couple of drawImage() methods (DG); * 18-Nov-2008 : Check for GradientPaint in setPaint() method (DG); * 27-Feb-2009 : Implemented fillPolygon() - see bug 2583891 (DG); * */ package org.jfree.experimental.swt; import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Composite; import java.awt.Font; import java.awt.FontMetrics; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.Image; import java.awt.Paint; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.RenderingHints.Key; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; import java.awt.geom.PathIterator; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ImageObserver; import java.awt.image.RenderedImage; import java.awt.image.renderable.RenderableImage; import java.text.AttributedCharacterIterator; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.Path; import org.eclipse.swt.graphics.Resource; import org.eclipse.swt.graphics.Transform; /** * This is a class utility to draw Graphics2D stuff on a swt composite. * It is presently developed to use JFreeChart with the Standard * Widget Toolkit but may be of a wider use later. */ public class SWTGraphics2D extends Graphics2D { /** The swt graphic composite */ private GC gc; /** * The rendering hints. For now, these are not used, but at least the * basic mechanism is present. */ private RenderingHints hints; /** A reference to the compositing rule to apply. This is necessary * due to the poor compositing interface of the SWT toolkit. */ private java.awt.Composite composite; /** A HashMap to store the Swt color resources. */ private Map colorsPool = new HashMap(); /** A HashMap to store the Swt font resources. */ private Map fontsPool = new HashMap(); /** A HashMap to store the Swt transform resources. */ private Map transformsPool = new HashMap(); /** A List to store the Swt resources. */ private List resourcePool = new ArrayList(); /** * Creates a new instance. * * @param gc the graphics context. */ public SWTGraphics2D(GC gc) { super(); this.gc = gc; this.hints = new RenderingHints(null); this.composite = AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f); } /** * Not implemented yet - see {@link Graphics#create()}. * * @return <code>null. */ public Graphics create() { // TODO Auto-generated method stub return null; } /** * Not implemented yet - see {@link Graphics2D#getDeviceConfiguration()}. * * @return <code>null. */ public GraphicsConfiguration getDeviceConfiguration() { // TODO Auto-generated method stub return null; } /** * Returns the current value for the specified hint key, or * <code>null if no value is set. * * @param hintKey the hint key (<code>null permitted). * * @return The hint value, or <code>null. * * @see #setRenderingHint(RenderingHints.Key, Object) */ public Object getRenderingHint(Key hintKey) { return this.hints.get(hintKey); } /** * Sets the value for a rendering hint. For now, this graphics context * ignores all hints. * * @param hintKey the key (<code>null not permitted). * @param hintValue the value (must be compatible with the specified key). * * @throws IllegalArgumentException if <code>hintValue is not * compatible with the <code>hintKey. * * @see #getRenderingHint(RenderingHints.Key) */ public void setRenderingHint(Key hintKey, Object hintValue) { this.hints.put(hintKey, hintValue); } /** * Returns a copy of the hints collection for this graphics context. * * @return A copy of the hints collection. */ public RenderingHints getRenderingHints() { return (RenderingHints) this.hints.clone(); } /** * Adds the hints in the specified map to the graphics context, replacing * any existing hints. For now, this graphics context ignores all hints. * * @param hints the hints (<code>null not permitted). * * @see #setRenderingHints(Map) */ public void addRenderingHints(Map hints) { this.hints.putAll(hints); } /** * Replaces the existing hints with those contained in the specified * map. Note that, for now, this graphics context ignores all hints. * * @param hints the hints (<code>null not permitted). * * @see #addRenderingHints(Map) */ public void setRenderingHints(Map hints) { if (hints == null) { throw new NullPointerException("Null 'hints' argument."); } this.hints = new RenderingHints(hints); } /** * Returns the current paint for this graphics context. * * @return The current paint. * * @see #setPaint(Paint) */ public Paint getPaint() { // TODO: it might be a good idea to keep a reference to the color // specified in setPaint() or setColor(), rather than creating a // new object every time getPaint() is called. return SWTUtils.toAwtColor(this.gc.getForeground()); } /** * Sets the paint for this graphics context. For now, this graphics * context only supports instances of {@link Color} or * {@link GradientPaint} (in the latter case there is no real gradient * support, the paint used is the <code>Color returned by * <code>getColor1()). * * @param paint the paint (<code>null not permitted). * * @see #getPaint() * @see #setColor(Color) */ public void setPaint(Paint paint) { if (paint instanceof Color) { setColor((Color) paint); } else if (paint instanceof GradientPaint) { GradientPaint gp = (GradientPaint) paint; setColor(gp.getColor1()); } else { throw new RuntimeException("Can only handle 'Color' at present."); } } /** * Returns the current color for this graphics context. * * @return The current color. * * @see #setColor(Color) */ public Color getColor() { // TODO: it might be a good idea to keep a reference to the color // specified in setPaint() or setColor(), rather than creating a // new object every time getPaint() is called. return SWTUtils.toAwtColor(this.gc.getForeground()); } /** * Sets the current color for this graphics context. * * @param color the color. * * @see #getColor() */ public void setColor(Color color) { org.eclipse.swt.graphics.Color swtColor = getSwtColorFromPool(color); this.gc.setForeground(swtColor); // handle transparency and compositing. if (this.composite instanceof AlphaComposite) { AlphaComposite acomp = (AlphaComposite) this.composite; switch (acomp.getRule()) { case AlphaComposite.SRC_OVER: this.gc.setAlpha((int) (color.getAlpha() * acomp.getAlpha())); break; default: this.gc.setAlpha(color.getAlpha()); break; } } } /** * Sets the background colour. * * @param color the colour. */ public void setBackground(Color color) { org.eclipse.swt.graphics.Color swtColor = getSwtColorFromPool(color); this.gc.setBackground(swtColor); } /** * Returns the background colour. * * @return The background colour. */ public Color getBackground() { return SWTUtils.toAwtColor(this.gc.getBackground()); } /** * Not implemented - see {@link Graphics#setPaintMode()}. */ public void setPaintMode() { // TODO Auto-generated method stub } /** * Not implemented - see {@link Graphics#setXORMode(Color)}. * * @param color the colour. */ public void setXORMode(Color color) { // TODO Auto-generated method stub } /** * Returns the current composite. * * @return The current composite. * * @see #setComposite(Composite) */ public Composite getComposite() { return this.composite; } /** * Sets the current composite. This implementation currently supports * only the {@link AlphaComposite} class. * * @param comp the composite. */ public void setComposite(Composite comp) { this.composite = comp; if (comp instanceof AlphaComposite) { AlphaComposite acomp = (AlphaComposite) comp; int alpha = (int) (acomp.getAlpha() * 0xFF); this.gc.setAlpha(alpha); } else { System.out.println("warning, can only handle alpha composite at the moment."); } } /** * Returns the current stroke for this graphics context. * * @return The current stroke. * * @see #setStroke(Stroke) */ public Stroke getStroke() { return new BasicStroke(this.gc.getLineWidth(), this.gc.getLineCap(), this.gc.getLineJoin()); } /** * Sets the stroke for this graphics context. For now, this implementation * only recognises the {@link BasicStroke} class. * * @param stroke the stroke (<code>null not permitted). * * @see #getStroke() */ public void setStroke(Stroke stroke) { if (stroke instanceof BasicStroke) { BasicStroke bs = (BasicStroke) stroke; // linewidth this.gc.setLineWidth((int) bs.getLineWidth()); // line join switch (bs.getLineJoin()) { case BasicStroke.JOIN_BEVEL : this.gc.setLineJoin(SWT.JOIN_BEVEL); break; case BasicStroke.JOIN_MITER : this.gc.setLineJoin(SWT.JOIN_MITER); break; case BasicStroke.JOIN_ROUND : this.gc.setLineJoin(SWT.JOIN_ROUND); break; } // line cap switch (bs.getEndCap()) { case BasicStroke.CAP_BUTT : this.gc.setLineCap(SWT.CAP_FLAT); break; case BasicStroke.CAP_ROUND : this.gc.setLineCap(SWT.CAP_ROUND); break; case BasicStroke.CAP_SQUARE : this.gc.setLineCap(SWT.CAP_SQUARE); break; } // set the line style to solid by default this.gc.setLineStyle(SWT.LINE_SOLID); // apply dash style if any float[] dashes = bs.getDashArray(); if (dashes != null) { int[] swtDashes = new int[dashes.length]; for (int i = 0; i < swtDashes.length; i++) { swtDashes[i] = (int) dashes[i]; } this.gc.setLineDash(swtDashes); } } else { throw new RuntimeException( "Can only handle 'Basic Stroke' at present."); } } /** * Applies the specified clip. * * @param s the shape for the clip. */ public void clip(Shape s) { Path path = toSwtPath(s); this.gc.setClipping(path); path.dispose(); } /** * Returns the clip bounds. * * @return The clip bounds. */ public Rectangle getClipBounds() { org.eclipse.swt.graphics.Rectangle clip = this.gc.getClipping(); return new Rectangle(clip.x, clip.y, clip.width, clip.height); } /** * Sets the clipping to the intersection of the current clip region and * the specified rectangle. * * @param x the x-coordinate. * @param y the y-coordinate. * @param width the width. * @param height the height. */ public void clipRect(int x, int y, int width, int height) { org.eclipse.swt.graphics.Rectangle clip = this.gc.getClipping(); clip.intersects(x, y, width, height); this.gc.setClipping(clip); } /** * Returns the current clip. * * @return The current clip. */ public Shape getClip() { return SWTUtils.toAwtRectangle(this.gc.getClipping()); } /** * Sets the clip region. * * @param clip the clip. */ public void setClip(Shape clip) { if (clip == null) { return; } Path clipPath = toSwtPath(clip); this.gc.setClipping(clipPath); clipPath.dispose(); } /** * Sets the clip region to the specified rectangle. * * @param x the x-coordinate. * @param y the y-coordinate. * @param width the width. * @param height the height. */ public void setClip(int x, int y, int width, int height) { this.gc.setClipping(x, y, width, height); } /** * Returns the current transform. * * @return The current transform. */ public AffineTransform getTransform() { Transform swtTransform = new Transform(this.gc.getDevice()); this.gc.getTransform(swtTransform); AffineTransform awtTransform = toAwtTransform(swtTransform); swtTransform.dispose(); return awtTransform; } /** * Sets the current transform. * * @param t the transform. */ public void setTransform(AffineTransform t) { Transform transform = getSwtTransformFromPool(t); this.gc.setTransform(transform); } /** * Concatenates the specified transform to the existing transform. * * @param t the transform. */ public void transform(AffineTransform t) { Transform swtTransform = new Transform(this.gc.getDevice()); this.gc.getTransform(swtTransform); swtTransform.multiply(getSwtTransformFromPool(t)); this.gc.setTransform(swtTransform); swtTransform.dispose(); } /** * Applies a translation. * * @param x the translation along the x-axis. * @param y the translation along the y-axis. */ public void translate(int x, int y) { Transform swtTransform = new Transform(this.gc.getDevice()); this.gc.getTransform(swtTransform); swtTransform.translate(x, y); this.gc.setTransform(swtTransform); swtTransform.dispose(); } /** * Applies a translation. * * @param tx the translation along the x-axis. * @param ty the translation along the y-axis. */ public void translate(double tx, double ty) { translate((int) tx, (int) ty); } /** * Applies a rotation transform. * * @param theta the angle of rotation. */ public void rotate(double theta) { Transform swtTransform = new Transform(this.gc.getDevice()); this.gc.getTransform(swtTransform); swtTransform.rotate((float) (theta * 180 / Math.PI)); this.gc.setTransform(swtTransform); swtTransform.dispose(); } /** * Not implemented - see {@link Graphics2D#rotate(double, double, double)}. * * @see java.awt.Graphics2D#rotate(double, double, double) */ public void rotate(double theta, double x, double y) { // TODO Auto-generated method stub } /** * Applies a scale transform. * * @param scaleX the scale factor along the x-axis. * @param scaleY the scale factor along the y-axis. */ public void scale(double scaleX, double scaleY) { Transform swtTransform = new Transform(this.gc.getDevice()); this.gc.getTransform(swtTransform); swtTransform.scale((float) scaleX, (float) scaleY); this.gc.setTransform(swtTransform); swtTransform.dispose(); } /** * Applies a shear transform. * * @param shearX the x-factor. * @param shearY the y-factor. */ public void shear(double shearX, double shearY) { Transform swtTransform = new Transform(this.gc.getDevice()); this.gc.getTransform(swtTransform); Transform shear = new Transform(this.gc.getDevice(), 1f, (float) shearX, (float) shearY, 1f, 0, 0); swtTransform.multiply(shear); this.gc.setTransform(swtTransform); swtTransform.dispose(); } /** * Draws the outline of the specified shape using the current stroke and * paint settings. * * @param shape the shape (<code>null not permitted). * * @see #getPaint() * @see #getStroke() * @see #fill(Shape) */ public void draw(Shape shape) { Path path = toSwtPath(shape); this.gc.drawPath(path); path.dispose(); } /** * Draws a line from (x1, y1) to (x2, y2) using the current stroke * and paint settings. * * @param x1 the x-coordinate for the starting point. * @param y1 the y-coordinate for the starting point. * @param x2 the x-coordinate for the ending point. * @param y2 the y-coordinate for the ending point. * * @see #draw(Shape) */ public void drawLine(int x1, int y1, int x2, int y2) { this.gc.drawLine(x1, y1, x2, y2); } /** * Draws the outline of the polygon specified by the given points, using * the current paint and stroke settings. * * @param xPoints the x-coordinates. * @param yPoints the y-coordinates. * @param npoints the number of points in the polygon. * * @see #draw(Shape) */ public void drawPolygon(int [] xPoints, int [] yPoints, int npoints) { drawPolyline(xPoints, yPoints, npoints); if (npoints > 1) { this.gc.drawLine(xPoints[npoints - 1], yPoints[npoints - 1], xPoints[0], yPoints[0]); } } /** * Draws a sequence of connected lines specified by the given points, using * the current paint and stroke settings. * * @param xPoints the x-coordinates. * @param yPoints the y-coordinates. * @param npoints the number of points in the polygon. * * @see #draw(Shape) */ public void drawPolyline(int [] xPoints, int [] yPoints, int npoints) { if (npoints > 1) { int x0 = xPoints[0]; int y0 = yPoints[0]; int x1 = 0, y1 = 0; for (int i = 1; i < npoints; i++) { x1 = xPoints[i]; y1 = yPoints[i]; this.gc.drawLine(x0, y0, x1, y1); x0 = x1; y0 = y1; } } } /** * Draws an oval that fits within the specified rectangular region. * * @param x the x-coordinate. * @param y the y-coordinate. * @param width the frame width. * @param height the frame height. * * @see #fillOval(int, int, int, int) * @see #draw(Shape) */ public void drawOval(int x, int y, int width, int height) { this.gc.drawOval(x, y, width - 1, height - 1); } /** * Draws an arc that is part of an ellipse that fits within the specified * framing rectangle. * * @param x the x-coordinate. * @param y the y-coordinate. * @param width the frame width. * @param height the frame height. * @param arcStart the arc starting point, in degrees. * @param arcAngle the extent of the arc. * * @see #fillArc(int, int, int, int, int, int) */ public void drawArc(int x, int y, int width, int height, int arcStart, int arcAngle) { this.gc.drawArc(x, y, width - 1, height - 1, arcStart, arcAngle); } /** * Draws a rectangle with rounded corners that fits within the specified * framing rectangle. * * @param x the x-coordinate. * @param y the y-coordinate. * @param width the frame width. * @param height the frame height. * @param arcWidth the width of the arc defining the roundedness of the * rectangle's corners. * @param arcHeight the height of the arc defining the roundedness of the * rectangle's corners. * * @see #fillRoundRect(int, int, int, int, int, int) */ public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { this.gc.drawRoundRectangle(x, y, width - 1, height - 1, arcWidth, arcHeight); } /** * Fills the specified shape using the current paint. * * @param shape the shape (<code>null not permitted). * * @see #getPaint() * @see #draw(Shape) */ public void fill(Shape shape) { Path path = toSwtPath(shape); // Note that for consistency with the AWT implementation, it is // necessary to switch temporarily the foreground and background // colours switchColors(); this.gc.fillPath(path); switchColors(); path.dispose(); } /** * Fill a rectangle area on the swt graphic composite. * The <code>fillRectangle method of the Other jfreechart examples (source code examples)Here is a short list of links related to this jfreechart SWTGraphics2D.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.