I have spent over a WEEK trying to figure out why my code isn't working. It's a long code, I will post it all but I will break down the code as I explain.
First off, I have called double[] arrays and then initialized them later on in the program on certain steps. What problem is that even though they are initialized, later on in the code, it's telling me that the double[] I'm requesting is NULL, as if it didn't know that I have already done all that and added elements to it. Here's the program.....

package usefulapps;
/*  
    File: MortgageCalculator2.java
    This file calculates the monthly payments of a user inputs for a mortgage.
*/

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

/* import java package: classes to handle I/O methods, 
including FileReader, InputStreamReader, and BufferedReader.
*/													

@SuppressWarnings("serial")
public class MortgageCalculator3 extends JFrame implements ActionListener
{
	int financeYears;
	double interestRate;
    int salary;
    double loan;
    double rate;
    double yearlyPmt;
    double[] monthlyPmt, principal, loanPmt, ratePmt, newPrincipal;
	double endPrincipal;
	boolean calculate = false;
	boolean next = false;
	boolean previous = false;
	//variables
	int yearNumber = 1;
	int periodNumber = 1;
	int month = 0;
	int currMonth = 0;
	double interestPerYear = 0;
	DecimalFormat df = new DecimalFormat("###,###.00");
	
	
    
	//layout preparation
	LoanLayout customLayout = new LoanLayout();
			
		JLabel loanLabel = new JLabel("Loan Amount");
		
			JTextField loanText = new JTextField();
		
		JLabel termLabel = new JLabel("Years Financed");
		
			JTextField termText = new JTextField();
		
		JLabel rateLabel = new JLabel("Interest Rate (x.xx)");
		
			JTextField rateText = new JTextField();
			
		JLabel salaryLabel = new JLabel("Annual Salary");
		
			JTextField salaryText = new JTextField();
		
		JLabel monthlyLabel = new JLabel("Monthly Payment");
		
			JTextField monthlyText = new JTextField();
			
		JLabel yearTotalLabel = new JLabel("Year Total");
		
			JTextField yearTotalText = new JTextField();
			
		JLabel salaryTaxLabel = new JLabel("Salary After Taxes");
		
			JTextField salaryTaxText = new JTextField();
			
		JLabel salPercentLabel = new JLabel("Salary Percent of Yearly Mortgage");
		
			JTextField salPercentText = new JTextField();
		
		JLabel scheduleLabel = new JLabel("Schedule");
		
			JTextArea scheduleText = new JTextArea();
			
			JScrollPane scroller = new JScrollPane(scheduleText);
			
	public MortgageCalculator3()
	{
		JButton calcButton = new JButton("Calculate");
		
		JButton resetButton = new JButton("Reset");
		
		JButton scheduleButton = new JButton("Show Schedule");
		
		JButton previousButton = new JButton("<< Previous Year");
		
		JButton nextButton = new JButton("Next Year >>");
		
		JButton exitButton = new JButton("Exit");
		
		//add ActionListener to buttons
		calcButton.addActionListener(this);
		resetButton.addActionListener(this);
		scheduleButton.addActionListener(this);
		previousButton.addActionListener(this);
		nextButton.addActionListener(this);
		exitButton.addActionListener(this);
		
		//add ActionCommand to buttons
		calcButton.setActionCommand("calculate");
		resetButton.setActionCommand("reset");
		scheduleButton.setActionCommand("show");
		previousButton.setActionCommand("previous");
		nextButton.setActionCommand("next");
		exitButton.setActionCommand("exit");
		
		//getContentPane, set editable & setText for all labels, fields, and buttons
		getContentPane().setLayout(customLayout);
		getContentPane().add(loanLabel);
		getContentPane().add(loanText);
		getContentPane().add(termLabel);
		getContentPane().add(termText);
		getContentPane().add(rateLabel);
		getContentPane().add(rateText);
		getContentPane().add(salaryLabel);
		getContentPane().add(salaryText);
		getContentPane().add(calcButton);
		getContentPane().add(resetButton);
		getContentPane().add(monthlyLabel);
		getContentPane().add(monthlyText);
		monthlyText.setEditable(false);
		getContentPane().add(yearTotalLabel);
		getContentPane().add(yearTotalText);
		yearTotalText.setEditable(false);
		getContentPane().add(salaryTaxLabel);
		getContentPane().add(salaryTaxText);
		salaryTaxText.setEditable(false);
		getContentPane().add(salPercentLabel);
		getContentPane().add(salPercentText);
		getContentPane().add(scheduleButton);
		salPercentText.setEditable(false);
		getContentPane().add(scheduleLabel);
		getContentPane().add(scroller);
		scheduleText.setEditable(false);
		getContentPane().add(previousButton);
		getContentPane().add(nextButton);
		getContentPane().add(exitButton);
		
		//added this to ensure that the Frame closes properly	
		addWindowListener(new WindowAdapter()
			{
				public void windowClosing(WindowEvent e)
				{	
					System.exit(0);
				}
			}
			);
	}
	
	//actionPerformed 			
	public void actionPerformed(ActionEvent e)
	{
		String arg = e.getActionCommand();
		if (arg == "calculate" ) 
		{
			scheduleText.setText("");
		    
		    try 
		    {
	    		loan = Double.parseDouble(loanText.getText());
	    		financeYears = Integer.parseInt(termText.getText());
	    		rate = Double.parseDouble(rateText.getText());
	    		salary = Integer.parseInt(salaryText.getText());
		    } 
		    catch (Exception ex) 
		    {
		    	JOptionPane.showMessageDialog(null, "Invalid mortgage, term, rate, or salary amount\nFill out all above fields","Error", JOptionPane.ERROR_MESSAGE);
				return;
		    }
		    
		    calculate = true;
		    rate = rate / 100;
		    endPrincipal = loan;
		    DecimalFormat df1 = new DecimalFormat("###,###.000");
		    
		    double[] monthlyPmt = new double[(int) (12 * financeYears + 1)];
		    double[] principal = new double[(int) (12 * financeYears + 1)];
		    
	    	for (int i = 0; i < monthlyPmt.length; i++)
	    	{
	    		principal[i] = loan;
			    monthlyPmt[i] = (double) Math.round((rate / 12 * principal[i] * (Math.pow(1 + rate / 12,financeYears * 12)))/(Math.pow((1 + rate / 12),financeYears * 12) -1) * 100) / 100;
			    yearlyPmt = (monthlyPmt[i] * 12);
	    	}
			int[] bracketRange = {0, 8375, 34000, 82400, 171850, 373650};
			double[] taxBracket = {0.90, 0.85, 0.75, 0.72, 0.67, 0.65};
			double afterTaxes = 0;
			double salaryPercent = 0;
			if (salary >= bracketRange[5])
			{
				salaryPercent = (yearlyPmt / (salary * taxBracket[5] / 100));
				afterTaxes = salary * taxBracket[5];
			}
			if (salary >= bracketRange[4] && salary < bracketRange[5])
			{
				salaryPercent = (yearlyPmt / (salary * taxBracket[4] / 100));
				afterTaxes = salary * taxBracket[4];
			}
			if (salary >= bracketRange[3] && salary < bracketRange[4])
			{
				salaryPercent = (yearlyPmt / (salary * taxBracket[3] / 100));
				afterTaxes = salary * taxBracket[3];
			}
			if (salary >= bracketRange[2] && salary < bracketRange[3])
			{
				salaryPercent = (yearlyPmt / (salary * taxBracket[2] / 100));
				afterTaxes = salary * taxBracket[2];
			}
			if (salary >= bracketRange[1] && salary < bracketRange[2])
			{
				salaryPercent = (yearlyPmt / (salary * taxBracket[1] / 100));
				afterTaxes = salary * taxBracket[1];
			}
			if (salary >= bracketRange[0] && salary < bracketRange[1])
			{
				salaryPercent = (yearlyPmt / (salary * taxBracket[0] / 100));
				afterTaxes = salary * taxBracket[0];
			}
		   
			monthlyText.setText("$" + df.format(monthlyPmt[0]));
	        yearTotalText.setText("$" + df.format(yearlyPmt));
	        salaryTaxText.setText("$" + df.format(afterTaxes));
	        salPercentText.setText(df1.format(salaryPercent) + "%");
	    }
		//if reset button is picked, fields are cleared.
		if (arg == "reset")
		{
			calculate = false;
			loanText.setText("");
			termText.setText("");
			rateText.setText("");
			salaryText.setText("");
			monthlyText.setText("");
			yearTotalText.setText("");
			salaryTaxText.setText("");
			salPercentText.setText("");
			scheduleText.setText("");
		    yearNumber = 1;
		}
		//if show button is picked, year 1 is shown in the schedule area
		if (arg == "show")
		{
			if (calculate)
			{
				createSchedule(monthlyPmt, principal, financeYears, rate);
				interestPerYear = 0;
				yearNumber = 1;
				populateSchedule(yearNumber);
			}
		}
		//if previous button is picked, schedule goes back 1 year
		if (arg == "previous")
		{
			previous = true;
			if (yearNumber > 1)
			{
				yearNumber = yearNumber - 1;
				populateSchedule(yearNumber);
			}
			else
				JOptionPane.showMessageDialog(null, "Cannot go back, already on Year 1","Error", JOptionPane.ERROR_MESSAGE);
		}
		//if next button is picked, schedule goes forward 1 year
		if (arg == "next")
		{
			next = true;
			if (yearNumber < financeYears) 
			{
				yearNumber = yearNumber + 1;
				populateSchedule(yearNumber);
				
			}
			else
				JOptionPane.showMessageDialog(null, "Cannot continue forward, reached maximum year","Error", JOptionPane.ERROR_MESSAGE);
		}
		//if exit button is picked, program closes
		if (arg == "exit")
		{
			System.exit(0);
		}
		
	}
	public static void main(String[] args)						
	{																					
		//creating the JFrame window
		{ 
			new MortgageCalculator3();
			JFrame nFrame = new MortgageCalculator3();
			nFrame.setVisible(true);
			nFrame.setTitle("Mortgage Calculator");
			nFrame.setSize(650,770);
			nFrame.setLocation(600,200);
		}
	}
	public void createSchedule(double monthlyPmt[], double principal[], double financeYears, double rate)
	{	
		double[] loanPmt = new double[(int) (12 * financeYears + 1)];
		double[] ratePmt = new double[(int) (12 * financeYears + 1)];
		double[] newPrincipal = new double[(int) (12 * financeYears + 1)];
		for (yearNumber = 1; yearNumber <= financeYears; yearNumber++)
		{
			for (int periodNumber = 1; periodNumber <= 12; periodNumber++)
			{
				month = (12 * (yearNumber - 1)) + periodNumber - 1;
				ratePmt[month] = (double) Math.round((principal[month] * rate / 12) * 100) / 100;
				loanPmt[month] = (double) Math.round((monthlyPmt[month] - ratePmt[month]) * 100) / 100;
				newPrincipal[month] = (double) Math.round((principal[month] - loanPmt[month]) * 100) / 100;
				principal[month + 1] = newPrincipal[month];
			}
			principal[month + 1] = newPrincipal[month];
		}
	}
	public void populateSchedule(int yearNumber)  // Places the values for a given year of the loan into the schedule
	{
			if (yearNumber >= 10)
				scheduleText.append("\t\t                   Year " + yearNumber + "\n\t\t                   ********");
			else
				scheduleText.append("\t\t                    Year " + yearNumber + "\n\t\t                    *******");
			scheduleText.append("\nMONTH\tBEG BALANCE\tLOAN\tRATE\tTOTAL\tEND BALANCE");
			for (int periodNumber = 1; periodNumber <= 12; periodNumber++)
			{
				currMonth = 12 * (yearNumber - 1) + periodNumber - 1;
				//for last few payments, so the balance doesn't go in the negative
				if (newPrincipal[currMonth] < 0)
				{
					newPrincipal[currMonth] = 0;
					loanPmt[currMonth] = principal[currMonth] - ratePmt[currMonth];
					monthlyPmt[currMonth] = loanPmt[currMonth] + ratePmt[currMonth];
				}
				scheduleText.append("\n" + (currMonth + 1) + "\t$" + (df.format(principal[currMonth])) + " \t$" + (df.format(loanPmt[currMonth])) + "\t$" + (df.format(ratePmt[currMonth])) + "\t$" + (df.format(monthlyPmt[currMonth])) + "\t$" + (df.format(newPrincipal[currMonth])));
				principal[currMonth + 1] = newPrincipal[currMonth];
			
				if (yearNumber <= financeYears)
					interestPerYear += ratePmt[currMonth];
			}
			if (yearNumber < financeYears)
				scheduleText.append("\n\nTotal interest paid so far is: $" + df.format(interestPerYear));
			else
			{
				scheduleText.append("\n\nTotal interest paid: $" + df.format(interestPerYear));
				scheduleText.append("\nTotal cost of home: $" + df.format(endPrincipal + interestPerYear) + " after " + (yearNumber) + " years");
			}
			scheduleText.append("\n\n");
	}
	
	//Layout manager
	class LoanLayout implements LayoutManager 
	{
		public LoanLayout() 
		{
		}
		public void addLayoutComponent(String name, Component comp) 
		{
		}
		public void removeLayoutComponent(Component comp) 
		{
		}
		
		// layout dimensions
		public Dimension preferredLayoutSize(Container parent) 
		{
			Dimension dim = new Dimension(0, 0);
				Insets insets = parent.getInsets();
				 dim.height = 770 + insets.top + insets.bottom;    //height of window
				 dim.width = 650 + insets.left + insets.right;     // width of window
			return dim;
		}
		
		public Dimension minimumLayoutSize(Container parent) 
		{
			Dimension dim = new Dimension(0, 0);
			return dim;
		}
		
		// arrangement of all components (JButton, JTextField, and JLabel) in window as listed above
		public void layoutContainer(Container parent) 
		{
			Insets insets = parent.getInsets();
			
			Component w;  // array for components (JButton, JTextField, and JLabel)
			w = parent.getComponent(0);
			if (w.isVisible()) {w.setBounds(insets.left+20,insets.top+20,130,20);} //loan label
			w = parent.getComponent(1);
			if (w.isVisible()) {w.setBounds(insets.left+170,insets.top+20,100,20);} // loan field
			w = parent.getComponent(2);
			if (w.isVisible()) {w.setBounds(insets.left+20,insets.top+50,130,20);} // term label
			w = parent.getComponent(3);
			if (w.isVisible()) {w.setBounds(insets.left+170,insets.top+50,100,20);} // term field
			w = parent.getComponent(4);
			if (w.isVisible()) {w.setBounds(insets.left+20,insets.top+80,130,20);} // rate label
			w = parent.getComponent(5);
			if (w.isVisible()) {w.setBounds(insets.left+170,insets.top+80,100,20);}  // rate field
			w = parent.getComponent(6);
			if (w.isVisible()) {w.setBounds(insets.left+20,insets.top+110,160,20);} // salary label
			w = parent.getComponent(7);
			if (w.isVisible()) {w.setBounds(insets.left+170,insets.top+110,100,20);}  // salary field
			w = parent.getComponent(8);
			if (w.isVisible()) {w.setBounds(insets.left+20,insets.top+150,120,30);}  // calculate button
			w = parent.getComponent(9);
			if (w.isVisible()) {w.setBounds(insets.left+150,insets.top+150,100,30);}  // reset button
			w = parent.getComponent(10);
			if (w.isVisible()) {w.setBounds(insets.left+20,insets.top+200,140,20);}  // payment label
			w = parent.getComponent(11);
			if (w.isVisible()) {w.setBounds(insets.left+170,insets.top+200,100,20);}  // payment field
			w = parent.getComponent(12);
			if (w.isVisible()) {w.setBounds(insets.left+20,insets.top+230,140,20);}  // yearTotal label
			w = parent.getComponent(13);
			if (w.isVisible()) {w.setBounds(insets.left+170,insets.top+230,100,20);}  // yearTotal field
			w = parent.getComponent(14);
			if (w.isVisible()) {w.setBounds(insets.left+20,insets.top+260,140,20);}  // salaryTax label
			w = parent.getComponent(15);
			if (w.isVisible()) {w.setBounds(insets.left+170,insets.top+260,100,20);}  // salaryTax field
			w = parent.getComponent(16);
			if (w.isVisible()) {w.setBounds(insets.left+20,insets.top+290,210,20);}  // salPercent label
			w = parent.getComponent(17);
			if (w.isVisible()) {w.setBounds(insets.left+240,insets.top+290,80,20);}  // salPercent field
			w = parent.getComponent(18);
			if (w.isVisible()) {w.setBounds(insets.left+20,insets.top+320,200,30);}  // show button
			w = parent.getComponent(19);
			if (w.isVisible()) {w.setBounds(insets.left+285,insets.top+340,80,20);}  // schedule label
			w = parent.getComponent(20);
			if (w.isVisible()) {w.setBounds(insets.left+20,insets.top+370,610,300);}  // schedule field
			w = parent.getComponent(21);
			if (w.isVisible()) {w.setBounds(insets.left+20,insets.top+680,150,30);}  // previous button
			w = parent.getComponent(22);
			if (w.isVisible()) {w.setBounds(insets.left+480,insets.top+680,150,30);}  // next button
			w = parent.getComponent(23);
			if (w.isVisible()) {w.setBounds(insets.left+285,insets.top+690,80,50);}  // exit button
		}
	}
}

Now, at the very beginning is where i called out double[] arrays,

double[] monthlyPmt, principal, loanPmt, ratePmt, newPrincipal;

then when I press the "calculate" button, I called out or initialize 2 of them, telling it how many elements in the array I want, then assigning numbers to the elements, etc.

public void actionPerformed(ActionEvent e)
	{
		String arg = e.getActionCommand();
		if (arg == "calculate" ) 
		{
			scheduleText.setText("");
		    
		    try 
		    {
	    		loan = Double.parseDouble(loanText.getText());
	    		financeYears = Integer.parseInt(termText.getText());
	    		rate = Double.parseDouble(rateText.getText());
	    		salary = Integer.parseInt(salaryText.getText());
		    } 
		    catch (Exception ex) 
		    {
		    	JOptionPane.showMessageDialog(null, "Invalid mortgage, term, rate, or salary amount\nFill out all above fields","Error", JOptionPane.ERROR_MESSAGE);
				return;
		    }
		    
		    calculate = true;
		    rate = rate / 100;
		    endPrincipal = loan;
		    DecimalFormat df1 = new DecimalFormat("###,###.000");
		    
		    double[] monthlyPmt = new double[(int) (12 * financeYears + 1)];
		    double[] principal = new double[(int) (12 * financeYears + 1)];
		    
	    	for (int i = 0; i < monthlyPmt.length; i++)
	    	{
	    		principal[i] = loan;
			    monthlyPmt[i] = (double) Math.round((rate / 12 * principal[i] * (Math.pow(1 + rate / 12,financeYears * 12)))/(Math.pow((1 + rate / 12),financeYears * 12) -1) * 100) / 100;
			    yearlyPmt = (monthlyPmt[i] * 12);
	    	}

now to look more closer in this code

double[] monthlyPmt = new double[(int) (12 * financeYears + 1)];
           double[] principal = new double[(int) (12 * financeYears + 1)];
		    
for (int i = 0; i < monthlyPmt.length; i++)
{
        principal[i] = loan;
	monthlyPmt[i] = (double) Math.round((rate / 12 * principal[i] * (Math.pow(1 + rate / 12,financeYears * 12)))/(Math.pow((1 + rate / 12),financeYears * 12) -1) * 100) / 100;
	yearlyPmt = (monthlyPmt[i] * 12);
}

right there is where I do all the things I explained....now, later on in the code, I call this...

if (arg == "show")
{
	if (calculate)
	{
		createSchedule(monthlyPmt, principal, financeYears, rate);
		interestPerYear = 0;
		yearNumber = 1;
		populateSchedule(yearNumber);
	}
}

Which for some reason, even though I have already assigned numbers to the arrays, with however many elements total there are according to what the user wants, I think it still thinks I'm requesting THIS

double[] monthlyPmt, principal, loanPmt, ratePmt, newPrincipal;

Which is null to begin with, that's why I initialize them in the "calculate" button.
First off, I thought arrays REMEMBER what happens, what is assigned to it, etc, how come for some reason, it's telling me on line 309

public void createSchedule(double monthlyPmt[], double principal[], double financeYears, double rate)
	{	
		double[] loanPmt = new double[(int) (12 * financeYears + 1)];
		double[] ratePmt = new double[(int) (12 * financeYears + 1)];
		double[] newPrincipal = new double[(int) (12 * financeYears + 1)];
		for (yearNumber = 1; yearNumber <= financeYears; yearNumber++)
		{
			for (int periodNumber = 1; periodNumber <= 12; periodNumber++)
			{
				month = (12 * (yearNumber - 1)) + periodNumber - 1;
				ratePmt[month] = (double) Math.round((principal[month] * rate / 12) * 100) / 100;
				loanPmt[month] = (double) Math.round((monthlyPmt[month] - ratePmt[month]) * 100) / 100;
				newPrincipal[month] = (double) Math.round((principal[month] - loanPmt[month]) * 100) / 100;
				principal[month + 1] = newPrincipal[month];
			}
			principal[month + 1] = newPrincipal[month];
		}
	}

309 is the

ratePmt[month] = (double) Math.round((principal[month] * rate / 12) * 100) / 100;

telling me that principal[month] is NULL???? it shouldnt be because I told it what I want from it, from

double[] monthlyPmt = new double[(int) (12 * financeYears + 1)];
double[] principal = new double[(int) (12 * financeYears + 1)];

And I'm sure that if the principal[month] problem is fixed, it will tell me monthlyPmt[month] is ALSO NULL.
Basically I just need my arrays to be program-wide for everything to read them correctly.
Again, I've been spending 9 days, since LAST wednesday on this very problem. Somebody help me....

Recommended Answers

All 2 Replies

The problem is in that when you first declare the arrays:

double[] monthlyPmt, principal, loanPmt, ratePmt, newPrincipal;

You then in the actionPerfromed() method again say

double[] monthlyPmt[] = new double[...]

This is not needed. just remove the doble before that it should be:

monthlyPmt[] = new double[...]

Here is a working code:
http://http://pastebin.com/HB2ApsMu]

I will suggest to try and not put everything in one big class though.

I'm not sure what that link you gave me is for...could you explain?
But other than that, thank you soo much for the quick help. I spent probably a good 3 days JUST ON THAT problem, I should've posted it on this website 3 days ago and then I wouldn't have had all that stress, lol.

Quick question: what do you suggest I do to spread my program out over different files? I've thought about doing that but I'm not sure where to start. I mean, every time I have used separate files, I always seem to have to CONNECT them all, instead of having them just be their own independent classes.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.