Results 1 to 5 of 5
  1. #1
    Allexxy is offline Member
    Join Date
    Feb 2012
    Location
    Lagos, Nigeria
    Posts
    7
    Rep Power
    0

    Question 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: (-:

  2. #2
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    11,450
    Rep Power
    19

    Default 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.

  3. #3
    Allexxy is offline Member
    Join Date
    Feb 2012
    Location
    Lagos, Nigeria
    Posts
    7
    Rep Power
    0

    Default 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

    Java 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;
            }
    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 code

    Java 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();
    		}
    	}
    The controller class is how the user interacts with the gui, so to do add, in the class I have the following

    Java 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);
    				
        		}
        	}
        	
        }
    To give you a picture...here's how the process looks like when adding

    Problem with Object serialization/deserialization to GUI-addexample.png

    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!

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    11,450
    Rep Power
    19

    Default 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.

  5. #5
    Allexxy is offline Member
    Join Date
    Feb 2012
    Location
    Lagos, Nigeria
    Posts
    7
    Rep Power
    0

    Default 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

  1. setTooltipText broken after serialization/deserialization
    By tylerdurden in forum AWT / Swing
    Replies: 7
    Last Post: 03-04-2011, 12:45 AM
  2. Singleton serialization / deserialization
    By DerekRaimann in forum New To Java
    Replies: 4
    Last Post: 02-28-2011, 01:38 AM
  3. Enum singleton serialization and deserialization
    By bassfero in forum Advanced Java
    Replies: 16
    Last Post: 09-08-2010, 01:37 PM
  4. Serialization/Deserialization Error
    By andrepezzo in forum Advanced Java
    Replies: 2
    Last Post: 12-16-2008, 05:36 PM
  5. Serialization/Deserialization Error
    By andrepezzo in forum Networking
    Replies: 0
    Last Post: 12-16-2008, 04:21 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •