This demonstration program illustrates the use of object
serialization to send and receive objects via streams. This
means that all of the data that makes up an object is extracted
and sent serially to a file or other destination. Conversely, the
data can be received and used to rebuild the histogram by creating
an instance of the object and placing the data values into their
fields.
Serialization is an important aspect of network communications
with Java as we will see in Part II. Objects need to be taken apart,
sent over the network, and rebuilt at the destination site. Making
objects persistent is also an important aspect of object
oriented databases.
For a class to work with the ObjectOutputStream
and ObjectInputStream
classes, it must implement the Serializable
interface. This interface has no methods and only serves as a tag
to indicate that this class is allowed to be serialized.
The program HistIOSerialApp
shown below uses the object serialization techniques to stream a
Histogram
object to the file. The method
writeSerialFile() in the HistIOSerialTools
class wraps a ObjectOutputStream
around a FileOutputStream
object, which in turn streams to a file. The writeObject()
method sends the Histogram
object onto the stream to the file.
ObjectOutputStream
out = new ObjectOutputStream (new FileOutputStream (fFile));
out.writeObject (fHistogram);
out.flush ();
out.close ();
Similarly, to read a histogram from a file we can use the method
readSerialFile(), which wraps an ObjectInputStream
around a FileInputStream
object, which in turn streams from a file. The readObject()
method obtains the Histogram
object from the file:
FileInputStream
in = new FileInputStream (fFile);
ObjectInputStream oin =
new ObjectInputStream (in);
Histogram hist = (Histogram)
(oin.readObject ());
oin.close ();
This approach offers an elegant, simple approach to saving and
retrieving objects. It has some overhead with regard to managing
the bookkeeping for the data values (i.e. knowing what data goes
where) and is somewhat slow. Random access to a file full of objects
is not provided for.
HistIOSerialApp
Application Frame
HistIOSerialApp.java
-
This application follows closely to the previous HistIOApp
example except that it uses the object serialization methods
in HistIOTools class to save and read back histogram files.
HistIOSerialTools.java
- contains the two static methods shown below.
The writeSerialFile(File
file, Histogram histogram) method writes a
Histogram object to a file with an OutputObjectStream.
The method readSerialFile(File
file) reads a histogram from such a file using the InputObjectStream.
Histogram.java
- For this demo we create a special version of Histogram
that is identical to the Chapter
6: Tech Histogram except that it implements the Serializable
interface. See below
+
Previous classes:
HstFilter.java
- JFileChooser uses this to list ".hst" type
files.
Chapter
6:Tech: HistPanel.java
Chapter
6:Tech: PlotPanel.java,
PlotFormat.java
|
/**
Special serializable version of Histogram. **/
public class Histogram implements java.io.Serializable
{
... rest same as the standard Histogram
class ...
} // class Histogram |
[HistIOSerialTools
is the same as HistIOTools
discussed in the previous section
except for the following two methods.]
/**
* Use a ObjectOutputStream wrapped
around a FileOutputStream,
* to write a Histogram (made
Serializable) to the given file.
*
* @param file File object for the
file to receive the histogram data.
**/
public static boolean writeSerialFile (File
file,
Histogram
histogram) {
try {
ObjectOutputStream out
=
new ObjectOutputStream
(new FileOutputStream (file));
out.writeObject (histogram);
out.flush ();
out.close ();
}
catch (IOException ioe) {
JOptionPane.showMessageDialog
(
null,
"Error
in writing data object!!\n\r"+ioe,
"Histogram
File Save Error",
JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
} // writeSerialFile
/**
* Use a ObjectInputStream
wrapped around a FileInputStream
* to read the Histogram
object (made Serializable
* from the given file.
*
* @param file File object from which
to locate file.
**/
public static Histogram readSerialFile (File
file) {
try {
FileInputStream in =
new FileInputStream (file);
ObjectInputStream oin
=
new ObjectInputStream (in);
Histogram hist = (Histogram)
(oin.readObject ());
oin.close ();
return hist;
}
catch (ClassNotFoundException
notex) {
JOptionPane.showMessageDialog
(
null,
"Error
in reading data!!\n\r"+notex,
"Histogram
File Read Error",
JOptionPane.ERROR_MESSAGE);
return null;
}
catch (IOException ioe)
{
JOptionPane.showMessageDialog
(
null,
"Error
in reading data!!\n\r"+ioe,
"Histogram
File Read Error",
JOptionPane.ERROR_MESSAGE);
return null;
}
} // readSerialFile
|
import
javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
/**
* Demonstrate streaming I/O by saving and
* reading in histograms.
**/
public class HistIOSerialApp extends JFrame
implements ActionListener{
JMenuItem fMenuOpen;
JMenuItem fMenuSave;
JMenuItem fMenuClose;
// Use the HistPanel JPanel subclass here
HistPanel fOutputPanel;
Histogram fHistogram;
int fNumDataPoints = 100;
// A text field for input strings
JTextField fTextField = null;
//Buttons
JButton fGoButton;
JButton fClearButton;
File fFile;
/**
* Pass a title to the frame via the
constructor
* argument.
**/
HistIOSerialApp (String title) {
super (title);
} // ctor
/**
* Create a User Interface with a HistPanel
to
* contain the Histogram object plus
buttons to
* fill and clear the histogram. A
text area allows
* for entry of the number of desired
histogram entries.
**/
public void init () {
Container content_pane = getContentPane
();
// Create a menubar for the frame
with File menu
makeMenuBar ();
// Now create components for the framed
area.
JPanel panel = new JPanel (new BorderLayout
());
// Create a histogram with Gaussian
distribution.
makeHist ();
// JPanel subclass here.
fOutputPanel = new HistPanel (fHistogram);
panel.add (fOutputPanel,"Center");
// Use a textfield for an input parameter.
fTextField =
new JTextField (Integer.toString
(fNumDataPoints), 10);
// If return hit after entering text,
the
// actionPerformed will be invoked.
fTextField.addActionListener (this);
fGoButton = new JButton ("Go");
fGoButton.addActionListener (this);
fClearButton = new JButton ("Clear");
fClearButton.addActionListener (this);
JPanel control_panel = new JPanel
();
control_panel.add (fTextField);
control_panel.add (fGoButton);
control_panel.add (fClearButton);
panel.add (control_panel,"South");
// Add text area with scrolling to
the content pane.
content_pane.add (panel);
setSize (400,400);
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
} // init
/** Create a menu bar with a File drop down menu.
**/
void makeMenuBar () {
// Use the helper method makeMenuItem
// for making the menu items and registering
// their listener.
JMenu m = new JMenu ("File");
m.add (fMenuOpen = makeMenuItem
("Open"));
m.add (fMenuSave = makeMenuItem
("Save"));
m.add (fMenuClose = makeMenuItem ("Quit"));
JMenuBar mb = new JMenuBar ();
mb.add (m);
setJMenuBar (mb);
} // makeMenuBar
/** Process the events from the buttons and menu.
**/
public void actionPerformed (ActionEvent e) {
boolean status = false;
Object source = e.getSource ();
// Fill the histogram when the go
button clicked or
// when "enter" hit after a number
entered into the
// textfield
if (source == fGoButton || source
== fTextField) {
String strNumDataPoints
= fTextField.getText ();
try {
fNumDataPoints
= Integer.parseInt (strNumDataPoints);
}
catch (NumberFormatException
ex) {
// Could open
an error dialog here but just
// display
a message on the browser status line.
System.out.println
("Bad input value");
return;
}
// Call the makeHist ()
method to add data to the histogram.
// If the first time,
it also creates the histogram.
makeHist ();
repaint ();
} else if (source == fClearButton)
{
fHistogram.clear ();
repaint ();
}
// Menu item "Open" for reading in
histogram files.
else if (source == fMenuOpen) {
// Get a file name with
the chooser
fFile = HistIOSerialTools.openFile
(this);
// Return if no file selected
if (fFile == null) return;
Histogram tmpHist = HistIOSerialTools.readSerialFile
(fFile);
if (tmpHist != null)
fHistogram
= tmpHist;
else {
JOptionPane.showMessageDialog
(
null,
"Error
opening file!", "File Open Error",
JOptionPane.ERROR_MESSAGE);
return;
}
// Update panel with new
histogram.
fOutputPanel.setHistogram
(fHistogram);
repaint ();
}
// Menu item Save for saving the current
histgram
// to a disk file.
else if (source == fMenuSave) {
// Get a file name with
the chooser
fFile = HistIOSerialTools.saveFile
(this, null);
// Return if no file selected
if (fFile == null) return;
// Save a file
status = HistIOSerialTools.writeSerialFile
(fFile,fHistogram);
if (!status)
JOptionPane.showMessageDialog
(
null,
"IO
error in saving file!!", "File Save Error",
JOptionPane.ERROR_MESSAGE);
} else if (source == fMenuClose) {
dispose ();
}
} // actionPerformed
/** Create a histogram and fill it with Gaussian
data. **/
void makeHist () {
// Create an instance of the Random
class for
// producing our random values.
java.util.Random r = new java.util.Random
();
// Them method nextGaussian in the
class Random produces
// a value centered at 0.0 and a standard
deviation
// of 1.0.
// Create an instance of our basic
histogram class.
// Make it wide enough enough to include
most of the
// gaussian values.
if (fHistogram == null)
fHistogram
= new Histogram ("Gaussian Distribution",
"random
values",
20,-3.0,3.0);
// Fill histogram with Gaussian distribution
for (int i=0; i < fNumDataPoints;
i++) {
double val
= r.nextGaussian ();
fHistogram.add
(val);
}
} // makeHist
/**
* This "helper method" makes a menu
item and then
* registers this object as a listener
to it.
*
* @param name menu item label.
**/
private JMenuItem makeMenuItem (String name) {
JMenuItem m = new JMenuItem (name);
m.addActionListener (this);
return m;
} // makeMenuItem
public static void main (String [] args) {
// Can pass frame title in command
line arguments
String title="HistIOSerialApp";
if (args.length != 0)
title = args[0];
HistIOSerialApp f = new HistIOSerialApp
(title);
f.init ();
f.setVisible (true);
} // main
} // class HistIOSerialApp |
References & Web Resources
Latest update: Feb.4.2006
|