Google
 
Site navigation: [ Home | Theory | Java | Moodle courses | Resource wiki | About ]

Object serialization

SL Mastery aspect:

  • File i/o
  • Objects as data records

 

We've simplified it a bit so as to let you have more fun developing other fields, validation techniques and so on - we're nice like that.

What HAS been added, astute students will note, is the reference to the Serializable interface.

VideoTape.java source code

We can't show examples of these applications in a web page, you will have to download the source, import into your IDE to compile and run them.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

All this is stuff you have seen before.

 

 

 

 

 

 

New lines >>>>>>>

 

 

 

 

 

 

 

New lines >>>>>>>

 

 

 

 

 

 

 

 

New method >>>>>>>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

New method >>>>>>>

 

Open a data file and read the records into the array (in one go - remember that an array is an object too)

The array may not have been full of records when saved.

last points to the last record in the array.

Everything OK, set the pointers as before.

 

 

There might not be any records at all.

Deal with file problems.

 

 

 

Applications start with main methods.

Main processing method, as ever.

More buttons could be added here - edit record , delete record , save, quit .

We've moved the operations into separate methods to simplify the processing.

Same process as before.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

These two methods are the same.

I know, I know, you've seen all this before; tell you what I'll leave them out of the next example.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Phew! Notice how the examples are getting longer? Your code development will go easier when you do the design first and break the programming task down into smaller methods.

 

This example includes all the techniques that SL students will need to complete a dossier. However, there is much more to completing a dossier than just the coding.

 

In addition, other techniques such as sorting and searching can be added to a dossier when appropriate.

On this page: [ VideoTape Class | VideoCollection Application ]

This example continues from the VideoTape Class example we introduced in the section on records .

The Class structure is as follows:

public class VideoTape implements java.io.Serializable
{
   // data members
   private String title;
   private int length;
   private boolean lent;

   // Constructors
   public VideoTape()
   {
     super();
   }
   // Even though these are technically overlaoded, this is trivial as an    // example of polymorphism.
   public VideoTape( String title, int length, boolean lent, char type )
   {
     this(); // call first constructor
     setTitle( title );
     setLength( length );
     setLent( lent );
   }
   // trivial as examples of methods with parameters and return values
   // mutator methods, could include data validation
   public void setTitle( String title ) { this.title = title; }
   public void setLength( int length ) { this.length = length; }
   public void setLent( boolean lent ) { this.lent = lent; }
   // accessor methods
   public String getTitle() { return this.title; }
   public int getLength() { return this.length; }
   public boolean isLent() { return this.lent; }
}

Back to top

VideoTapeCollection Application

The Application is similar to the Applet we saw before. However, Applets cannot write to the local file system so we use a GUI Application that has a main Class. A text-based console application would probably do as well and you can see an example on the JETS pages .


import java.awt.*;
import java.awt.event.*;
import java.io.*;

/**
* The initial VideoTape Application using ObjectStreams to save data
*
* @author Mr J
* @version 20040309
*/

public class VideoTapeCollection extends Frame implements ActionListener
{
   // display fields for record data
   private TextField vtTitle = new TextField(25);
   private TextField vtLength = new TextField(6);
   private Checkbox vtLent = new Checkbox();

  // labels for field data
   private Label fdTitle = new Label("Video title:", Label.RIGHT);
   private Label fdLength = new Label("Length (min):", Label.RIGHT);
   private Label fdLent = new Label("Lent:", Label.RIGHT);

  // control buttons
   private Button add = new Button("add tape");
   private Button next = new Button("next");
   private Button prev = new Button("previous");

  // system messages display
   private Label messages = new Label("System messages will appear here");

  // Set up an array to hold the tape collection
   private static final int MAX_TAPES = 10;
   VideoTape[] collection = new VideoTape[MAX_TAPES];
   private int last = -1; // pointer to last record in collection
   private int current = -1; // pointer to record in display

  // Filename is fixed
   static final String FILENAME = "videos.dat";

   /**
   * Add objects to the Frame using the constructor
   */

   public VideoTapeCollection()
   {
     makeDisplay();

     // window listener checks for Window Close button being clicked
     addWindowListener ( new WindowAdapter()
     {
       public void windowClosing(WindowEvent e)
       {
        // write the array contents to the file
        try
         {
           ObjectOutputStream out
                   = new ObjectOutputStream(new FileOutputStream(FILENAME));
           out.writeObject(collection);
           out.close();
         }
         catch(Exception ioe)
         {
           System.exit(1);
         }
           System.exit(0);
         }
     } );

     // Set up the application frame and make it visible
     setSize(400, 170);
     setTitle("Video Tape Collection Application");
     setVisible(true);

     // load any existing data records
     loadRecords();
  }
   /**
   * Create a display from Panels added to the Frame
   */

   public void makeDisplay()
   {
     Panel recordPanel = new Panel();
     recordPanel.setLayout( new GridLayout(3, 2, 10, 10) );
     recordPanel.add(fdTitle);
     recordPanel.add(vtTitle);
     recordPanel.add(fdLength);
     recordPanel.add(vtLength);
     recordPanel.add(fdLent);
     recordPanel.add(vtLent);

     Panel buttonPanel = new Panel();
     buttonPanel.setLayout( new GridLayout(3, 1, 10, 10) );
     buttonPanel.add(add);
     buttonPanel.add(prev);
     buttonPanel.add(next);

     // set up frame details
     setLayout( new BorderLayout() );
     add(recordPanel, BorderLayout.CENTER);
     add(buttonPanel, BorderLayout.EAST);
     add(messages, BorderLayout.SOUTH);

     // Causes button presses to be detected
     add.addActionListener(this);
     prev.addActionListener(this);
     next.addActionListener(this);
   }
   /**
   * Attempt to open the data file and load the records into the array
   */

   public void loadRecords()
   {
     try
     {
       ObjectInputStream in
                    = new ObjectInputStream(new FileInputStream(FILENAME));
       collection = (VideoTape[]) in.readObject();
       in.close();
       // find the number of non-null entries in the array
       int p = 0;
       while ( (p < MAX_TAPES) && (collection[p] != null) )
       {
         p = p + 1;
       }
       last = p - 1;

      if ( last != -1 )
       {
         current = 0;
         setDisplay(current);
         messages.setText("File opened successfully " + (last + 1)
                                                      + " records");
       }
       else
       {
         clearDisplay();
         messages.setText("Data file is empty");
       }
     }
     catch (Exception io)
     {
       messages.setText("Error in file initialization: " + io.getMessage());
     }
   }
   /**
   * The main method initialises the application
   */

   public static void main(String[] args)
   {
     VideoTapeCollection theCollection = new VideoTapeCollection();
   }
   /**
   * When an event occurs on an object with an ActionListener attached, this
   * method is carried out.
   *
   * @param e carries details about the event that occurred
   */

   public void actionPerformed(ActionEvent e)
   {
     if (e.getSource() == add)
     {
       addTape();
     }
     else if (e.getSource() == next)
     {
       nextTape();
     }
     else if (e.getSource() == prev)
     {
       previousTape();
     }
   }
   /**
   * collect tape details and create new tape
   *
   * @return a VideoTape object - null if details are invalid
   */

   private VideoTape getTapeDetails()
   {
     try
     {
       String title = vtTitle.getText();
       int length = Integer.parseInt(vtLength.getText());
       boolean lent = vtLent.getState();

       if ( (title.length() == 0) || (length <= 0) )
       {
         return null;
       }
       return new VideoTape(title, length, lent);
     }
     catch(Exception e)
     {
       return null;
     }
   }
   /**
   * display tape details
   *
   * @param the current VideoTape object
   */

   private void setDisplay(int current)
   {
     vtTitle.setText(collection[current].getTitle());
     vtLength.setText("" + collection[current].getLength());
     vtLent.setState(collection[current].isLent());
   }
   /**
   * clear record display panel
   */

   private void clearDisplay()
   {
     vtTitle.setText("");
     vtLength.setText("");
     vtLent.setState(false);
   }
   /**
   * adds a new tape to the collection - if there is space
   */

   private void addTape()
   {
     VideoTape theTape = getTapeDetails();
     if (theTape != null)
     {
       last = last + 1;
       if (last == MAX_TAPES)
       {
         messages.setText("No more space to store tapes");
         last = last - 1;
       }
       else
       {
         collection[last] = theTape;
         current = last;
         messages.setText("tape added");
         clearDisplay();
       }
     }
     else
     {
       messages.setText("Invalid tape details");
     }
   }
   /**
   * Moves to next tape,if there is one
   */

   public void nextTape()
   {
     if (current < last)
     {
       current = current + 1;
       setDisplay(current);
       messages.setText("At tape " + (current + 1) + " of " + (last + 1));
     }
     else
     {
       messages.setText("At last record");
       setDisplay(current);
     }
   }
   /**
   * Moves to the previous tape,if there is one
   */

   public void previousTape()
   {
     if (current > 0)
     {
       current = current - 1;
       setDisplay(current);
       messages.setText("At tape " + (current + 1) + " of " + (last+1));
     }
     else
     {
       messages.setText("At first record");
       setDisplay(current);
     }
   }
}

Back to top

Exercise

Editing a record should be fairly easy, add a button that allows you to collect new details from the display and put it into the array at the current position.

Deleting a record is relatively complicated, I'd be inclined to leave it for now ;-)

Saving would best be done by moving the code inside the windowClosing() method into its own saveRecords method. This can then be called from windowClosing and a new save Button - a good example of method re-use.

Related: [ Java home | Previous: Files home | Next: RAF Files]

A really simple approach. Allows the reading and writing of an entire array of object instances.



For a comparison and example of Applications vs Applets see the page applications.html

Other examples can be found in the book Computer Science, Java Enabled from::

http://www.ibid.com.au/

 


 
The site is partly financed by advertising revenue, partly by online teaching activities and partly by donations. If you or your organisation feel these resouces have been useful to you, please consider a donation, $9.95 is suggested. Please report any issues with the site, such as broken links, via the feedback page, thanks.

Questions or problems related to this web site should be addressed to Richard Jones who asserts his right to be identified as the author and owner of these materials - unless otherwise indicated. Please feel free to use the material presented here and to create links to it for non-commercial purposes; an acknowledgement of the source is required by the Creative Commons licence. Use of materials from this site is conditional upon your having read the additional terms of use on the about page and the Creative Commons Licence. View privacy policy.

Creative Commons License


This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License. © 2001 - 2009 Richard Jones, PO BOX 246, Cambridge, New Zealand;
This page was last modified: May 31, 2009