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.Insets;
015    import java.awt.LinearGradientPaint;
016    import java.awt.RadialGradientPaint;
017    import java.awt.MultipleGradientPaint.ColorSpaceType;
018    import java.awt.geom.AffineTransform;
019    import java.awt.geom.Arc2D;
020    import java.awt.geom.Area;
021    import java.awt.geom.CubicCurve2D;
022    import java.awt.geom.Ellipse2D;
023    import java.awt.geom.GeneralPath;
024    import java.awt.geom.Line2D;
025    import java.awt.geom.PathIterator;
026    import java.awt.geom.Point2D;
027    import java.awt.geom.QuadCurve2D;
028    import java.awt.geom.Rectangle2D;
029    import java.awt.geom.RoundRectangle2D;
030    import java.beans.DefaultPersistenceDelegate;
031    import java.beans.Encoder;
032    import java.beans.Expression;
033    import java.beans.PersistenceDelegate;
034    import java.beans.PropertyEditorSupport;
035    import java.beans.Statement;
036    import java.beans.XMLEncoder;
037    import java.io.ByteArrayOutputStream;
038    
039    import org.jdesktop.swingx.painter.Painter;
040    
041    /**
042     * Two parts to this property editor. The first part is a simple dropdown.
043     * The second part is a complicated UI for constructing multiple "layers" of
044     * various different Painters, including gradient painters.
045     *
046     * @author Richard
047     */
048    public class PainterPropertyEditor extends PropertyEditorSupport {
049        /** Creates a new instance of PainterPropertyEditor */
050        public PainterPropertyEditor() {
051        }
052        
053        public Painter getValue() {
054            return (Painter)super.getValue();
055        }
056        
057        public String getJavaInitializationString() {
058            Painter painter = getValue();
059            //TODO!!!
060            return painter == null ? "null" :
061                "new org.jdesktop.swingx.painter.CheckerboardPainter()";
062        }
063        
064        public static void main(String... args) {
065            ByteArrayOutputStream baos = new ByteArrayOutputStream(300);
066            XMLEncoder e = new XMLEncoder(baos);
067            
068            e.setPersistenceDelegate(GradientPaint.class, new GradientPaintDelegate());
069            e.setPersistenceDelegate(Arc2D.Float.class, new Arc2DDelegate());
070            e.setPersistenceDelegate(Arc2D.Double.class, new Arc2DDelegate());
071            e.setPersistenceDelegate(CubicCurve2D.Float.class, new CubicCurve2DDelegate());
072            e.setPersistenceDelegate(CubicCurve2D.Double.class, new CubicCurve2DDelegate());
073            e.setPersistenceDelegate(Ellipse2D.Float.class, new Ellipse2DDelegate());
074            e.setPersistenceDelegate(Ellipse2D.Double.class, new Ellipse2DDelegate());
075            e.setPersistenceDelegate(Line2D.Float.class, new Line2DDelegate());
076            e.setPersistenceDelegate(Line2D.Double.class, new Line2DDelegate());
077            e.setPersistenceDelegate(Point2D.Float.class, new Point2DDelegate());
078            e.setPersistenceDelegate(Point2D.Double.class, new Point2DDelegate());
079            e.setPersistenceDelegate(QuadCurve2D.Float.class, new QuadCurve2DDelegate());
080            e.setPersistenceDelegate(QuadCurve2D.Double.class, new QuadCurve2DDelegate());
081            e.setPersistenceDelegate(Rectangle2D.Float.class, new Rectangle2DDelegate());
082            e.setPersistenceDelegate(Rectangle2D.Double.class, new Rectangle2DDelegate());
083            e.setPersistenceDelegate(RoundRectangle2D.Float.class, new RoundRectangle2DDelegate());
084            e.setPersistenceDelegate(RoundRectangle2D.Double.class, new RoundRectangle2DDelegate());
085            e.setPersistenceDelegate(Area.class, new AreaDelegate());
086            e.setPersistenceDelegate(GeneralPath.class, new GeneralPathDelegate());
087            e.setPersistenceDelegate(AffineTransform.class, new AffineTransformDelegate());
088            e.setPersistenceDelegate(RadialGradientPaint.class, new RadialGradientPaintDelegate());
089            e.setPersistenceDelegate(LinearGradientPaint.class, new LinearGradientPaintDelegate());
090            e.setPersistenceDelegate(Insets.class, new InsetsDelegate());
091            
092            /*
093            Area a = new Area(new RoundRectangle2D.Double(20, 20, 50, 50, 4, 4));
094            a.add(new Area(new Ellipse2D.Double(10, 10, 100, 20)));
095             
096            TextPainter textPainter = new TextPainter("Yo dude");
097            textPainter.setFillPaint(Color.WHITE);
098            
099            e.writeObject(new CompoundPainter(
100                    new MattePainter(),
101                    new CheckerboardPainter(),
102                    new MattePainter(Color.BLACK),
103                    //new BasicGradientPainter(BasicGradientPainter.RED_XP),
104                    //new LinearGradientPainter(LinearGradientPainter.BLACK_PERSPECTIVE),
105                    new MattePainter(new RadialGradientPaint(
106                        new Point2D.Double(.5, .5),
107                        .2f, new float[] {0f, .5f, 1f},
108                        new Color[] {Color.BLACK,Color.WHITE,Color.RED})),
109                    new ShapePainter(a),
110                    new PinstripePainter(),
111                    textPainter,
112                    new GlossPainter()
113            //                new IconPainter(),
114            //                new ImagePainter(),
115                    ));
116            e.close();
117            System.out.println(baos.toString());
118             
119             
120            XMLDecoder d = new XMLDecoder(new ByteArrayInputStream(baos.toByteArray()));
121             
122            Painter p = (Painter)d.readObject();
123             
124            JFrame frame = new JFrame("Yo momma");
125            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
126            JXPanel panel = new JXPanel();
127            panel.setBackgroundPainter(p);
128            frame.add(panel);
129            frame.setSize(800,600);
130            frame.setVisible(true);
131             */
132            
133            RadialGradientPaint rp = new RadialGradientPaint(new Point2D.Double(0.5,0.5),
134                    .2f, new float[] {0f, .5f, 1f},
135                    new Color[] {Color.BLACK, Color.WHITE, Color.RED}
136            );
137            baos = new ByteArrayOutputStream(300);
138            e = new XMLEncoder(baos);
139            TestStuff ts = new TestStuff();
140            //ts.setStr("asdfasdf");
141            ts.str = "asdfasdf";
142            System.out.println("db = " + ts.getDb());
143            ts.setDb(new Point2D.Double(1.0,1.0));
144            ts.setIns(new Insets(5,5,5,5));
145            System.out.println("db = " + ts.getDb());
146            e.writeObject(ts);
147            e.close();
148            System.out.println("more stuff");
149            System.out.println(baos.toString());
150            if(new Point2D.Double(0,0).equals(new Point2D.Double(1,1))) {
151                System.out.println("they are equal");
152            } else {
153                System.out.println("they are not equal");
154            }
155        }
156        
157        public static final class TestStuff {
158            public Point2D.Double db = null;// = new Point2D.Double(5,5);
159            public TestStuff() {
160                
161            }
162            public TestStuff(Point2D.Double db, String str) {
163                setDb(db);
164                setStr(str);
165            }
166            public void setDb(Point2D.Double db) {
167                this.db = db;
168            }
169            public Point2D.Double getDb() {
170                //new Exception().printStackTrace();
171                return this.db;
172            }
173            public String str = "asdf";
174            public void setStr(String str) {
175                this.str = str;
176            }
177            public String getStr() {
178                return this.str;
179            }
180            private Insets ins = null;
181            
182            public Insets getIns() {
183                return ins;
184            }
185            
186            public void setIns(Insets ins) {
187                this.ins = ins;
188            }
189        }
190        
191        public static final class GradientPaintDelegate extends DefaultPersistenceDelegate {
192            public GradientPaintDelegate() {
193                super(new String[] {"point1", "color1", "point2", "color2"});
194            }
195        }
196        public static final class LinearGradientPaintDelegate extends DefaultPersistenceDelegate {
197            public LinearGradientPaintDelegate() {
198                super(new String[] {"startPoint", "endPoint", "fractions", "colors"});
199                //these 3 not yet supported. The problem is the
200                //colorspace. I haven't figured out how to transfer that one yet
201                //, "cycleMethod", "colorSpace", "transform"});
202            }
203            
204            protected Expression instantiate(Object oldInstance, Encoder out) {
205                
206                ColorSpaceType e = ((LinearGradientPaint)oldInstance).getColorSpace();
207                Expression retValue;
208                
209                retValue = super.instantiate(oldInstance, out);
210                return retValue;
211            }
212        }
213        public static final class RadialGradientPaintDelegate extends DefaultPersistenceDelegate {
214            public RadialGradientPaintDelegate() {
215                super(new String[] {"centerPoint", "radius", "focusPoint", "fractions", "colors"});
216                //these 3 not yet supported. The problem is the
217                //colorspace. I haven't figured out how to transfer that one yet
218                //, "cycleMethod", "colorSpace", "transform"});
219            }
220        }
221        public static final class Arc2DDelegate extends DefaultPersistenceDelegate {
222            public Arc2DDelegate() {
223                super(new String[] {"x", "y", "width", "height", "angleStart", "angleExtent", "arcType"});
224            }
225        }
226        public static final class CubicCurve2DDelegate extends DefaultPersistenceDelegate {
227            public CubicCurve2DDelegate() {
228                super(new String[] {"x1", "y1", "ctrlX1", "ctrlY1", "ctrlX2", "ctrlY2", "x2", "y2"});
229            }
230        }
231        public static final class Ellipse2DDelegate extends DefaultPersistenceDelegate {
232            public Ellipse2DDelegate() {
233                super(new String[] {"x", "y", "width", "height"});
234            }
235        }
236        public static final class Line2DDelegate extends DefaultPersistenceDelegate {
237            public Line2DDelegate() {
238                super(new String[] {"x1", "y1", "x2", "y2"});
239            }
240        }
241        public static final class Point2DDelegate extends DefaultPersistenceDelegate {
242            public Point2DDelegate() {
243                super(new String[] {"x", "y"});
244            }/*
245        protected Expression instantiate(Object oldInstance, Encoder out) {
246           Point2D pt = (Point2D)oldInstance;
247           Object[] constructorArgs = new Object[]{
248           pt.getX(), pt.getY()
249           };
250           return new Expression(new Point2D.Double(-1,-1), oldInstance.getClass(), "new", constructorArgs);
251       } */
252       /*
253            protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
254                super.initialize(type,oldInstance,newInstance,out);
255                System.out.println("initialize called: " + type + " " + oldInstance
256                        + " " + newInstance + " " + out);
257            }*/
258            
259        }
260        public static final class QuadCurve2DDelegate extends DefaultPersistenceDelegate {
261            public QuadCurve2DDelegate() {
262                super(new String[] {"x1", "y1", "ctrlX", "ctrlY", "x2", "y2"});
263            }
264        }
265        public static final class Rectangle2DDelegate extends DefaultPersistenceDelegate {
266            public Rectangle2DDelegate() {
267                super(new String[] {"x", "y", "width", "height"});
268            }
269        }
270        public static final class InsetsDelegate extends DefaultPersistenceDelegate {
271            public InsetsDelegate() {
272                super(new String[] {"top", "left", "bottom", "right"});
273            }
274            protected Expression instantiate(Object oldInstance,
275                    Encoder out) {
276                Insets ins = (Insets)oldInstance;
277                return new Expression(oldInstance,
278                        oldInstance.getClass(),
279                        "new",
280                        new Object[]{ ins.top, ins.left, ins.bottom, ins.right });
281            }
282        }
283        public static final class RoundRectangle2DDelegate extends DefaultPersistenceDelegate {
284            public RoundRectangle2DDelegate() {
285                super(new String[] {"x", "y", "width", "height", "arcWidth", "arcHeight"});
286            }
287        }
288        public static final class AreaDelegate extends PersistenceDelegate {
289            protected Expression instantiate(Object oldInstance, Encoder out) {
290                Area a = (Area)oldInstance;
291                
292                //use the default constructor
293                AffineTransform tx = new AffineTransform();
294                PathIterator itr = a.getPathIterator(tx);
295                
296                GeneralPath path = new GeneralPath();
297                out.writeExpression(new Expression(path, GeneralPath.class, "new", new Object[0]));
298                
299                while (!itr.isDone()) {
300                    float[] segment = new float[6]; //must use floats because lineTo etc use floats
301                    int pathType = itr.currentSegment(segment);
302                    
303                    switch (pathType) {
304                        case PathIterator.SEG_CLOSE:
305                            out.writeStatement(new Statement(path, "closePath", new Object[0]));
306                            break;
307                        case PathIterator.SEG_CUBICTO:
308                            out.writeStatement(new Statement(path, "curveTo", new Object[] {segment[0], segment[1], segment[2], segment[3], segment[4], segment[5]}));
309                            break;
310                        case PathIterator.SEG_LINETO:
311                            out.writeStatement(new Statement(path, "lineTo", new Object[] {segment[0], segment[1]}));
312                            break;
313                        case PathIterator.SEG_MOVETO:
314                            out.writeStatement(new Statement(path, "moveTo", new Object[] {segment[0], segment[1]}));
315                            break;
316                        case PathIterator.SEG_QUADTO:
317                            out.writeStatement(new Statement(path, "quadTo", new Object[] {segment[0], segment[1], segment[2], segment[3]}));
318                            break;
319                    }
320                    itr.next();
321                }
322                
323                return new Expression(a, Area.class, "new", new Object[] {path});
324            }
325        }
326        public static final class AffineTransformDelegate extends DefaultPersistenceDelegate {
327            public AffineTransformDelegate() {
328                super(new String[] {"scaleX", "shearY", "shearX", "scaleY", "translateX", "translateY"});
329            }
330        }
331        public static final class GeneralPathDelegate extends PersistenceDelegate {
332            protected Expression instantiate(Object oldInstance, Encoder out) {
333                return new Expression(oldInstance, GeneralPath.class, "new", new Object[0]);
334            }
335            protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
336                GeneralPath a = (GeneralPath)oldInstance;
337                
338                AffineTransform tx = new AffineTransform();
339                PathIterator itr = a.getPathIterator(tx);
340                
341                out.writeStatement(new Statement(a, "setWindingRule", new Object[] {a.getWindingRule()}));
342                
343                while (!itr.isDone()) {
344                    float[] segment = new float[6]; //must use floats because lineTo etc use floats
345                    int pathType = itr.currentSegment(segment);
346                    
347                    switch (pathType) {
348                        case PathIterator.SEG_CLOSE:
349                            out.writeStatement(new Statement(a, "closePath", new Object[0]));
350                            break;
351                        case PathIterator.SEG_CUBICTO:
352                            out.writeStatement(new Statement(a, "curveTo", new Object[] {segment[0], segment[1], segment[2], segment[3], segment[4], segment[5]}));
353                            break;
354                        case PathIterator.SEG_LINETO:
355                            out.writeStatement(new Statement(a, "lineTo", new Object[] {segment[0], segment[1]}));
356                            break;
357                        case PathIterator.SEG_MOVETO:
358                            out.writeStatement(new Statement(a, "moveTo", new Object[] {segment[0], segment[1]}));
359                            break;
360                        case PathIterator.SEG_QUADTO:
361                            out.writeStatement(new Statement(a, "quadTo", new Object[] {segment[0], segment[1], segment[2], segment[3]}));
362                            break;
363                    }
364                    itr.next();
365                }
366            }
367        }
368    //    public static final class PaintDelegate extends PersistenceDelegate {
369    //        protected Expression instantiate(Object oldInstance, Encoder out) {
370    //            if (oldInstance instanceof GradientPaint) {
371    //
372    //            }
373    //        }
374    //    }
375    }