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