Results 1 to 5 of 5
- 03-22-2012, 12:18 AM #1
Member
- Join Date
- Feb 2012
- Location
- Lagos, Nigeria
- Posts
- 7
- Rep Power
- 0
Problem with Object serialization/deserialization to GUI
Hi all,
I've got a problem with reading saved objects to the gui. Initially, the first set of person objects are added to an "Untitled" screen via 'ADD' button, and then saved to a file called "Addressbook.txt". Its read back to the screen, with no problems. I tried adding a new name to the now opened file. Its added to other persons on screen, then I saved it again. The program tells me its saved. But, reading it back, there's no update.
I've tried ByteArrayOutput stream. Also tried using ObjectOutput.reset(). I need to write the whole address book object in and out, and be able to append to the file its saved to.
Here's my code:
Java Code:public class FileSystem extends java.lang.Object{ /** * Constructor to enable creation of FileSystem */ public FileSystem() { } /** * Read a stored file * * @param file - the file specification for the file to read * @return the AddressBook object stored in the file * @throws java.io.IOException - if there is a problem reading the file * java.lang.ClassCastException - if the file does not contain an AddressBook * java.lang.ClassNotFoundException - if the file does not contain an AddressBook, * and the class it does contain is not found - this should never happen */ public AddressBook readFile( java.io.File file ) throws java.io.IOException, java.lang.ClassCastException, java.lang.ClassNotFoundException { AddressBook addressBook = new AddressBook(); file = addressBook.getFile(); // get the file of the address book to be read from ObjectInputStream obj_in = new ObjectInputStream( new BufferedInputStream ( new FileInputStream( file ))); synchronized ( addressBook ) { addressBook = ( AddressBook ) obj_in.readObject(); } System.out.println( "File " + file.getName() + " read." ); addressBook.printAll(); return addressBook; } /** * Save an address book to a file * * @param addressBook - the AddressBook to save * @param file - the file specification for the file to create * @throws java.io.IOException - if there is a problem writing to the file */ public void saveFile( AddressBook addressBook, java.io.File file ) { try { file = addressBook.getFile(); // get the file of the address book to be saved to boolean append = true; //write to the end of the file rather than the beginning ObjectOutputStream obj_out = new ObjectOutputStream( new BufferedOutputStream ( new FileOutputStream( file, append ))); synchronized ( addressBook ) { obj_out.writeObject( addressBook ); obj_out.flush(); // Empty output buffer obj_out.reset(); obj_out.close(); } System.out.println("Address book saved to file: " + file.getName()); } catch ( IOException e) { e.printStackTrace(); System.out.println("Error saving to " + file.getName() + ". Address book not saved.\n" + e); } } }
Please help...thanks in advance: (-:
- 03-22-2012, 09:43 AM #2
Moderator
- Join Date
- Apr 2009
- Posts
- 10,481
- Rep Power
- 16
Re: Problem with Object serialization/deserialization to GUI
How are you adding an address to the AddressBook?
That seems to be the key.
At the moment you are writing the entire AddressBook to the end of the file each time, not just any new entry, in which case you may as well skip the append flag.
And, are you aure you need to synchronise on the address book?Please do not ask for code as refusal often offends.
- 03-22-2012, 02:14 PM #3
Member
- Join Date
- Feb 2012
- Location
- Lagos, Nigeria
- Posts
- 7
- Rep Power
- 0
Re: Problem with Object serialization/deserialization to GUI
Hello Tolls, thanks for replying...

O.k...Let me explain that my program uses MVC design pattern, so I have a model which is called AddressBook.java, a controller called AddressBookController, a view called AddressBookGUI, a Person class, used by the AddressBook class. In addition, a FileSystem (as above) that gets some file info from the model, then a main application which ccontrols everything called AddessBookApplication.
When the main is run, the GUI class gets its information from the AddressBook class, so to answer your first question...I'll take you through the process. In my AddressBook class, I have the following methods for adding and returning info
In the GUI class, leaving out the frame creation stuff, I have a mini method that gets info from the AddressBook class and puts it into an instance of a NameListModel which extends AbstactListModel like so. Without confusing you, here's the codeJava Code:/** * Create a new, empty address book */ public AddressBook( ) { // New address book, therefore save is enabled changedSinceLastSave = true; // Here, a Vector of type Person object is created and // the resulting handle is immediately assigned to the global List collection = new Vector < Person > (); } /** * Add a new person to the collection * * @param addElement person to collection */ public void addPerson( String firstName, String lastName, String address, String city, String state, String zip, String phone ) { // Create a new person with the following details person = new Person( firstName, lastName, address, city, state, zip, phone ); // Then add person to end of collection of persons collection.add(person); } /** * @return numberOfPersons in the address book */ public int getNumberOfPersons() { int numberOfPersons = 0; numberOfPersons = collection.size(); return numberOfPersons; } /** * Get the person's full name * * @param getFirstName at position index * @param getLastName at position index * @return the person's full name at position index */ public String getFullNameOfPerson( int index ) { String fullNameOfPerson = collection.get(index).getFirstName() + " " + collection.get(index).getLastName(); return fullNameOfPerson; } /** * Provide the rest of the current information about a person * * @return an array of Strings, * each containing one piece of stored information about this person. * The person's name is _not_ included, since this is not changeable */ public String[ ] getOtherPersonInformation( int index ) { String address = collection.get(index).getAddress(); String city = collection.get(index).getCity(); String state = collection.get(index).getState(); String zip = collection.get(index).getZip(); String phone = collection.get(index).getPhone(); String[] otherPersonInformation = { address, city, state, zip, phone }; return otherPersonInformation; } /** * Print the collection of persons in order */ public void printAll( ) { // Iterates over the person objects in this collection in the proper sequence. Iterator <Person> it = collection.iterator(); if(collection.isEmpty()) { return; } else while( it.hasNext() ) System.out.println( it.next() ); return; } /** * Get the File this address book was most recently read from or saved to * * @return the file of the address book was read from */ public File getFile( ) { setFile( file ); return this.file; } /** * Set the File this address book was most recently read from or saved to * * @param file - the file just used to read or save this object */ public void setFile( File file ) { file = new File( "Addressbook.txt" ); this.file = file; }
The controller class is how the user interacts with the gui, so to do add, in the class I have the followingJava Code:// The displayed list of names gets its information from the // address book nameListModel = new NameListModel(); // The nameListModel and saveItem objects must exist before this is done; // but this must be done before the nameList is created setAddressBook(addressBook); // Create and add components for the main window nameList = new JList(nameListModel); //blah blah blah blah //... //... //... // then action listener for adding addButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { controller.doAdd(AddressBookGUI.this); int index = getAddressBook().getNumberOfPersons() - 1; nameListModel.addElement(index); // not included in original code // This will ensure that the person just added is visible in list nameList.ensureIndexIsVisible(index); } }); openItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { if (getAddressBook().getChangedSinceLastSave()) controller.doOfferSaveChanges(AddressBookGUI.this); controller.doOpen(AddressBookGUI.this); } // Error with original IOException & InterruptedException catch clauses: Unreachable catch block for IOException. This exception is never thrown from the try statement body. Therefore removed catch(SecurityException exception) { // Thrown if security manager disallows the operation - // will always happen in an applet reportError("Operation disallowed: " + exception); } catch(Exception exception) { // Any other case means the file did not contain an // address book reportError("This file did not contain an address book"); } } }); saveItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { controller.doSave(AddressBookGUI.this); } // Error with original IOException & InterruptedException catch clauses: Unreachable catch block for IOException. This exception is never thrown from the try statement body. Therefore removed catch(SecurityException exception) { // Thrown if security manager disallows the operation - // will always happen in an applet reportError("Operation disallowed: " + exception); } } }); saveAsItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { controller.doSaveAs(AddressBookGUI.this); } // Error with original IOException & InterruptedException catch clauses: Unreachable catch block for IOException. This exception is never thrown from the try statement body. Therefore removed catch(SecurityException exception) { // Thrown if security manager disallows the operation - // will always happen in an applet reportError("Operation disallowed: " + exception); } } }); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { try { if (getAddressBook().getChangedSinceLastSave()) controller.doOfferSaveChanges(AddressBookGUI.this); dispose(); if (Frame.getFrames().length == 0) AddressBookApplication.quitApplication(); }// Error with original IOException & InterruptedException catch clauses: Unreachable catch block for IOException. This exception is never thrown from the try statement body. Therefore removed catch(SecurityException exception) { // Thrown if security manager disallows the operation - // will always happen in an applet reportError("Operation disallowed: " + exception); } } }); // The following is adapted from an example in the documentation // for class JList. It invokes the controller's doEdit method // if the user double clicks a name. nameList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { int index = nameList.locationToIndex(e.getPoint()); controller.doEdit(AddressBookGUI.this, index); } } }); pack(); } /** Accessor for the address book this GUI displays * * @return the current address book for this GUI */ public AddressBook getAddressBook() { return addressBook; } /** Mutator to change the address book this GUI displays * * @param addressBook the new address book for this GUI */ public void setAddressBook(AddressBook addressBook) { if (this.addressBook != null) this.addressBook.deleteObserver(this); this.addressBook = addressBook; addressBook.addObserver(this); update(addressBook, null); } /** Report an error to the user * * @param message the message to display */ public void reportError(String message) { JOptionPane.showMessageDialog(this, message, "Error message", JOptionPane.ERROR_MESSAGE); } /** Method required by the Observer interface - update the display * in response to any change in the address book */ public void update(Observable o, Object arg) { if (o == addressBook) { setTitle(addressBook.getTitle()); saveItem.setEnabled(addressBook.getChangedSinceLastSave()); nameListModel.contentsChanged(); } } // GUI components and menu items private NameListModel nameListModel; @SuppressWarnings("rawtypes") private JList nameList; private JButton addButton, editButton, deleteButton, sortByNameButton, sortByZipButton; private JMenuItem newItem, openItem, saveItem, saveAsItem, printItem, quitItem; private JMenuItem findItem, findAgainItem; // included, not part of original menu options // The controller that performs operations in response to user gestures @SuppressWarnings("unused") private AddressBookController controller; // The address book this GUI displays / operates on private AddressBook addressBook; /** * Class used for the model for the list of persons in the address book */ private class NameListModel extends AbstractListModel<Object> // update -- IDE recommended parametizing { /** * Auto-generated serial ID used during deserialization to verify that the sender and receiver of a * serialized object have loaded classes for that object that are compatible * with respect to serialization */ private static final long serialVersionUID = 1L; /** * Report that the contents of the list have changed */ void contentsChanged() { super.fireContentsChanged(this, 0, 0); } /** * Report that an element has been removed from the index */ void removeElement(int index) // (Included, not part of original code) { super.fireIntervalRemoved(this, index, index); } /** * Report that an element has been added to the index */ void addElement(int index) //(Included, not part of original code) { super.fireIntervalAdded(this, index, index); } // Implementation of abstract methods of the base class /** Get the person's complete details at position index * * @ return full name of person and other personal information */ public Object getElementAt(int index) { // The original code just returned the person's full name // Inpiration for modification was from // http://www.apl.jhu.edu/~hall/java/Swing-Tutorial/Swing-Tutorial-JList.html - JavaLocationListModel.java // I was not sure how to loop through the address details in one fell swoop // Also, I discovered tab (\t) does not work in GUI; 'space' has to be given a variable and still has limits in how much String gap = " "; String comma = ", "; return getAddressBook().getFullNameOfPerson(index) + gap + getAddressBook().getOtherPersonInformation(index)[0] + comma + getAddressBook().getOtherPersonInformation(index)[1] + comma + getAddressBook().getOtherPersonInformation(index)[2] + comma + getAddressBook().getOtherPersonInformation(index)[3] + comma + getAddressBook().getOtherPersonInformation(index)[4]; } /** Get the size of the Address book * * @return number of persons in the address book */ public int getSize() { return getAddressBook().getNumberOfPersons(); } }
To give you a picture...here's how the process looks like when addingJava Code:/** * Constructor to create object of FileSystem to interact with the file system */ public AddressBookController( FileSystem fileSystem ) { fileSystem = new FileSystem(); } /** * Do the Add a Person Use Case. */ public void doAdd( AddressBookGUI gui ) { // The title of this dialog frame String title_Of_Dialog = ( "New Person" ); // Create fields for user input String dialog_prompts[] = { "Enter First name", "Enter Last name", "Enter Address", "Enter City", "Enter State", "Enter Zip code", "Enter Phone" }; // Prompt for Person details String dialog [] = MultiInputPane.showMultiInputDialog( gui, dialog_prompts, title_Of_Dialog ); // Store dialog_prompts details of the user String firstName = dialog [0]; String lastName = dialog [1]; String address = dialog [2]; String city = dialog [3]; String state = dialog [4]; String zip = dialog [5]; String phone = dialog [6]; // Show added person in main window gui.getAddressBook().addPerson( firstName, lastName, address, city, state, zip, phone ); } /** * Do the Save Address Book As Use Case. * * @param createNewFile() - create a new file * @param saveFile - save the new file */ public void doSaveAs( AddressBookGUI gui ) { /* * Prompt for a file name and save it to the File system * Save the address book if file to which it was saved to before is found */ FileSystem fileSystem = new FileSystem(); FileDialog d = new FileDialog( gui, "Save As...", FileDialog.SAVE ); d.setFile("*.txt"); // Filename filter -- must have extension .txt d.setDirectory("."); // Current directory d.setVisible( true );// make dialog visible String fileName = d.getFile(); // name of file to open String dirName = d.getDirectory(); // directory to open String filePath = dirName + fileName; // C:\\..+ filename // Create user's new file File file = new File( filePath ); if( fileName != null ) { try { file.createNewFile(); } catch (IOException e) { // Report file creation error e.printStackTrace(); gui.reportError("Not able to create new file " + file.getName() + " :" + e); } try { gui.setTitle(fileName); fileSystem.saveFile( gui.getAddressBook(), file); } catch (Exception e) { // Report file saving error gui.reportError("Error Saving to " + file.getName() + " : " + e); } } }

Hope this kind of explains it
As for the synchonizing...it was to try to solve a problem with GUI acknowledging address book as a file and telling me its been modified when I make a change to it. But as of now...it tells me its being modified all the tie..even after I have just saved it...that' another problem. But I do think its related to this problem.
Thanks again!
- 03-22-2012, 03:30 PM #4
Moderator
- Join Date
- Apr 2009
- Posts
- 10,481
- Rep Power
- 16
Re: Problem with Object serialization/deserialization to GUI
There's rather a lot there.
So all I can really do is spot curiosities.
First thing I see is in the saveFile() method, you take in an addressBook and a File.
Yet in the code you ignore the file supplied completely, in favour of whatever is already in the addressBook.
For the always allowing it to save, changedSinceLastSave seems to always be true.
Id it transient? If not then I don't see how it will ever become false?Please do not ask for code as refusal often offends.
- 03-22-2012, 04:26 PM #5
Member
- Join Date
- Feb 2012
- Location
- Lagos, Nigeria
- Posts
- 7
- Rep Power
- 0
Re: Problem with Object serialization/deserialization to GUI
Thanks Tolls...
I discovered that when you serialize the same object reference (i.e AdddresBook addressbook = new AddressBook(), over and over again, the output stream will return the same instance over and over again.
So, a friend suggested using use the writeUnshared() and reset() calls on each send. It works like a charm!!!!!
But your points are valid, especially on setting changedSinceLastSave transient
Thank you so much for your input
Similar Threads
-
setTooltipText broken after serialization/deserialization
By tylerdurden in forum AWT / SwingReplies: 7Last Post: 03-04-2011, 12:45 AM -
Singleton serialization / deserialization
By DerekRaimann in forum New To JavaReplies: 4Last Post: 02-28-2011, 01:38 AM -
Enum singleton serialization and deserialization
By bassfero in forum Advanced JavaReplies: 16Last Post: 09-08-2010, 01:37 PM -
Serialization/Deserialization Error
By andrepezzo in forum Advanced JavaReplies: 2Last Post: 12-16-2008, 05:36 PM -
Serialization/Deserialization Error
By andrepezzo in forum NetworkingReplies: 0Last Post: 12-16-2008, 04:21 PM


LinkBack URL
About LinkBacks
Reply With Quote
Bookmarks