/* * PainterUtil.java * * Created on July 20, 2006, 1:18 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package org.jdesktop.beans.editors; import java.awt.GradientPaint; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.LinearGradientPaint; import java.awt.RadialGradientPaint; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.geom.Arc2D; import java.awt.geom.Area; import java.awt.geom.CubicCurve2D; import java.awt.geom.Ellipse2D; import java.awt.geom.GeneralPath; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.QuadCurve2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.beans.BeanInfo; import java.beans.DefaultPersistenceDelegate; import java.beans.Encoder; import java.beans.ExceptionListener; import java.beans.Expression; import java.beans.Introspector; import java.beans.PersistenceDelegate; import java.beans.PropertyDescriptor; import java.beans.Statement; import java.beans.XMLDecoder; import java.beans.XMLEncoder; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.net.MalformedURLException; import java.net.URL; import javax.imageio.ImageIO; import javax.swing.JComponent; import org.jdesktop.beans.editors.PainterPropertyEditor.AffineTransformDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.Arc2DDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.AreaDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.CubicCurve2DDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.Ellipse2DDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.GeneralPathDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.GradientPaintDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.InsetsDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.Line2DDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.LinearGradientPaintDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.Point2DDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.QuadCurve2DDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.RadialGradientPaintDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.Rectangle2DDelegate; import org.jdesktop.beans.editors.PainterPropertyEditor.RoundRectangle2DDelegate; import org.jdesktop.swingx.JXButton; import org.jdesktop.swingx.JXLabel; import org.jdesktop.swingx.JXPanel; import org.jdesktop.swingx.painter.AbstractLayoutPainter; import org.jdesktop.swingx.painter.AbstractPainter; import org.jdesktop.swingx.painter.CompoundPainter; import org.jdesktop.swingx.painter.ImagePainter; import org.jdesktop.swingx.painter.Painter; import org.jdesktop.swingx.painter.RectanglePainter; /** * * @author joshy */ public class PainterUtil { /** Creates a new instance of PainterUtil */ private PainterUtil() { } /* public static void main(String[] args) throws Exception { ImagePainter ip = new ImagePainter(); ip.setImageString("file:/Users/joshy/Pictures/cooltikis.jpg"); File outfile = new File("/Users/joshy/Desktop/test.xml"); outfile.createNewFile(); p("outfile = " + outfile.getAbsolutePath()); p("exists = " + outfile.exists()); savePainterToFile(ip, outfile, outfile.getParentFile().toURL()); p("---------"); ip = (ImagePainter)loadPainter(outfile); p("image = " + ip.getImage()); ip = (ImagePainter)loadPainter(outfile.toURL()); p("image = " + ip.getImage()); p("=================="); }*/ public static Painter loadPainter(File file) throws FileNotFoundException, MalformedURLException, IOException { return loadPainter(file.toURI().toURL(), file.toURI().toURL()); } private static Painter loadPainter(final URL in, URL baseURL) throws FileNotFoundException, IOException { Thread.currentThread().setContextClassLoader(PainterUtil.class.getClassLoader()); XMLDecoder dec = new XMLDecoder(in.openStream()); // p("creating a persistence owner with the base url: " + baseURL); dec.setOwner(new PersistenceOwner(baseURL)); dec.setExceptionListener(new ExceptionListener() { public void exceptionThrown(Exception ex) { System.out.println(ex.getMessage()); ex.printStackTrace(); } }); Object obj = dec.readObject(); return (Painter)obj; } public static Painter loadPainter(URL url) throws IOException { return loadPainter(url,url); } static public void savePainterToFile(Painter compoundPainter, File file) throws IOException { savePainterToFile(compoundPainter,file,file.getParentFile().toURI().toURL()); } static public void savePainterToFile(Painter compoundPainter, File file, URL baseURL) throws IOException { //System.setErr(null); // u.p("writing out to: " + file.getCanonicalPath()); setTransient(ImagePainter.class, "image"); setTransient(ImagePainter.class, "imageString"); //setTransient(CompoundPainter.class,"antialiasing"); //setTransient(AbstractPainter.class,"antialiasing"); //setTransient(AbstractPainter.class,"renderingHints"); //setPropertyDelegate(); XMLEncoder e = new XMLEncoder(new FileOutputStream(file)); e.setOwner(new PersistenceOwner(baseURL)); //p("owner = " + e.getOwner()); //e.setOwner(compoundPainter); // serialize the enums //e.setPersistenceDelegate(AbstractPainter.Antialiasing.class, new TypeSafeEnumPersistenceDelegate()); e.setPersistenceDelegate(AbstractPainter.Interpolation.class, new TypeSafeEnumPersistenceDelegate()); // e.setPersistenceDelegate(AbstractPainter.FractionalMetrics.class, new TypeSafeEnumPersistenceDelegate()); e.setPersistenceDelegate(RectanglePainter.Style.class, new TypeSafeEnumPersistenceDelegate()); e.setPersistenceDelegate(AbstractLayoutPainter.HorizontalAlignment.class, new TypeSafeEnumPersistenceDelegate()); e.setPersistenceDelegate(AbstractLayoutPainter.VerticalAlignment.class, new TypeSafeEnumPersistenceDelegate()); e.setPersistenceDelegate(AbstractPainter.class, new AbstractPainterDelegate()); e.setPersistenceDelegate(ImagePainter.class, new ImagePainterDelegate()); e.setPersistenceDelegate(RenderingHints.class, new RenderingHintsDelegate()); e.setPersistenceDelegate(GradientPaint.class, new GradientPaintDelegate()); e.setPersistenceDelegate(Arc2D.Float.class, new Arc2DDelegate()); e.setPersistenceDelegate(Arc2D.Double.class, new Arc2DDelegate()); e.setPersistenceDelegate(CubicCurve2D.Float.class, new CubicCurve2DDelegate()); e.setPersistenceDelegate(CubicCurve2D.Double.class, new CubicCurve2DDelegate()); e.setPersistenceDelegate(Ellipse2D.Float.class, new Ellipse2DDelegate()); e.setPersistenceDelegate(Ellipse2D.Double.class, new Ellipse2DDelegate()); e.setPersistenceDelegate(Line2D.Float.class, new Line2DDelegate()); e.setPersistenceDelegate(Line2D.Double.class, new Line2DDelegate()); e.setPersistenceDelegate(Point2D.Float.class, new Point2DDelegate()); e.setPersistenceDelegate(Point2D.Double.class, new Point2DDelegate()); e.setPersistenceDelegate(QuadCurve2D.Float.class, new QuadCurve2DDelegate()); e.setPersistenceDelegate(QuadCurve2D.Double.class, new QuadCurve2DDelegate()); e.setPersistenceDelegate(Rectangle2D.Float.class, new Rectangle2DDelegate()); e.setPersistenceDelegate(Rectangle2D.Double.class, new Rectangle2DDelegate()); e.setPersistenceDelegate(RoundRectangle2D.Float.class, new RoundRectangle2DDelegate()); e.setPersistenceDelegate(RoundRectangle2D.Double.class, new RoundRectangle2DDelegate()); e.setPersistenceDelegate(Area.class, new AreaDelegate()); e.setPersistenceDelegate(GeneralPath.class, new GeneralPathDelegate()); e.setPersistenceDelegate(AffineTransform.class, new AffineTransformDelegate()); e.setPersistenceDelegate(RadialGradientPaint.class, new RadialGradientPaintDelegate()); e.setPersistenceDelegate(LinearGradientPaint.class, new LinearGradientPaintDelegate()); e.setPersistenceDelegate(Insets.class, new InsetsDelegate()); e.writeObject(compoundPainter); e.close(); } //private static void setPropertyDelegate(Class clazz, String property, ) private static void setTransient(Class clazz, String property) { try { BeanInfo info = Introspector.getBeanInfo(clazz); PropertyDescriptor[] propertyDescriptors = info.getPropertyDescriptors(); for (int i = 0; i < propertyDescriptors.length; ++i) { PropertyDescriptor pd = propertyDescriptors[i]; if (pd.getName().equals(property)) { pd.setValue("transient", Boolean.TRUE); //u.p(pd.attributeNames()); } } } catch (Exception ex) { //u.p(ex); } } static class TypeSafeEnumPersistenceDelegate extends PersistenceDelegate { @Override protected boolean mutatesTo( Object oldInstance, Object newInstance ) { return oldInstance == newInstance; } @Override protected Expression instantiate( Object oldInstance, Encoder out ) { Class type = oldInstance.getClass(); if ( !Modifier.isPublic( type.getModifiers() ) ) throw new IllegalArgumentException( "Could not instantiate instance of non-public class: " + oldInstance ); for ( Field field : type.getFields() ) { int mod = field.getModifiers(); if ( Modifier.isPublic( mod ) && Modifier.isStatic( mod ) && Modifier.isFinal( mod ) && ( type == field.getDeclaringClass() ) ) { try { if ( oldInstance == field.get( null ) ) return new Expression( oldInstance, field, "get", new Object[]{null} ); } catch ( IllegalAccessException exception ) { throw new IllegalArgumentException( "Could not get value of the field: " + field, exception ); } } } throw new IllegalArgumentException( "Could not instantiate value: " + oldInstance ); } } public static final class RenderingHintsDelegate extends PersistenceDelegate { @Override protected Expression instantiate(Object oldInstance, Encoder out) { //u.p("rh inst"); // give it a constructor w/ null as the argument return new Expression(oldInstance, oldInstance.getClass(), "new", new Object[] { null }); } @Override protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) { //u.p("rh init "); RenderingHints rh = (RenderingHints)oldInstance; out.writeStatement(new Statement(oldInstance, "put", new Object[] {RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON})); //u.p("done"); } } public static final class AbstractPainterDelegate extends DefaultPersistenceDelegate { @Override protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { // p("ap delegate called"); super.initialize(type, oldInstance, newInstance, out); } } public static final class ImagePainterDelegate extends DefaultPersistenceDelegate { @Override protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { // p("image painter delegate called"); super.initialize(type, oldInstance, newInstance, out); //p("old instance = " + oldInstance); //p("owner = " + ((XMLEncoder)out).getOwner()); PersistenceOwner owner = (PersistenceOwner)((XMLEncoder)out).getOwner(); ImagePainter ip = (ImagePainter)oldInstance; // p("need to convert string: " + ip.getImageString()); // String s = owner.toXMLURL(ip.getImageString()); // p("converted to: " + s); //out.writeExpression(new Expression(oldInstance,owner,"fromXMLURL",new Object[]{ip.getImageString()})); //out.writeStatement(new Statement(owner,"fromXMLURL",new Object[]{ip.getImageString()})); //out.writeStatement(new Statement(oldInstance,"setImageString",new Object[]{ //new Expression(oldInstance,owner,"fromXMLURL",new Object[]{ip.getImageString()}) //})); out.writeStatement(new Statement(oldInstance,"setResolver",new Object[]{owner})); // out.writeStatement(new Statement(oldInstance,"setImageString",new Object[]{s})); } } public static void savePainterToImage(JComponent testPanel, CompoundPainter compoundPainter, File file) throws IOException { BufferedImage img = new BufferedImage(testPanel.getWidth(),testPanel.getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D g = img.createGraphics(); setBGP(testPanel,compoundPainter); testPanel.paint(g); ImageIO.write(img,"png",file); } public static void setBGP(JComponent comp, Painter painter) { if(comp instanceof JXPanel) { ((JXPanel)comp).setBackgroundPainter(painter); } if(comp instanceof JXButton) { ((JXButton)comp).setBackgroundPainter(painter); } } public static void setFGP(JComponent comp, Painter painter) { if(comp instanceof JXLabel) { ((JXLabel)comp).setForegroundPainter(painter); } if(comp instanceof JXButton) { ((JXButton)comp).setForegroundPainter(painter); } } public static Painter getFGP(JComponent comp) { if(comp instanceof JXLabel) { return ((JXLabel)comp).getForegroundPainter(); } if(comp instanceof JXButton) { return ((JXButton)comp).getForegroundPainter(); } return null; } public static Painter getBGP(JComponent comp) { if(comp instanceof JXPanel) { return ((JXPanel)comp).getBackgroundPainter(); } if(comp instanceof JXButton) { return ((JXButton)comp).getBackgroundPainter(); } return null; } public static class PersistenceOwner { private URL baseURL; public PersistenceOwner(URL baseURL) { this.baseURL = baseURL; } public URL getBaseURL() { return baseURL; } public String toXMLURL(String url) { // p("========"); // p("in toXMLURL()"); // p("base url = " + baseURL); // p("url to convert = " + url); //trim off the beginning if the url is relative to the base if(url.startsWith(baseURL.toString())) { // p("it's a valid substring!!!!!!!!!!!!"); url = url.substring(baseURL.toString().length()); // p("subsstring = " + url); } // p("final url = " + url); // p("========"); return url; } public String fromXMLURL(String url) throws MalformedURLException { /*p("========"); p("in fromXMLURL()"); p("base url = " + baseURL); p("url to convert: " + url);*/ String s = new URL(baseURL,url).toString(); // p("returning: " + s); // p("========"); return s; } } }