001 /* 002 * PainterPropertyEditor.java 003 * 004 * Created on March 21, 2006, 11:26 AM 005 * 006 * To change this template, choose Tools | Template Manager 007 * and open the template in the editor. 008 */ 009 010 package org.jdesktop.swingx.editors; 011 012 import java.awt.Color; 013 import java.awt.GradientPaint; 014 import java.awt.geom.AffineTransform; 015 import java.awt.geom.Arc2D; 016 import java.awt.geom.Area; 017 import java.awt.geom.CubicCurve2D; 018 import java.awt.geom.Ellipse2D; 019 import java.awt.geom.GeneralPath; 020 import java.awt.geom.Line2D; 021 import java.awt.geom.PathIterator; 022 import java.awt.geom.Point2D; 023 import java.awt.geom.QuadCurve2D; 024 import java.awt.geom.Rectangle2D; 025 import java.awt.geom.RoundRectangle2D; 026 import java.beans.DefaultPersistenceDelegate; 027 import java.beans.Encoder; 028 import java.beans.Expression; 029 import java.beans.PersistenceDelegate; 030 import java.beans.PropertyEditorSupport; 031 import java.beans.Statement; 032 import java.beans.XMLDecoder; 033 import java.beans.XMLEncoder; 034 import java.io.ByteArrayInputStream; 035 import java.io.ByteArrayOutputStream; 036 import javax.swing.JFrame; 037 import org.apache.batik.ext.awt.LinearGradientPaint; 038 import org.apache.batik.ext.awt.MultipleGradientPaint.ColorSpaceEnum; 039 import org.apache.batik.ext.awt.RadialGradientPaint; 040 import org.jdesktop.swingx.JXPanel; 041 import org.jdesktop.swingx.painter.BackgroundPainter; 042 import org.jdesktop.swingx.painter.CheckerboardPainter; 043 import org.jdesktop.swingx.painter.CompoundPainter; 044 import org.jdesktop.swingx.painter.GlossPainter; 045 import org.jdesktop.swingx.painter.MattePainter; 046 import org.jdesktop.swingx.painter.Painter; 047 import org.jdesktop.swingx.painter.PinstripePainter; 048 import org.jdesktop.swingx.painter.ShapePainter; 049 import org.jdesktop.swingx.painter.TextPainter; 050 import org.jdesktop.swingx.painter.gradient.BasicGradientPainter; 051 import org.jdesktop.swingx.painter.gradient.LinearGradientPainter; 052 import org.jdesktop.swingx.painter.gradient.RadialGradientPainter; 053 054 /** 055 * Two parts to this property editor. The first part is a simple dropdown. 056 * The second part is a complicated UI for constructing multiple "layers" of 057 * various different Painters, including gradient painters. 058 * 059 * @author Richard 060 */ 061 public class PainterPropertyEditor extends PropertyEditorSupport { 062 /** Creates a new instance of PainterPropertyEditor */ 063 public PainterPropertyEditor() { 064 } 065 066 public Painter getValue() { 067 return (Painter)super.getValue(); 068 } 069 070 public String getJavaInitializationString() { 071 Painter painter = getValue(); 072 //TODO!!! 073 return painter == null ? "null" : 074 "new org.jdesktop.swingx.painter.CheckerboardPainter()"; 075 } 076 077 public static void main(String... args) { 078 ByteArrayOutputStream baos = new ByteArrayOutputStream(300); 079 XMLEncoder e = new XMLEncoder(baos); 080 081 e.setPersistenceDelegate(GradientPaint.class, new GradientPaintDelegate()); 082 e.setPersistenceDelegate(Arc2D.Float.class, new Arc2DDelegate()); 083 e.setPersistenceDelegate(Arc2D.Double.class, new Arc2DDelegate()); 084 e.setPersistenceDelegate(CubicCurve2D.Float.class, new CubicCurve2DDelegate()); 085 e.setPersistenceDelegate(CubicCurve2D.Double.class, new CubicCurve2DDelegate()); 086 e.setPersistenceDelegate(Ellipse2D.Float.class, new Ellipse2DDelegate()); 087 e.setPersistenceDelegate(Ellipse2D.Double.class, new Ellipse2DDelegate()); 088 e.setPersistenceDelegate(Line2D.Float.class, new Line2DDelegate()); 089 e.setPersistenceDelegate(Line2D.Double.class, new Line2DDelegate()); 090 e.setPersistenceDelegate(Point2D.Float.class, new Point2DDelegate()); 091 e.setPersistenceDelegate(Point2D.Double.class, new Point2DDelegate()); 092 e.setPersistenceDelegate(QuadCurve2D.Float.class, new QuadCurve2DDelegate()); 093 e.setPersistenceDelegate(QuadCurve2D.Double.class, new QuadCurve2DDelegate()); 094 e.setPersistenceDelegate(Rectangle2D.Float.class, new Rectangle2DDelegate()); 095 e.setPersistenceDelegate(Rectangle2D.Double.class, new Rectangle2DDelegate()); 096 e.setPersistenceDelegate(RoundRectangle2D.Float.class, new RoundRectangle2DDelegate()); 097 e.setPersistenceDelegate(RoundRectangle2D.Double.class, new RoundRectangle2DDelegate()); 098 e.setPersistenceDelegate(Area.class, new AreaDelegate()); 099 e.setPersistenceDelegate(GeneralPath.class, new GeneralPathDelegate()); 100 e.setPersistenceDelegate(AffineTransform.class, new AffineTransformDelegate()); 101 e.setPersistenceDelegate(RadialGradientPaint.class, new RadialGradientPaintDelegate()); 102 e.setPersistenceDelegate(LinearGradientPaint.class, new LinearGradientPaintDelegate()); 103 104 Area a = new Area(new RoundRectangle2D.Double(20, 20, 50, 50, 4, 4)); 105 a.add(new Area(new Ellipse2D.Double(10, 10, 100, 20))); 106 107 TextPainter textPainter = new TextPainter("Yo dude"); 108 textPainter.setPaint(Color.WHITE); 109 110 e.writeObject(new CompoundPainter( 111 new BackgroundPainter(), 112 new CheckerboardPainter(), 113 new MattePainter(Color.BLACK), 114 new BasicGradientPainter(BasicGradientPainter.RED_XP), 115 new LinearGradientPainter(LinearGradientPainter.BLACK_PERSPECTIVE), 116 new RadialGradientPainter(new RadialGradientPaint( 117 new Point2D.Double(.5, .5), 118 .2f, new float[] {0f, .5f, 1f}, 119 new Color[] {Color.BLACK,Color.WHITE,Color.RED})), 120 new ShapePainter(a), 121 new PinstripePainter(), 122 textPainter, 123 new GlossPainter() 124 // new IconPainter(), 125 // new ImagePainter(), 126 )); 127 e.close(); 128 System.out.println(baos.toString()); 129 130 XMLDecoder d = new XMLDecoder(new ByteArrayInputStream(baos.toByteArray())); 131 132 Painter p = (Painter)d.readObject(); 133 134 JFrame frame = new JFrame("Yo momma"); 135 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 136 JXPanel panel = new JXPanel(); 137 panel.setBackgroundPainter(p); 138 frame.add(panel); 139 frame.setSize(800,600); 140 frame.setVisible(true); 141 } 142 143 public static final class GradientPaintDelegate extends DefaultPersistenceDelegate { 144 public GradientPaintDelegate() { 145 super(new String[] {"point1", "color1", "point2", "color2"}); 146 } 147 } 148 public static final class LinearGradientPaintDelegate extends DefaultPersistenceDelegate { 149 public LinearGradientPaintDelegate() { 150 super(new String[] {"startPoint", "endPoint", "fractions", "colors"}); 151 //these 3 not yet supported. The problem is the 152 //colorspace. I haven't figured out how to transfer that one yet 153 //, "cycleMethod", "colorSpace", "transform"}); 154 } 155 156 protected Expression instantiate(Object oldInstance, Encoder out) { 157 158 ColorSpaceEnum e = ((LinearGradientPaint)oldInstance).getColorSpace(); 159 Expression retValue; 160 161 retValue = super.instantiate(oldInstance, out); 162 return retValue; 163 } 164 } 165 public static final class RadialGradientPaintDelegate extends DefaultPersistenceDelegate { 166 public RadialGradientPaintDelegate() { 167 super(new String[] {"centerPoint", "radius", "focusPoint", "fractions", "colors"}); 168 //these 3 not yet supported. The problem is the 169 //colorspace. I haven't figured out how to transfer that one yet 170 //, "cycleMethod", "colorSpace", "transform"}); 171 } 172 } 173 public static final class Arc2DDelegate extends DefaultPersistenceDelegate { 174 public Arc2DDelegate() { 175 super(new String[] {"x", "y", "width", "height", "angleStart", "angleExtent", "arcType"}); 176 } 177 } 178 public static final class CubicCurve2DDelegate extends DefaultPersistenceDelegate { 179 public CubicCurve2DDelegate() { 180 super(new String[] {"x1", "y1", "ctrlX1", "ctrlY1", "ctrlX2", "ctrlY2", "x2", "y2"}); 181 } 182 } 183 public static final class Ellipse2DDelegate extends DefaultPersistenceDelegate { 184 public Ellipse2DDelegate() { 185 super(new String[] {"x", "y", "width", "height"}); 186 } 187 } 188 public static final class Line2DDelegate extends DefaultPersistenceDelegate { 189 public Line2DDelegate() { 190 super(new String[] {"x1", "y1", "x2", "y2"}); 191 } 192 } 193 public static final class Point2DDelegate extends DefaultPersistenceDelegate { 194 public Point2DDelegate() { 195 super(new String[] {"x", "y"}); 196 } 197 } 198 public static final class QuadCurve2DDelegate extends DefaultPersistenceDelegate { 199 public QuadCurve2DDelegate() { 200 super(new String[] {"x1", "y1", "ctrlX", "ctrlY", "x2", "y2"}); 201 } 202 } 203 public static final class Rectangle2DDelegate extends DefaultPersistenceDelegate { 204 public Rectangle2DDelegate() { 205 super(new String[] {"x", "y", "width", "height"}); 206 } 207 } 208 public static final class RoundRectangle2DDelegate extends DefaultPersistenceDelegate { 209 public RoundRectangle2DDelegate() { 210 super(new String[] {"x", "y", "width", "height", "arcWidth", "arcHeight"}); 211 } 212 } 213 public static final class AreaDelegate extends PersistenceDelegate { 214 protected Expression instantiate(Object oldInstance, Encoder out) { 215 Area a = (Area)oldInstance; 216 217 //use the default constructor 218 AffineTransform tx = new AffineTransform(); 219 PathIterator itr = a.getPathIterator(tx); 220 221 GeneralPath path = new GeneralPath(); 222 out.writeExpression(new Expression(path, GeneralPath.class, "new", new Object[0])); 223 224 while (!itr.isDone()) { 225 float[] segment = new float[6]; //must use floats because lineTo etc use floats 226 int pathType = itr.currentSegment(segment); 227 228 switch (pathType) { 229 case PathIterator.SEG_CLOSE: 230 out.writeStatement(new Statement(path, "closePath", new Object[0])); 231 break; 232 case PathIterator.SEG_CUBICTO: 233 out.writeStatement(new Statement(path, "curveTo", new Object[] {segment[0], segment[1], segment[2], segment[3], segment[4], segment[5]})); 234 break; 235 case PathIterator.SEG_LINETO: 236 out.writeStatement(new Statement(path, "lineTo", new Object[] {segment[0], segment[1]})); 237 break; 238 case PathIterator.SEG_MOVETO: 239 out.writeStatement(new Statement(path, "moveTo", new Object[] {segment[0], segment[1]})); 240 break; 241 case PathIterator.SEG_QUADTO: 242 out.writeStatement(new Statement(path, "quadTo", new Object[] {segment[0], segment[1], segment[2], segment[3]})); 243 break; 244 } 245 itr.next(); 246 } 247 248 return new Expression(a, Area.class, "new", new Object[] {path}); 249 } 250 } 251 public static final class AffineTransformDelegate extends DefaultPersistenceDelegate { 252 public AffineTransformDelegate() { 253 super(new String[] {"scaleX", "shearY", "shearX", "scaleY", "translateX", "translateY"}); 254 } 255 } 256 public static final class GeneralPathDelegate extends PersistenceDelegate { 257 protected Expression instantiate(Object oldInstance, Encoder out) { 258 return new Expression(oldInstance, GeneralPath.class, "new", new Object[0]); 259 } 260 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) { 261 GeneralPath a = (GeneralPath)oldInstance; 262 263 AffineTransform tx = new AffineTransform(); 264 PathIterator itr = a.getPathIterator(tx); 265 266 out.writeStatement(new Statement(a, "setWindingRule", new Object[] {a.getWindingRule()})); 267 268 while (!itr.isDone()) { 269 float[] segment = new float[6]; //must use floats because lineTo etc use floats 270 int pathType = itr.currentSegment(segment); 271 272 switch (pathType) { 273 case PathIterator.SEG_CLOSE: 274 out.writeStatement(new Statement(a, "closePath", new Object[0])); 275 break; 276 case PathIterator.SEG_CUBICTO: 277 out.writeStatement(new Statement(a, "curveTo", new Object[] {segment[0], segment[1], segment[2], segment[3], segment[4], segment[5]})); 278 break; 279 case PathIterator.SEG_LINETO: 280 out.writeStatement(new Statement(a, "lineTo", new Object[] {segment[0], segment[1]})); 281 break; 282 case PathIterator.SEG_MOVETO: 283 out.writeStatement(new Statement(a, "moveTo", new Object[] {segment[0], segment[1]})); 284 break; 285 case PathIterator.SEG_QUADTO: 286 out.writeStatement(new Statement(a, "quadTo", new Object[] {segment[0], segment[1], segment[2], segment[3]})); 287 break; 288 } 289 itr.next(); 290 } 291 } 292 } 293 // public static final class PaintDelegate extends PersistenceDelegate { 294 // protected Expression instantiate(Object oldInstance, Encoder out) { 295 // if (oldInstance instanceof GradientPaint) { 296 // 297 // } 298 // } 299 // } 300 }