This exercise is a continuation of Exercise P10.14. When the program starts, it should look to see whether a file is present that contains a serialized array of vehicles. If so, it redisplays them. Otherwise, it generates random vehicles, writes them to a file, and displays them.

Here is a sample program output:

.

Complete the following files:

Truck.java

Vehicle.java

Use the following files:

Car.java

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

/**
   This class represents a car.
*/
public class Car extends Vehicle
{
   private final int CAR_WIDTH = 60;
   private final int CAR_HEIGHT = CAR_WIDTH / 2 ;

   /**
      Draw the car.
      @param g2 the graphics context
   */
   public void draw(Graphics2D g2)
   {
      Rectangle body = new Rectangle(getX(), getY() + CAR_HEIGHT / 3,
            CAR_WIDTH, CAR_HEIGHT / 3);

      Ellipse2D.Double frontTire = new Ellipse2D.Double(getX() + CAR_WIDTH / 6,
               getY() + CAR_HEIGHT * 2 / 3, CAR_WIDTH / 6, CAR_WIDTH / 6);
      Ellipse2D.Double rearTire = new Ellipse2D.Double(getX() + CAR_WIDTH * 4 / 6,
            getY() + CAR_HEIGHT * 2 / 3, CAR_WIDTH / 6, CAR_WIDTH / 6);

      Point2D.Double r1 = new Point2D.Double(getX() + CAR_WIDTH / 6,
            getY() + CAR_HEIGHT / 3); // the bottom of the front windshield
         
      Point2D.Double r2 = new Point2D.Double(getX() + CAR_WIDTH * 2 / 6, getY());
         // the front of the roof
      Point2D.Double r3 = new Point2D.Double(getX() + CAR_WIDTH * 4 / 6, getY());
         // the rear of the roof
      Point2D.Double r4 = new Point2D.Double(getX() + CAR_WIDTH * 5 / 6,
            getY() + CAR_HEIGHT / 3); // the bottom of the rear windshield

      Line2D.Double frontWindshield = new Line2D.Double(r1, r2);
      Line2D.Double roofTop = new Line2D.Double(r2, r3);
      Line2D.Double rearWindshield = new Line2D.Double(r3, r4);

      g2.draw(body);
      g2.draw(frontTire);
      g2.draw(rearTire);
      g2.draw(frontWindshield);
      g2.draw(roofTop);
      g2.draw(rearWindshield);
   }

   public int getHeight()
   {
      return CAR_HEIGHT;
   }
   
   public int getWidth()
   {
      return CAR_WIDTH;
   }
}

RandomVehicleViewer.java

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;

/**
   This program draws cars and trucks in random order.
*/
public class RandomVehicleViewer
{
   public static void main(String args[])
      throws IOException, ClassNotFoundException
   {
      JFrame frame = new JFrame();
      final int FRAME_WIDTH = 600;
      final int FRAME_HEIGHT = 600;

      frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      
      VehicleComponent component = new VehicleComponent();
      frame.add(component);
      frame.setVisible(true);      

      ArrayList<Vehicle> vehicles = null;
      try
      {
         ObjectInputStream in = new ObjectInputStream(new
            FileInputStream("vehicles.dat"));
         vehicles = (ArrayList<Vehicle>) in.readObject();
         in.close();
      }
      catch (IOException ex)
      {
         vehicles = new ArrayList<Vehicle>();
         Random generator = new Random();

         final int VEHICLE_COUNT = 10;

         for (int i = 1; i <= VEHICLE_COUNT; i++)
         {
            Vehicle v;
            if (generator.nextBoolean())
               v = new Car();
            else
               v = new Truck();
            v.setLocation(generator.nextInt(component.getWidth() - v.getWidth()),
               generator.nextInt(component.getHeight() - v.getHeight()));
            vehicles.add(v);
         }
         ObjectOutputStream out = new ObjectOutputStream(new
            FileOutputStream("vehicles.dat"));
         out.writeObject(vehicles);
         out.close();
      }

      for (Vehicle v : vehicles)
         component.add(v);
   }
}

VehicleComponent.java

import javax.swing.JComponent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;

/**
   This component draws a collection of vehicles.
*/
public class VehicleComponent extends JComponent
{
   private ArrayList<Vehicle> vehicles;

   public VehicleComponent()
   {
      vehicles = new ArrayList<Vehicle>();
   }

   public void paintComponent(Graphics g)
   {
      Graphics2D g2 = (Graphics2D) g;
      for (Vehicle v : vehicles)
         v.draw(g2);
   }

   public void add(Vehicle v)
   {
      vehicles.add(v);
      repaint();
   }
}