0

EDIT

I've cleaned up the .equals method for string equality and changed the ContactsCollection initialization to:

public static ArrayList<Contact> contactList = new ArrayList<Contact>();

I've also changed the action performed method in hopes that 'Display contacts' would show more than one contact.

    if (contactInput.equals("Display contacts"))
    {
        ContactsCollection.read();
        for (int i = 0; i < contactList.size(); i++)
        {
            contact = (Contact)contactList.get(i);
            for (int j =0; j < contactList.size(); j++)
            {
                textArea.append(contact.getName() + "," + contact.getNumber() + "\n");
            }
        }
    }

Ultimately the .dat file is written but does not contain any data that is added through the GUI.

END EDIT

I am writing a mock cellphone GUI that acts as a very basic contacts manager. There are several other classes that do not deal with the ArrayList that are working as intended.

When attempting to add a contact to the file I receive a null pointer exception at line 13 of the ContactsCollection class:

for (int i = 0; i < contactList.size(); i++)

and line 93 of the Contacts (GUI) class:

contactList.add(contact);

I have a feeling that I did something wrong when coding the Contacts and ContactsCollection classes. I'm hoping the program to run as follows: The user clicks add contact and enters the information which becomes an object Contact and is added to the contactList ArrayList and written (serialized) to a file "contactList.dat". When the user clicks display contacts the file is read in and each contact is displayed in GUI.

I think that there are several issues with the way I set up the ArrayList, but I think I'm very close to having the program run as I had hoped. Any help is greatly appreciated!

Contacts class:

import java.util.*;
import java.io.*;

public class Contact implements Serializable
{
public static final long serialVersionUID = 42L;
public String name, number;

Contact()
{
    name = "No name";
    number = "No number";
}

Contact (String theName, String theNumber)
{
    this.name = theName;
    this.number = theNumber;
}

public void setName(String aName)
{
    this.name = aName;
}

public void setNumber(String aNumber)
{
    this.number =aNumber;
}

public String getName()
{
    return name;
}

public String getNumber()
{
    return number;
}

public String toString()
{
    return name + ": " + number;
}

public boolean equals(Contact other)
{
   if (name.equals(other.getName()) && number.equals(other.getNumber()))
   {
      return(true);
   }
   else
   {
      return(false);
   }
}   
}

Contacts Collection class

import java.io.*;
import java.util.*;

class ContactsCollection
{
public static ArrayList<Contact> contactList;

public static void write()
{
    try 
    {
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("contactList.dat"));
        for (int i = 0; i < contactList.size(); i++)
        {
            out.writeObject(contactList.get(i));
        }
        out.close();
    } 
    catch(IOException e)
    {
        e.printStackTrace();
    }
}

public static void read()
{
contactList = new ArrayList<Contact>();
try
{
    ObjectInputStream in = new ObjectInputStream(new FileInputStream("contactList.dat"));
    Contact temp;
    while (in.available()!=0)
    {
        temp = (Contact)in.readObject();
        contactList.add(temp);
    }
    in.close();
}
catch(FileNotFoundException e)
{
    e.printStackTrace();
}
catch(IOException e)
{
    e.printStackTrace();
}
catch(ClassNotFoundException e)
{
    e.printStackTrace();
}       

}
}

Contacts (GUI) class

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.Timer;
import java.util.*;

class Contacts extends JFrame implements ActionListener, WindowListener
{
public static final int WIDTH = 400;
    public static final int HEIGHT = 600;
    public static final int SMALL_WIDTH = 200;
    public static final int SMALL_HEIGHT = 100;

private static final Dimension stdBtn = new Dimension(150, 50);    

    JPanel centerPanel, northPanel, southPanel;
ImageIcon icon;
JLabel picture;
JButton addContact, displayContacts;
JScrollPane scroll;
JTextArea textArea;
Clock clock;
Background background;
Contact contact;
ArrayList<Contact> contactList;


public Contacts()
{
    super("Contacts");
    this.setLayout(new BorderLayout());
    this.setSize(WIDTH, HEIGHT);
    this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    addWindowListener(this);
    this.setLocationRelativeTo(null);

    centerPanel = new JPanel();
    northPanel = new JPanel();
    southPanel = new JPanel();

    centerPanel.setBackground(Color.BLACK);
    southPanel.setBackground(Color.BLACK);      

    clock = new Clock();
    northPanel.add(clock);

    icon = new ImageIcon("ContactsBackground.jpg");
    picture = new JLabel(icon);
    centerPanel.add(picture);

    textArea = new JTextArea("", 10, 30);
    textArea.setEditable(false);
    JScrollPane scroll = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);    
    centerPanel.add(scroll);    

    JButton displayContacts = new JButton("Display contacts");
    displayContacts.addActionListener(this);
    southPanel.add(displayContacts);

    JButton addContact = new JButton("Add contact");
    addContact.addActionListener(this);
    southPanel.add(addContact);

    this.add(northPanel, BorderLayout.NORTH);
    this.add(centerPanel, BorderLayout.CENTER);
    this.add(southPanel, BorderLayout.SOUTH);       

    setResizable(false);        
}

public void actionPerformed(ActionEvent e)
{
    contactList = new ArrayList<Contact>();
    JButton source = (JButton)e.getSource();
    String contactInput = source.getText();

    if (contactInput == "Display contacts")
    {
        ContactsCollection.read();
        for (int i = 0; i < contactList.size(); i++)
        {
            contact = (Contact)contactList.get(i);
            textArea.setText(contact.getName() + "," + contact.getNumber() + "\n");
        }
    }
    if (contactInput == "Add contact")
    {
        String name = JOptionPane.showInputDialog(null, "Enter Name");
        String number = JOptionPane.showInputDialog(null, "Enter Number");
        contact = new Contact(name, number);
        contactList.add(contact);
        ContactsCollection.write();
    }
}

public void windowOpened(WindowEvent e)
{}

public void windowClosing(WindowEvent e)
{
    this.setVisible(false);
    background = new Background();
    background.setVisible(true);        
}

public void windowClosed(WindowEvent e)
{}

public void windowIconified(WindowEvent e)
{}

public void windowDeiconified(WindowEvent e)
{}

public void windowActivated(WindowEvent e)
{}

public void windowDeactivated(WindowEvent e)
{}      
}
user2380220
  • 29
  • 3
  • 8

1 Answers1

3

Change

public static ArrayList<Contact> contactList;

to

public static ArrayList<Contact> contactList = new ArrayList<>();

in your version contactList is null because you never initialize it and in the write() method you are trying to call size() on it.


Also, there are some serious flaws in your GUI class (in the actionPerformed() method), read this question to fix them: How do I compare strings in Java?


Also remember that textArea.setText(...) will set the complete text for the textArea, so because this is in a loop in your code, the textArea will contain the output of the last iteration of that loop only. In your case it will be only the last contact.

Community
  • 1
  • 1
jlordo
  • 37,490
  • 6
  • 58
  • 83
  • I've updated the code at the top to show the changes I made. At this point it writes the .dat file but only Ԁ appears in the file. – user2380220 May 15 '13 at 06:11
  • @user2380220: You will still only see the last contact in your textarea. Instead of having `contactList` as a class member, use it as an instance attribute to serialize it. – jlordo May 15 '13 at 06:32
  • I changed the setText so that it appends. I'm not sure how to go about changing contactList from a class member to an instance attribute/variable. I'm not able to call contactList.read() or contactList.write(), I have to use ContactsCollection.read()/.write(). – user2380220 May 15 '13 at 06:46
  • @user2380220: Now, if you have `n` contacts, you will show every contact `n` times. You have to get rid of all of the the `static` keywords and in `ContactsCollection` and adjust your code to use an instance of it. – jlordo May 15 '13 at 06:48
  • I removed the static keyword from the ContactsCollection methods and ArrayList instantiation. Now I receive an error stating that non-static methods cannot be referenced from a static context. I thought by including ArrayList contactList; as an instance variable in the Contact class I was creating an instance of it? – user2380220 May 15 '13 at 06:59
  • @user2380220: You need to fix those errors. How do remove this kind of error `non-static methods cannot be referenced from a static context` is asked here multiple times daily. Do a search... – jlordo May 15 '13 at 07:02
  • I really appreciate you taking the time to help me with this. I understand that ContactsCollection contactList = new ContactsCollection(); would make an instance of the object ContactsCollection in the Contacts class. If I try to use that it won't let me use the ArrayList methods. – user2380220 May 15 '13 at 07:14
  • @user2380220: sure it does. You have to write `contactList.` directly before calling the instance methods... – jlordo May 15 '13 at 07:15
  • Can you explain what you mean by writing it directly? – user2380220 May 15 '13 at 07:23
  • @user2380220: After you have written `ContactsCollection contactList = new ContactsCollection();` you can write `contactList.read();`, `contactList.write();` and so forth. You also need a reference to `contactList` in your calling class. – jlordo May 15 '13 at 07:26
  • I'm unable to use the ArrayList methods such as contactList.add() and contactList.get(). contactList.read() and contactList.write() aren't causing any compiler errors. As far as a reference to contactList in the calling class, Contacts(GUI) is that class that calls all of the methods and that is where I added ContactsCollection contactList = new ContactsCollection();. I really appreciate your help with this. If you are able to give me more time than you already have I can add the current code to the original post. You've been helping me a lot with this I don't want to keep asking bad q's. – user2380220 May 15 '13 at 07:40
  • @user2380220: your `contactList` is a `public` member of `ContactsCollection`. Therefore you can write `contactList.contactList.add(...)` and so on after `ontactsCollection contactList = new ContactsCollection();` – jlordo May 15 '13 at 07:44
  • That did the trick. I actually got the Contact object to serialize to the file! When attempting to read back the file it throws a "Stream Corrupted Exception Invalid type code: AC" on the read() method of the ContactsCollection class: while (in.available()!=0) is the indicated line. Would you recommend using .readObject() instead? Will readObject read all objects, or only one and therefore would need some type of loop or while statement? – user2380220 May 15 '13 at 08:07
  • @user2380220: I think it's time for a new question ;) – jlordo May 15 '13 at 08:32