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