Hello, everyone.

I've been working on an application that will be able to accept customers and bills of an electrical service company. While testing this application, I've come across an error message saying Null Pointer Exception.

Okay, here are the details. The application is actually an entire GUI project. It has 3 classes, 3 frames and a data driver file (which handles all events). Now, I've told the program to accept an array of objects of class Subscriber. The program will ask the user to specify an initial number of customers on hand.

However, the problem is doing anything with that array of objects gets me nowhere. For instance, I've made a bunch of codes for moving from record to record and another bunch for saving input in the Subscriber array. With this, I was expecting the program to scroll back and forth through the records and be able to save changes and entries with these functions, but all I get is no response and a Null Pointer Exception message.

Here's the data driver file. The developer tool has shown me exactly where the error is - I'll point it out in full-caps comments. EDIT: They are lines 90 and 125.

/**
 * @(#)frmMain.java
 *
 *
 * @author 
 * @version 1.00 2008/8/2
 */


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

public class frmMain implements ActionListener
{
	frmSubscriber SubscriberFrame;
	frmBill BillFrame;
	frmMenu MenuFrame;
	
	Subscriber s[];
	int n = 0, order = 0;
		
	public frmMain() 
	{
		SubscriberFrame = new frmSubscriber(this);
		BillFrame = new frmBill(this);
		MenuFrame = new frmMenu(this);
		
		MenuFrame.open();
	}
	
	public void actionPerformed (ActionEvent onClick)
	{
		if (onClick.getSource() == MenuFrame.cmdSubscribe)
		{
			if (n == 0)
			{
				do
				{
					n = Integer.parseInt(JOptionPane.showInputDialog("The system needs at least 1 account in the database.\nCurrently, this is not the case.\n\nIn order to continue, please specify the number of accounts\nyou would like to assign to the database."));
				
					if (n <= 0)
					{
						JOptionPane.showMessageDialog(null, "Invalid entry! Use a value more than 0.");
					}
				}
				while (n <= 0);
				
				Subscriber s[] = new Subscriber[n];
				
				for (int i = 0; i < n; i++)
				{
					s[i] = new Subscriber();
					
					s[i].setName("");
					s[i].setAge(0);
					s[i].setAddress("");
					s[i].setGender(false);
					s[i].setAcct(0);
					s[i].setBalance(0);
					s[i].setServicestatus(false);
				}
				
				// view the first record
				order = 0;
				
				// disable button "Previous" because this is already the first record
				SubscriberFrame.cmdPrev.setEnabled(false);
				
				SubscriberFrame.txtX.setText("" + (order + 1));
				SubscriberFrame.txtY.setText("" + n);
			}
			
			SubscriberFrame.open();
			MenuFrame.close();
		}
		else if (onClick.getSource() == SubscriberFrame.cmdSave)
		{
			String name, address;
			int acct, age;
			double balance;
			
			name = SubscriberFrame.txtName.getText();
			address = SubscriberFrame.txtAge.getText();
			age = Integer.parseInt(SubscriberFrame.txtAge.getText());
			acct = Integer.parseInt(SubscriberFrame.txtAcct.getText());
			balance = Double.parseDouble(SubscriberFrame.txtAcct.getText());
			
			// NULL POINTER EXCEPTION FOUND HERE
			s[order].setName(name);
			s[order].setAddress(address);
			s[order].setAge(age);
			s[order].setAcct(acct);
			s[order].setBalance(balance);
		}
		/*else if (onClick.getSource() == SubscriberFrame.cmdNew)
		{
			int placeholder;
			
			placeholder = n;
			
			n++;
			
			for (int i = placeholder; i < n; i++)
			{
				s[i] = new Subscriber();
			}
			
			SubscriberFrame.txtY.setEnabled(true);
			SubscriberFrame.txtY.setText("" + n);
			SubscriberFrame.txtY.setEnabled(false);
		}*/
		else if (onClick.getSource() == SubscriberFrame.cmdNext && order < n)
		{
			// increment order so that the program will go to the next account
			++order;
			
			String name;
			String address;
			int age;
			int acct;
			double balance;
			
			// NULL POINTER EXCEPTION FOUND HERE
			name = s[order].getName();
			address = s[order].getAddress();
			age = s[order].getAge();
			acct = s[order].getAcct();
			balance = s[order].getBalance();
			
			// display the next account's contents
			SubscriberFrame.txtName.setText(name);
			SubscriberFrame.txtAddress.setText(address);
			SubscriberFrame.txtAge.setText("" + age);
			SubscriberFrame.txtAcct.setText("" + acct);
			SubscriberFrame.txtBalance.setText("" + balance);
			
			// show the record number
			SubscriberFrame.txtX.setText("" + (order + 1));
			SubscriberFrame.cmdPrev.setEnabled(true);
			
			// disable button "Next" when at the last record
			if (order == n - 1)
			{
				SubscriberFrame.cmdNext.setEnabled(false);
			}
		}
		else if (onClick.getSource() == SubscriberFrame.cmdPrev && order >= 0)
		{
			// decrement order so that the program will go the next account
			--order;
			
			String name;
			String address;
			int age;
			int acct;
			double balance;
			
			name = s[order].getName();
			address = s[order].getAddress();
			age = s[order].getAge();
			acct = s[order].getAcct();
			balance = s[order].getBalance();
			
			// display the previous account's contents
			SubscriberFrame.txtName.setText(name);
			SubscriberFrame.txtAddress.setText(address);
			SubscriberFrame.txtAge.setText("" + age);
			SubscriberFrame.txtAcct.setText("" + acct);
			SubscriberFrame.txtBalance.setText("" + balance);
			
			// show the record number
			SubscriberFrame.txtX.setText("" + (order + 1));
			SubscriberFrame.cmdNext.setEnabled(true);
			
			// disable button "Previous" when at the first record
			if (order == 0)
			{
				SubscriberFrame.cmdPrev.setEnabled(false);
			}
		}
		else if (onClick.getSource() == MenuFrame.cmdExit || onClick.getSource() == SubscriberFrame.cmdExit)
		{
			System.exit(0);
		}
		else if (onClick.getSource() == SubscriberFrame.cmdReturn)
		{
			MenuFrame.open();
			SubscriberFrame.close();
		}

	}
	
	public static void main(String args[])
	{
		frmMain mf = new frmMain();
	}
}

EDIT
Things I've tried that failed:
1. Sending Subscriber into cmdSave and cmdNext instruction block because I assumed Subcriber objects are only recognized in cmdSubscribe's instruction block.

It ended up with a syntax error of Variable s might not have been initialized. Subscriber 's' has already been specified as a class attribute, so, clearly, this is not a solution.

2. Puting
[inline]if (onClick.getSource() == cmdSave)[/inline]
and
[inline]if (onClick.getSource() == cmdNext)"[/inline] instruction blocks under
[inline]if (onClick.getSource() == cmdSubscribe)[/inline] because object array Subscriber is first assigned in that block.

It ended up with no run-time errors, but no effect, either.

I use JCreator Lite to do this program. Please do tell me if you need the other files as well.

Also, this is my first time looking through the forum for real - everything here is quite new to me, so I hope you can pardon my ignorance.

Help is very much appreciated.

The only place in which s[] is initialized is within the if (onClick.getSource() == MenuFrame.cmdSubscribe) block, and it eclipses the class level variable with a local declaration. None of the other blocks initialize s[]. That array must be initialized prior to use, whether it be in the action listener blocks or another method, and glancing at those blocks in the listener, I'd say you need to change the declaration on line 49 to an initialization of the class level s[] variable like so

s[] = new Subscriber[n];

The warning that it might not be initialized comes from the fact that s[] will only be assigned a value in a conditional block and the compiler sees that it won't have a value if any of the other conditional blocks execute before it.

That can be resolved by initializing s[] to a particular value when you declare it, such as

Subscriber s[] = null;
// or
Subscriber s[] = new Subscriber[0];

Initializing to a size of 0 is usually a better way to go, since any loop operations on the array will simply not execute under the standard looping idiom of

for (int i=0; i<s.length; i++){}
public class frmMain implements ActionListener
{
	frmSubscriber SubscriberFrame;
	frmBill BillFrame;
	frmMenu MenuFrame;
	
	Subscriber s[];
	int n = 0, order = 0;
		
	public frmMain() 
	{
		SubscriberFrame = new frmSubscriber(this);
		BillFrame = new frmBill(this);
		MenuFrame = new frmMenu(this);
		
		MenuFrame.open();
	}
	
	public void actionPerformed (ActionEvent onClick)
	{
		if (onClick.getSource() == MenuFrame.cmdSubscribe)
		{
			if (n == 0)
			{
				do
				{
					n = Integer.parseInt(JOptionPane.showInputDialog("The system needs at least 1 account in the database.\nCurrently, this is not the case.\n\nIn order to continue, please specify the number of accounts\nyou would like to assign to the database."));
				
					if (n <= 0)
					{
						JOptionPane.showMessageDialog(null, "Invalid entry! Use a value more than 0.");
					}
				}
				while (n <= 0);
				
			//	Subscriber s[] = new Subscriber[n]; // localized Subscriber, Ezzaral pointed this out
				s = new Subscriber[n]; // now uses globally scoped Subscriber

				for (int i = 0; i < n; i++)
				{
					s[i] = new Subscriber();
					
					s[i].setName("");
					s[i].setAge(0);
					s[i].setAddress("");
					s[i].setGender(false);
					s[i].setAcct(0);
					s[i].setBalance(0);
					s[i].setServicestatus(false);
				}
				
				// view the first record
				order = 0;
				
				// disable button "Previous" because this is already the first record
				SubscriberFrame.cmdPrev.setEnabled(false);
				
				SubscriberFrame.txtX.setText("" + (order + 1));
				SubscriberFrame.txtY.setText("" + n);
			}
			
			SubscriberFrame.open();
			MenuFrame.close();
		}
		else if (onClick.getSource() == SubscriberFrame.cmdSave)
		{
			String name, address;
			int acct, age;
			double balance;
			
			name = SubscriberFrame.txtName.getText();
			address = SubscriberFrame.txtAge.getText();
			age = Integer.parseInt(SubscriberFrame.txtAge.getText());
			acct = Integer.parseInt(SubscriberFrame.txtAcct.getText());
			balance = Double.parseDouble(SubscriberFrame.txtAcct.getText());
			
			// NULL POINTER EXCEPTION FOUND HERE
			s[order].setName(name);
			s[order].setAddress(address);
			s[order].setAge(age);
			s[order].setAcct(acct);
			s[order].setBalance(balance);
		}

I'm not sure of the amount of times you want s to be reinitialized - you'll have to set a flag if you only want this action done once.

I'd say you need to change the declaration on line 49 to an initialization of the class level s[] variable like so

s[] = new Subscriber[n];

Nuh-uh. JCreator Lite doesn't recognize it as a statement. I tried

s = new Subscriber[n];

that is losing the double brackets and it worked.

Thanks for trying, anyway.

On a side note: hours ago, I've just found a potential to use ArrayList to make the array of Subscribers more dynamic in such a way I can add and remove array elements.

But I've not been taught ArrayList in programming classes yet - I could get all the syntaxes (and worse, logic) wrong, so I have to learn by trial and error. Sadly, time isn't something I have right now.

Nuh-uh. JCreator Lite doesn't recognize it as a statement. I tried

s = new Subscriber[n];

that is losing the double brackets and it worked.

Yes, copy-paste oversight on my part, but you got the point I suppose. Thanks for sharing that enlightenment.

Thanks for trying, anyway.

:-/
You bet. I'll not waste any more of your time "trying", since you're short on that.

To: Alex Edwards

Yup. I knew I should've lost the "Subscriber" in Subscriber s.

I found my way out.

Almost forgot: thanks for pointing out the error.

This article has been dead for over six months. Start a new discussion instead.