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 }