001 /* 002 * PainterUtil.java 003 * 004 * Created on July 20, 2006, 1:18 PM 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 013 import java.awt.GradientPaint; 014 import java.awt.Graphics2D; 015 import java.awt.Insets; 016 import java.awt.LinearGradientPaint; 017 import java.awt.RadialGradientPaint; 018 import java.awt.RenderingHints; 019 import java.awt.geom.AffineTransform; 020 import java.awt.geom.Arc2D; 021 import java.awt.geom.Area; 022 import java.awt.geom.CubicCurve2D; 023 import java.awt.geom.Ellipse2D; 024 import java.awt.geom.GeneralPath; 025 import java.awt.geom.Line2D; 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.awt.image.BufferedImage; 031 import java.beans.BeanInfo; 032 import java.beans.DefaultPersistenceDelegate; 033 import java.beans.Encoder; 034 import java.beans.ExceptionListener; 035 import java.beans.Expression; 036 import java.beans.Introspector; 037 import java.beans.PersistenceDelegate; 038 import java.beans.PropertyDescriptor; 039 import java.beans.Statement; 040 import java.beans.XMLDecoder; 041 import java.beans.XMLEncoder; 042 import java.io.File; 043 import java.io.FileNotFoundException; 044 import java.io.FileOutputStream; 045 import java.io.IOException; 046 import java.lang.reflect.Field; 047 import java.lang.reflect.Modifier; 048 import java.net.MalformedURLException; 049 import java.net.URL; 050 051 import javax.imageio.ImageIO; 052 import javax.swing.JComponent; 053 054 import org.jdesktop.swingx.JXButton; 055 import org.jdesktop.swingx.JXLabel; 056 import org.jdesktop.swingx.JXPanel; 057 import org.jdesktop.swingx.editors.PainterPropertyEditor.AffineTransformDelegate; 058 import org.jdesktop.swingx.editors.PainterPropertyEditor.Arc2DDelegate; 059 import org.jdesktop.swingx.editors.PainterPropertyEditor.AreaDelegate; 060 import org.jdesktop.swingx.editors.PainterPropertyEditor.CubicCurve2DDelegate; 061 import org.jdesktop.swingx.editors.PainterPropertyEditor.Ellipse2DDelegate; 062 import org.jdesktop.swingx.editors.PainterPropertyEditor.GeneralPathDelegate; 063 import org.jdesktop.swingx.editors.PainterPropertyEditor.GradientPaintDelegate; 064 import org.jdesktop.swingx.editors.PainterPropertyEditor.InsetsDelegate; 065 import org.jdesktop.swingx.editors.PainterPropertyEditor.Line2DDelegate; 066 import org.jdesktop.swingx.editors.PainterPropertyEditor.LinearGradientPaintDelegate; 067 import org.jdesktop.swingx.editors.PainterPropertyEditor.Point2DDelegate; 068 import org.jdesktop.swingx.editors.PainterPropertyEditor.QuadCurve2DDelegate; 069 import org.jdesktop.swingx.editors.PainterPropertyEditor.RadialGradientPaintDelegate; 070 import org.jdesktop.swingx.editors.PainterPropertyEditor.Rectangle2DDelegate; 071 import org.jdesktop.swingx.editors.PainterPropertyEditor.RoundRectangle2DDelegate; 072 import org.jdesktop.swingx.painter.AbstractLayoutPainter; 073 import org.jdesktop.swingx.painter.AbstractPainter; 074 import org.jdesktop.swingx.painter.CompoundPainter; 075 import org.jdesktop.swingx.painter.ImagePainter; 076 import org.jdesktop.swingx.painter.Painter; 077 import org.jdesktop.swingx.painter.RectanglePainter; 078 079 /** 080 * 081 * @author joshy 082 */ 083 public class PainterUtil { 084 085 /** Creates a new instance of PainterUtil */ 086 private PainterUtil() { 087 } 088 /* 089 public static void main(String[] args) throws Exception { 090 ImagePainter ip = new ImagePainter(); 091 ip.setImageString("file:/Users/joshy/Pictures/cooltikis.jpg"); 092 File outfile = new File("/Users/joshy/Desktop/test.xml"); 093 outfile.createNewFile(); 094 p("outfile = " + outfile.getAbsolutePath()); 095 p("exists = " + outfile.exists()); 096 savePainterToFile(ip, outfile, outfile.getParentFile().toURL()); 097 p("---------"); 098 ip = (ImagePainter)loadPainter(outfile); 099 p("image = " + ip.getImage()); 100 ip = (ImagePainter)loadPainter(outfile.toURL()); 101 p("image = " + ip.getImage()); 102 p("=================="); 103 104 105 }*/ 106 107 public static Painter loadPainter(File file) throws FileNotFoundException, MalformedURLException, IOException { 108 return loadPainter(file.toURI().toURL(), file.toURI().toURL()); 109 } 110 111 private static Painter loadPainter(final URL in, URL baseURL) throws FileNotFoundException, IOException { 112 Thread.currentThread().setContextClassLoader(PainterUtil.class.getClassLoader()); 113 XMLDecoder dec = new XMLDecoder(in.openStream()); 114 // p("creating a persistence owner with the base url: " + baseURL); 115 dec.setOwner(new PersistenceOwner(baseURL)); 116 dec.setExceptionListener(new ExceptionListener() { 117 public void exceptionThrown(Exception ex) { 118 System.out.println(ex.getMessage()); 119 ex.printStackTrace(); 120 } 121 }); 122 Object obj = dec.readObject(); 123 return (Painter)obj; 124 } 125 126 public static Painter loadPainter(URL url) throws IOException { 127 return loadPainter(url,url); 128 } 129 130 static public void savePainterToFile(Painter compoundPainter, File file) throws IOException { 131 savePainterToFile(compoundPainter,file,file.getParentFile().toURI().toURL()); 132 } 133 134 static public void savePainterToFile(Painter compoundPainter, File file, URL baseURL) throws IOException { 135 //System.setErr(null); 136 // u.p("writing out to: " + file.getCanonicalPath()); 137 setTransient(ImagePainter.class, "image"); 138 setTransient(ImagePainter.class, "imageString"); 139 //setTransient(CompoundPainter.class,"antialiasing"); 140 //setTransient(AbstractPainter.class,"antialiasing"); 141 //setTransient(AbstractPainter.class,"renderingHints"); 142 //setPropertyDelegate(); 143 144 XMLEncoder e = new XMLEncoder(new FileOutputStream(file)); 145 e.setOwner(new PersistenceOwner(baseURL)); 146 //p("owner = " + e.getOwner()); 147 //e.setOwner(compoundPainter); 148 149 // serialize the enums 150 //e.setPersistenceDelegate(AbstractPainter.Antialiasing.class, new TypeSafeEnumPersistenceDelegate()); 151 e.setPersistenceDelegate(AbstractPainter.Interpolation.class, new TypeSafeEnumPersistenceDelegate()); 152 // e.setPersistenceDelegate(AbstractPainter.FractionalMetrics.class, new TypeSafeEnumPersistenceDelegate()); 153 e.setPersistenceDelegate(RectanglePainter.Style.class, new TypeSafeEnumPersistenceDelegate()); 154 e.setPersistenceDelegate(AbstractLayoutPainter.HorizontalAlignment.class, new TypeSafeEnumPersistenceDelegate()); 155 e.setPersistenceDelegate(AbstractLayoutPainter.VerticalAlignment.class, new TypeSafeEnumPersistenceDelegate()); 156 157 158 e.setPersistenceDelegate(AbstractPainter.class, new AbstractPainterDelegate()); 159 e.setPersistenceDelegate(ImagePainter.class, new ImagePainterDelegate()); 160 e.setPersistenceDelegate(RenderingHints.class, new RenderingHintsDelegate()); 161 e.setPersistenceDelegate(GradientPaint.class, new GradientPaintDelegate()); 162 e.setPersistenceDelegate(Arc2D.Float.class, new Arc2DDelegate()); 163 e.setPersistenceDelegate(Arc2D.Double.class, new Arc2DDelegate()); 164 e.setPersistenceDelegate(CubicCurve2D.Float.class, new CubicCurve2DDelegate()); 165 e.setPersistenceDelegate(CubicCurve2D.Double.class, new CubicCurve2DDelegate()); 166 e.setPersistenceDelegate(Ellipse2D.Float.class, new Ellipse2DDelegate()); 167 e.setPersistenceDelegate(Ellipse2D.Double.class, new Ellipse2DDelegate()); 168 e.setPersistenceDelegate(Line2D.Float.class, new Line2DDelegate()); 169 e.setPersistenceDelegate(Line2D.Double.class, new Line2DDelegate()); 170 e.setPersistenceDelegate(Point2D.Float.class, new Point2DDelegate()); 171 e.setPersistenceDelegate(Point2D.Double.class, new Point2DDelegate()); 172 e.setPersistenceDelegate(QuadCurve2D.Float.class, new QuadCurve2DDelegate()); 173 e.setPersistenceDelegate(QuadCurve2D.Double.class, new QuadCurve2DDelegate()); 174 e.setPersistenceDelegate(Rectangle2D.Float.class, new Rectangle2DDelegate()); 175 e.setPersistenceDelegate(Rectangle2D.Double.class, new Rectangle2DDelegate()); 176 e.setPersistenceDelegate(RoundRectangle2D.Float.class, new RoundRectangle2DDelegate()); 177 e.setPersistenceDelegate(RoundRectangle2D.Double.class, new RoundRectangle2DDelegate()); 178 e.setPersistenceDelegate(Area.class, new AreaDelegate()); 179 e.setPersistenceDelegate(GeneralPath.class, new GeneralPathDelegate()); 180 e.setPersistenceDelegate(AffineTransform.class, new AffineTransformDelegate()); 181 e.setPersistenceDelegate(RadialGradientPaint.class, new RadialGradientPaintDelegate()); 182 e.setPersistenceDelegate(LinearGradientPaint.class, new LinearGradientPaintDelegate()); 183 e.setPersistenceDelegate(Insets.class, new InsetsDelegate()); 184 185 e.writeObject(compoundPainter); 186 e.close(); 187 } 188 189 //private static void setPropertyDelegate(Class clazz, String property, ) 190 private static void setTransient(Class clazz, String property) { 191 try { 192 BeanInfo info = Introspector.getBeanInfo(clazz); 193 PropertyDescriptor[] propertyDescriptors = 194 info.getPropertyDescriptors(); 195 for (int i = 0; i < propertyDescriptors.length; ++i) { 196 PropertyDescriptor pd = propertyDescriptors[i]; 197 if (pd.getName().equals(property)) { 198 pd.setValue("transient", Boolean.TRUE); 199 //u.p(pd.attributeNames()); 200 } 201 } 202 } catch (Exception ex) { 203 //u.p(ex); 204 } 205 } 206 207 static class TypeSafeEnumPersistenceDelegate extends PersistenceDelegate { 208 protected boolean mutatesTo( Object oldInstance, Object newInstance ) { 209 return oldInstance == newInstance; 210 } 211 212 protected Expression instantiate( Object oldInstance, Encoder out ) { 213 Class type = oldInstance.getClass(); 214 if ( !Modifier.isPublic( type.getModifiers() ) ) 215 throw new IllegalArgumentException( "Could not instantiate instance of non-public class: " + oldInstance ); 216 217 for ( Field field : type.getFields() ) { 218 int mod = field.getModifiers(); 219 if ( Modifier.isPublic( mod ) && Modifier.isStatic( mod ) && Modifier.isFinal( mod ) && ( type == field.getDeclaringClass() ) ) { 220 try { 221 if ( oldInstance == field.get( null ) ) 222 return new Expression( oldInstance, field, "get", new Object[]{null} ); 223 } catch ( IllegalAccessException exception ) { 224 throw new IllegalArgumentException( "Could not get value of the field: " + field, exception ); 225 } 226 } 227 } 228 throw new IllegalArgumentException( "Could not instantiate value: " + oldInstance ); 229 } 230 } 231 232 public static final class RenderingHintsDelegate extends PersistenceDelegate { 233 protected Expression instantiate(Object oldInstance, Encoder out) { 234 //u.p("rh inst"); 235 // give it a constructor w/ null as the argument 236 return new Expression(oldInstance, oldInstance.getClass(), 237 "new", new Object[] { null }); 238 } 239 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) { 240 //u.p("rh init "); 241 RenderingHints rh = (RenderingHints)oldInstance; 242 out.writeStatement(new Statement(oldInstance, "put", 243 new Object[] {RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON})); 244 //u.p("done"); 245 } 246 } 247 248 public static final class AbstractPainterDelegate extends DefaultPersistenceDelegate { 249 protected void initialize(Class type, Object oldInstance, 250 Object newInstance, Encoder out) { 251 // p("ap delegate called"); 252 super.initialize(type, oldInstance, newInstance, out); 253 } 254 } 255 256 public static final class ImagePainterDelegate extends DefaultPersistenceDelegate { 257 protected void initialize(Class type, Object oldInstance, 258 Object newInstance, Encoder out) { 259 // p("image painter delegate called"); 260 super.initialize(type, oldInstance, newInstance, out); 261 //p("old instance = " + oldInstance); 262 //p("owner = " + ((XMLEncoder)out).getOwner()); 263 PersistenceOwner owner = (PersistenceOwner)((XMLEncoder)out).getOwner(); 264 ImagePainter ip = (ImagePainter)oldInstance; 265 // p("need to convert string: " + ip.getImageString()); 266 String s = owner.toXMLURL(ip.getImageString()); 267 // p("converted to: " + s); 268 //out.writeExpression(new Expression(oldInstance,owner,"fromXMLURL",new Object[]{ip.getImageString()})); 269 //out.writeStatement(new Statement(owner,"fromXMLURL",new Object[]{ip.getImageString()})); 270 //out.writeStatement(new Statement(oldInstance,"setImageString",new Object[]{ 271 //new Expression(oldInstance,owner,"fromXMLURL",new Object[]{ip.getImageString()}) 272 //})); 273 274 out.writeStatement(new Statement(oldInstance,"setResolver",new Object[]{owner})); 275 out.writeStatement(new Statement(oldInstance,"setImageString",new Object[]{s})); 276 } 277 } 278 279 public static void savePainterToImage(JComponent testPanel, CompoundPainter compoundPainter, File file) throws IOException { 280 BufferedImage img = new BufferedImage(testPanel.getWidth(),testPanel.getHeight(), 281 BufferedImage.TYPE_INT_ARGB); 282 Graphics2D g = img.createGraphics(); 283 setBGP(testPanel,compoundPainter); 284 testPanel.paint(g); 285 ImageIO.write(img,"png",file); 286 } 287 288 public static void setBGP(JComponent comp, Painter painter) { 289 if(comp instanceof JXPanel) { 290 ((JXPanel)comp).setBackgroundPainter(painter); 291 } 292 if(comp instanceof JXButton) { 293 ((JXButton)comp).setBackgroundPainter(painter); 294 } 295 } 296 public static void setFGP(JComponent comp, Painter painter) { 297 if(comp instanceof JXLabel) { 298 ((JXLabel)comp).setForegroundPainter(painter); 299 } 300 if(comp instanceof JXButton) { 301 ((JXButton)comp).setForegroundPainter(painter); 302 } 303 } 304 305 public static Painter getFGP(JComponent comp) { 306 if(comp instanceof JXLabel) { 307 return ((JXLabel)comp).getForegroundPainter(); 308 } 309 if(comp instanceof JXButton) { 310 return ((JXButton)comp).getForegroundPainter(); 311 } 312 return null; 313 } 314 315 public static Painter getBGP(JComponent comp) { 316 if(comp instanceof JXPanel) { 317 return ((JXPanel)comp).getBackgroundPainter(); 318 } 319 if(comp instanceof JXButton) { 320 return ((JXButton)comp).getBackgroundPainter(); 321 } 322 return null; 323 } 324 325 public static class PersistenceOwner { 326 private URL baseURL; 327 public PersistenceOwner(URL baseURL) { 328 this.baseURL = baseURL; 329 } 330 331 public URL getBaseURL() { 332 return baseURL; 333 } 334 public String toXMLURL(String url) { 335 // p("========"); 336 // p("in toXMLURL()"); 337 // p("base url = " + baseURL); 338 // p("url to convert = " + url); 339 //trim off the beginning if the url is relative to the base 340 if(url.startsWith(baseURL.toString())) { 341 // p("it's a valid substring!!!!!!!!!!!!"); 342 url = url.substring(baseURL.toString().length()); 343 // p("subsstring = " + url); 344 } 345 // p("final url = " + url); 346 // p("========"); 347 return url; 348 } 349 350 public String fromXMLURL(String url) throws MalformedURLException { 351 /*p("========"); 352 p("in fromXMLURL()"); 353 p("base url = " + baseURL); 354 p("url to convert: " + url);*/ 355 String s = new URL(baseURL,url).toString(); 356 // p("returning: " + s); 357 // p("========"); 358 return s; 359 } 360 } 361 }