Thursday, May 30, 2013

Amoritization Calculator (3/5/2012)

 This was a Java programming project from Phoenix. The goal was to create a loan amoritization calculator. There were a few change requests to add and remove features over the course of the project. This is a screen shot of the program in action:


As this flowchart of the program details, it is designed to create a loan amoritization table based on either user defined terms, or presets. It can even load new presets from a CSV file. CSV was chosen because it is a simple format supported by even the most basic spreadsheet programs.



And the Payment Loop:


This is the code for the project. Project guidelines required the code to be in a single file, so it may seem a little long and disorganized.
/**********************************************************************
*            Program:                Mortgage Payment

*            Purpose:                 Week 3 Individual Assignment

*            Programmer:           Dylan Sloboda                  

*            Class:                    PRG/421                        

*            Instructor:               Vince Anderson               

*            Creation Date:         March 5, 2012                      

***********************************************************************

*            Program Summary:  

*            Amoritization Calculator for change request 5.

*  

**********************************************************************/
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.StringTokenizer;

public class AmoritizationCalc extends JFrame implements ActionListener    // class definition
{
/**
     *
     */
    private static final long serialVersionUID = 1L;
    double [][] loanTIA;{
    loanTIA = new double[3][2]; //This array holds 2 arrays consisting of the loan terms and interest rates
    loanTIA[0][0] = 84;
    loanTIA[0][1] = 0.0535;
    loanTIA[1][0] = 180;
    loanTIA[1][1] = 0.055;
    loanTIA[2][0] = 360;
    loanTIA[2][1] = 0.0575;}
JTextField principleTxt = new JTextField(7);
JTextField termTxt = new JTextField(3);
JTextField interestTxt = new JTextField(4);
JCheckBox optionOne = new JCheckBox("7 Years at 5.35%");
JCheckBox optionTwo = new JCheckBox("15 Years at 5.5%");
JCheckBox optionThree = new JCheckBox("30 Years at 5.75%");
JButton calcButton = new JButton("Calculate");
JButton loadOpt = new JButton("Load terms from file");
JTextArea pymntAmtTxt = new JTextArea("Monthly payment");
JPanel principle = new JPanel();
JPanel term = new JPanel();
JPanel interest = new JPanel();
JPanel loanOptions = new JPanel();
JPanel loanTerms = new JPanel();
JScrollPane scrollingResult = new JScrollPane(pymntAmtTxt);
JPanel bottomPanel = new JPanel();
JPanel topPanel = new JPanel();
JPanel wholePane = new JPanel();

public AmoritizationCalc()    // constructor
    {
    principle.add(principleTxt);
    principle.add(new JLabel("Principle"), BorderLayout.WEST);
    term.add(termTxt);
    term.add(new JLabel("Loan Term (months)"), BorderLayout.WEST);
    interest.add(interestTxt);
    interest.add(new JLabel("Interest rate(as decimal)"), BorderLayout.WEST);
    loanOptions.add(optionOne);
    loanOptions.add(optionTwo);
    loanOptions.add(optionThree);
    loanOptions.add(loadOpt, BorderLayout.SOUTH);
    loanOptions.setLayout(new BoxLayout(loanOptions, BoxLayout.PAGE_AXIS));
    bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.PAGE_AXIS));
    bottomPanel.add(scrollingResult, BorderLayout.SOUTH);
    loanTerms.add(principle, BorderLayout.LINE_START);
    loanTerms.add(term, BorderLayout.LINE_START);
    loanTerms.add(interest, BorderLayout.LINE_START);
    loanTerms.setLayout(new BoxLayout(loanTerms, BoxLayout.PAGE_AXIS));
    topPanel.add(loanTerms, BorderLayout.WEST);
    topPanel.add(loanOptions, BorderLayout.EAST);
    wholePane.add(topPanel, BorderLayout.NORTH);
    wholePane.add(calcButton);
    calcButton.setAlignmentX(Component.CENTER_ALIGNMENT);
    wholePane.add(bottomPanel, BorderLayout.SOUTH);
    wholePane.setLayout(new BoxLayout(wholePane, BoxLayout.PAGE_AXIS)); // Box layout requires arguments
    getContentPane().add(wholePane, BorderLayout.CENTER);
    calcButton.addActionListener(this);
    optionOne.addActionListener(this);
    optionTwo.addActionListener(this);
    optionThree.addActionListener(this);
    loadOpt.addActionListener(this);
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setTitle("Amoritization Calculator");
    }

public static void main(String[] args)    // main thread
     {
    AmoritizationCalc amoritizationApp = new AmoritizationCalc();
    amoritizationApp.setLocation(150, 100);
    amoritizationApp.setSize(425, 350);
    amoritizationApp.setVisible(true);
    amoritizationApp.setName("Amoritization Calculator");
   
    }

public void actionPerformed(ActionEvent e)    // event thread. This program is event driven.
    {
    boolean selected = false;
    double princAmt = 0;
    double numMon = 0;
    double intRate = 0;

    DecimalFormat money = new DecimalFormat("$0.00");
    if (e.getSource() == calcButton) {
    try    {
        princAmt = Double.parseDouble(principleTxt.getText());    // these lines collect the data entered
        numMon = Double.parseDouble(termTxt.getText());
        intRate = (Double.parseDouble(interestTxt.getText()))/12;    //interest rate per month   
        }
    catch (NumberFormatException x) {    // this code ensures that the data entered is the appropriate format
        principleTxt.setText("");
        termTxt.setText("");
        interestTxt.setText("");
        }
    optionOne.setEnabled(true); // these clear the options and make the boxes editable again
    optionOne.setSelected(false);
    optionTwo.setEnabled(true);
    optionTwo.setSelected(false);
    optionThree.setEnabled(true);
    optionThree.setSelected(false);
    termTxt.setEditable(true);
    interestTxt.setEditable(true);
    double monPymt = 0; // the monthly payment
    monPymt = (princAmt * (intRate * (Math.pow((1 + intRate), numMon)))/(Math.pow((1 + intRate), numMon) - 1)); // the amoritization formula for finding periodic payment amount
    pymntAmtTxt.setText("Term: " + numMon + " Rate: " + intRate + " Monthly payment amount: " + money.format(monPymt));
    double pymtInt=0;
    double pymtPrinc=0;
    double balance=princAmt;
    for (int n=0; n<numMon ; n++) {
        pymtInt=intRate * balance;
        pymtPrinc=monPymt - pymtInt;
        balance=balance-pymtPrinc;
        pymntAmtTxt.append("\n");
        pymntAmtTxt.append("Payment " + n + " : interest " + money.format(pymtInt) + ", principal " + money.format(pymtPrinc) + ", Balance " + money.format(balance));
        }
    }

    else if (e.getSource() == optionOne) { //each one of these disables the other boxes and sets the term and interest
        selected = optionOne.isSelected();
        if (selected) {
            optionTwo.setEnabled(false);
            optionThree.setEnabled(false);
            termTxt.setText("" + loanTIA[0][0]);
            interestTxt.setText("" + loanTIA[0][1]);
            termTxt.setEditable(false);
            interestTxt.setEditable(false);
            }
        else {
            optionOne.setEnabled(true); // these clear the options and make the boxes editable again
            optionOne.setSelected(false);
            optionTwo.setEnabled(true);
            optionTwo.setSelected(false);
            optionThree.setEnabled(true);
            optionThree.setSelected(false);
            termTxt.setEditable(true);
            interestTxt.setEditable(true);
            }
        }
    else if (e.getSource() == optionTwo) {
        selected = optionTwo.isSelected();
        if (selected) {
            optionOne.setEnabled(false);
            optionThree.setEnabled(false);
            termTxt.setText("" + loanTIA[1][0]);
            interestTxt.setText("" + loanTIA[1][1]);
            termTxt.setEditable(false);
            interestTxt.setEditable(false); }
        else {
            optionOne.setEnabled(true); // these clear the options and make the boxes editable again
            optionOne.setSelected(false);
            optionTwo.setEnabled(true);
            optionTwo.setSelected(false);
            optionThree.setEnabled(true);
            optionThree.setSelected(false);
            termTxt.setEditable(true);
            interestTxt.setEditable(true);
            }
    }
    else if (e.getSource() == optionThree) {
        selected = optionThree.isSelected();
        if (selected) {
            optionTwo.setEnabled(false);
            optionOne.setEnabled(false);
            termTxt.setText("" + loanTIA[2][0]);
            interestTxt.setText("" + loanTIA[2][1]);
            termTxt.setEditable(false);
            interestTxt.setEditable(false); }
        else {
            optionOne.setEnabled(true); // these clear the options and make the boxes editable again
            optionOne.setSelected(false);
            optionTwo.setEnabled(true);
            optionTwo.setSelected(false);
            optionThree.setEnabled(true);
            optionThree.setSelected(false);
            termTxt.setEditable(true);
            interestTxt.setEditable(true);
            }
        }
    else if (e.getSource() == loadOpt) { // this button event opens a jfile chooser to read CSV files with 3 rows and 2 columns
            JFileChooser optLoad = new JFileChooser();
            File selectedFile = null;
            BufferedReader in;
            FileReader fReader = null;
            if (optLoad.showOpenDialog(this)==JFileChooser.APPROVE_OPTION)
            {
                selectedFile = optLoad.getSelectedFile();
            }
            try {
                fReader = new FileReader(selectedFile);
            } catch (FileNotFoundException e2) {
                // TODO Auto-generated catch block
                e2.printStackTrace();
            }
            in = new BufferedReader(fReader);
            String[][] TempArray = new String[3][2]; // temporary string array for reading the data into
            int row = 0;
            int col = 0;
            String strLine;
            try {
                while ((strLine = in.readLine()) != null && row < 3)
                {
                    StringTokenizer st = new StringTokenizer(strLine,","); // divided as Comma Separated Values
                    while (st.hasMoreTokens())
                    {
                        TempArray[row][col] = st.nextToken();
                        col++;
                    }
                    col = 0;
                    row++;
                }
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            try {
                in.close();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        for (int i=0; i < 3; i++)
        {
            for (int n=0; n<2; n++)
            {
                loanTIA[i][n] = Double.parseDouble(TempArray[i][n]); // parse each field from the temporary array as double for loanTIA array
            }
        }
        optionOne.setText((loanTIA[0][0]/12)+" Years at "+(loanTIA[0][1]*100)+"%"); // assign new labels to match
        optionTwo.setText((loanTIA[1][0]/12)+" Years at "+(loanTIA[1][1]*100)+"%");
        optionThree.setText((loanTIA[2][0]/12)+" Years at "+(loanTIA[2][1]*100)+"%");
       
        }
    }
}