Lab 9 (Mar 25-26)

As always, use the lab time to get started on the new assignment.

If you are done with the assignment or want to work on something else during the lab here's a program from an earlier homework assignment (and lab) that has been adapted to save its state in a file through object serialization.

Object Streams

Here's a modified version of Step3 from assignment 4. What's in blue is the new part. The part that deals with the I/O is in italics.

Step3, as you well remember, allowed the user to move circles around, repositioning them on the screen. This functionality has been left unchanged. The circles were initialized according to the values in the arrays xCoords, yCoords, radii, and colors.

A menu has been added such that the user can save the state of the screen at any time (the other two options simply pop up message boxes).

Using menus with BreezyGUI is explained on pp. 168-169 in the text.

The program saves the array of Circles in a file

model.dat
When the program is started the state of the screen is read from this file. The screen then appears as it was last saved. If something happens when reading from this file the default initialization of the circles (from Step3.java) is used. Note the use of object streams and that class Circle needs to implement the Serializable interface for objects of this type to be written/read to/from a file. This is explained in your text, on pages 358-360.


import java.io.*; 
import java.awt.*;
import BreezyGUI.*;

public class Lab9 extends GBFrame {

  Color[] colors = { Color.blue, 
                     Color.red, 
                     Color.yellow,
                     Color.yellow, 
                     Color.blue, 
                     Color.blue}; 

  int[] xCoords = { 230,  40, 120, 120, 210, 320}; 
  int[] yCoords = {  30, 120, 120,  60, 210,  50}; 

  int[] radii   = {  10,  20,  15,  20,  30,  25}; 
  
  public void paint(Graphics g) { 
    for (int i = 0; i < radii.length; i++) 
      circles[i].draw(g); 
  }

  int numberOfCircles = 6; 

  Circle[] circles = new Circle[numberOfCircles]; 

  MenuItem option1 = addMenuItem("Menu", "Save"); 
  MenuItem option2 = addMenuItem("Menu", "Save & Exit"); 
  MenuItem option3 = addMenuItem("Menu", "Quit"); 

  public void menuItemSelected (MenuItem menuItemObj) {
    if (menuItemObj == option1) { 
      try { 

        FileOutputStream   
          foStream 
            = new FileOutputStream("model.dat"); 

        ObjectOutputStream 
          ooStream 
            = new ObjectOutputStream(foStream); 

        for (int i = 0; i < circles.length; i++) { 
          ooStream.writeObject(circles[i]);
        } 

        foStream.flush(); 
        foStream.close(); 

        messageBox("Your screen has been saved."); 
      } catch (IOException e) {
        messageBox("Error during output: " + e.toString()); 
      } 
    } else     if (menuItemObj == option2) {
      messageBox("Save and Exit... "); 
    } else     if (menuItemObj == option3) {
      messageBox("Exit, no Save..."); 
    } 
  }

  Lab9() {
    try {  

      FileInputStream   
        fiStream 
          = new FileInputStream("model.dat"); 
 
      ObjectInputStream 
        oiStream 
          = new ObjectInputStream(fiStream); 

      for (int i = 0; i < numberOfCircles; i++) {
        circles[i] = (Circle)oiStream.readObject(); 
      } 

      fiStream.close();  

    } catch (Exception e) {   
      for (int i = 0; i < numberOfCircles; i++) {
        circles[i] = 
          new 
            Circle(xCoords[i], yCoords[i], radii[i], colors[i]); 
      } 
    }  
  } 

  Circle selectedCircle; 

  public void mousePressed(int x, int y) {
    for (int i = 0; i < radii.length; i++) 
      if (circles[i].inside(x, y)) {
        selectedCircle = circles[i]; 
        break; 
      } 
  } 

  public void mouseDragged(int x, int y) {
    if (selectedCircle != null) 
      selectedCircle.jumpTo(getGraphics(), x, y); 
  } 

  public void mouseReleased(int x, int y) {
    selectedCircle = null; 
  } 

  public static void main(String[] args) {
    Frame f = new Lab9(); 
    f.setSize(500, 300); 
    f.setVisible(true); 
  }
}

class Circle implements Serializable {
  private int x, y, radius; 
  private Color color;
  Circle( int xInitially, int yInitially, 
          int radiusInitially, Color colorInitially) {
    x      = xInitially; 
    y      = yInitially; 
    radius = radiusInitially; 
    color  = colorInitially; 
  } 
  void draw(Graphics g) {
    g.setColor(color); 
    g.setXORMode(Color.black); 
    g.fillOval(x, y, 2 * radius, 2 * radius); 
  } 
  void jumpTo(Graphics g, int newX, int newY) {
    draw(g); 
    x = newX - radius; 
    y = newY - radius; 
    draw(g); 
  } 
  boolean inside(int xMouse, int yMouse) {
    if (Math.sqrt((x + radius - xMouse) * (x + radius - xMouse) +
                  (y + radius - yMouse) * (y + radius - yMouse)) 
        <= radius)
      return true;
    else 
      return false; 
  } 
}