001package horstmann.ch07_serial2;
002import java.awt.Graphics2D;
003import java.awt.Rectangle;
004import java.awt.geom.Ellipse2D;
005import java.awt.geom.RectangularShape;
006import java.io.IOException;
007import java.io.ObjectInputStream;
008import java.io.ObjectOutputStream;
009import java.io.Serializable;
010
011/**
012   A serializable car shape.
013 */
014public class Car implements Serializable
015{
016        private static final long serialVersionUID = 2008L;
017        /**
018      Constructs a car.
019      @param x the left of the bounding rectangle
020      @param y the top of the bounding rectangle
021      @param width the width of the bounding rectangle
022         */
023        public Car(int x, int y, int width)
024        {
025                body = new Rectangle(x, y + width / 6,
026                                width - 1, width / 6);
027                roof = new Rectangle(x + width / 3, y,
028                                width / 3, width / 6);
029                frontTire = new Ellipse2D.Double(x + width / 6, y + width / 3,
030                                width / 6, width / 6);
031                rearTire = new Ellipse2D.Double(x + width * 2 / 3, y + width / 3,
032                                width / 6, width / 6);
033        }
034
035        private void writeObject(ObjectOutputStream out)
036                        throws IOException
037        {
038                out.defaultWriteObject();
039                writeRectangularShape(out, frontTire);
040                writeRectangularShape(out, rearTire);
041        }
042
043        /**
044      A helper method to write a rectangular shape.
045      @param out the stream onto which to write the shape
046      @param s the shape to write
047         */
048        private static void writeRectangularShape(ObjectOutputStream out,
049                        RectangularShape s)
050                                        throws IOException
051        {
052                out.writeDouble(s.getX());
053                out.writeDouble(s.getY());
054                out.writeDouble(s.getWidth());
055                out.writeDouble(s.getHeight());
056        }
057
058        private void readObject(ObjectInputStream in)
059                        throws IOException, ClassNotFoundException
060        {
061                in.defaultReadObject();
062                frontTire = new Ellipse2D.Double();
063                readRectangularShape(in, frontTire);
064                rearTire = new Ellipse2D.Double();
065                readRectangularShape(in, rearTire);
066        }
067
068        /**
069      A helper method to read a rectangular shape.
070      @param in the stream from which to read the shape
071      @param s the shape to read. The method sets the frame
072      of this rectangular shape.
073         */
074        private static void readRectangularShape(ObjectInputStream in,
075                        RectangularShape s)
076                                        throws IOException
077        {
078                double x = in.readDouble();
079                double y = in.readDouble();
080                double width = in.readDouble();
081                double height = in.readDouble();
082                s.setFrame(x, y, width, height);
083        }
084
085        /**
086      Draws the car.
087      @param g2 the graphics context
088         */
089        public void draw(Graphics2D g2)
090        {
091                g2.draw(body);
092                g2.draw(roof);
093                g2.draw(frontTire);
094                g2.draw(rearTire);
095        }
096
097        public String toString()
098        {
099                return getClass().getName()
100                                + "[body=" + body
101                                + ",roof=" + roof
102                                + ",frontTire=" + formatRectangularShape(frontTire)
103                                + ",rearTire=" + formatRectangularShape(rearTire)
104                                + "]";
105        }
106
107        /**
108      A helper method to format a rectangular shape.
109      @param s the shape to format
110      @return a formatted representation of the given shape
111         */
112        private static String formatRectangularShape(RectangularShape s)
113        {
114                return RectangularShape.class.getName()
115                                + "[x=" + s.getX()
116                                + ",y=" + s.getY()
117                                + ",width=" + s.getWidth()
118                                + ",height=" + s.getHeight()
119                                + "]";
120        }
121
122
123        private Rectangle body;
124        private Rectangle roof;
125        private transient Ellipse2D.Double frontTire;
126        private transient Ellipse2D.Double rearTire;
127}
128
129