Serialize a java.awt.geom.Area

后端 未结 4 1261
时光说笑
时光说笑 2021-01-20 02:47

I have the need to serialize an Area object (java.awt.geom.Area) in a socket. However it doesn\'t seem to be serializable. Is there a way to do such thing? Maybe by converti

相关标签:
4条回答
  • 2021-01-20 03:13

    Use XStream to trivially convert it to/from XML. You don't need your object to implement particular interfaces, and the serialisation is customisable.

    0 讨论(0)
  • 2021-01-20 03:31

    Since Java 1.6 seems like there is a more formal way of doing this.

    All you have to do is convert the Area object to a Path2D.Double (or Path2D.Float) object (which is Serializable) with its corresponding append method, taking also into account the winding rule at construction time (or even later, with a corresponding setter that exists).

    To convert from Path2D.Double to Area, just use the Area's constructor which accepts a Shape.

    import java.awt.geom.AffineTransform;
    import java.awt.geom.Area;
    import java.awt.geom.Ellipse2D;
    import java.awt.geom.Path2D;
    import java.awt.geom.PathIterator;
    import java.awt.geom.Rectangle2D;
    
    public class SerializeArea {
    
        public static Path2D.Double toPath2D(final Area a) {
            final PathIterator pi = a.getPathIterator(new AffineTransform());
            final Path2D.Double path = new Path2D.Double();
            switch (pi.getWindingRule()) {
                case PathIterator.WIND_EVEN_ODD: path.setWindingRule(Path2D.WIND_EVEN_ODD); break;
                case PathIterator.WIND_NON_ZERO: path.setWindingRule(Path2D.WIND_NON_ZERO); break;
                default: throw new UnsupportedOperationException("Unimplemented winding rule.");
            }
            path.append(pi, false);
            return path;
        }
    
        public static Area toArea(final Path2D path) {
            return new Area(path);
        }
    
        public static void main(final String[] args) {
            final Area area = new Area(new Ellipse2D.Double(0, 0, 100, 100));
            area.intersect(new Area(new Rectangle2D.Double(0, 25, 100, 50))); //Creating something like a capsule.
    
            System.out.println(toArea(toPath2D(area)).equals(area)); //Prints true.
        }
    }
    
    0 讨论(0)
  • 2021-01-20 03:35

    I found this workaround:

    AffineTransform.getTranslateInstance(0,0).createTransformedShape(myArea)
    

    This results in a shape that can be serialized.

    0 讨论(0)
  • 2021-01-20 03:35

    From kieste's answer, this work-around can be derived.

    import java.awt.Shape;
    import java.awt.geom.AffineTransform;
    import java.awt.geom.Area;
    import java.io.IOException;
    import java.io.Serializable;
    
    public class SerialArea extends Area implements Serializable {
        private static final long serialVersionUID = -3627137348463415558L;
    
        /**
         * New Area
         */
        public SerialArea() {}
    
        /**
         * New Area From Shape
         */
        public SerialArea(Shape s) {
            super(s);
        }
    
        /**
         * Writes object out to out.
         * @param out Output
         * @throws IOException if I/O errors occur while writing to the
         *  underlying OutputStream
         */
        private void writeObject(java.io.ObjectOutputStream out)
                throws IOException {
            out.writeObject(AffineTransform.getTranslateInstance(0, 0).
                createTransformedShape(this));
        }
        /**
         * Reads object in from in.
         * @param in Input
         * @throws IOException if I/O errors occur while writing to the
         *  underlying OutputStream
         * @throws ClassNotFoundException if the class of a serialized object
         *  could not be found.
         */
        private void readObject(java.io.ObjectInputStream in)
                throws IOException, ClassNotFoundException {
            add(new Area((Shape) in.readObject()));
        }
    }
    
    0 讨论(0)
提交回复
热议问题