Good morning all. I'm having some difficulty in reading from a sequential file. I think I have my code set up properly, but when ran, it throws an exception which show me the error statement I specified. When I ran a debug, it does seem to be pulling the information into the specified arrays. I'm not sure if I have something coded wrong or if I just don't have the sequential files stored in the right place. Thanks, as always, for your help.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.text.*;
import java.util.Scanner;


public class MortgageCalculatorWk4 extends JFrame implements ActionListener
{

	JTextField tMortgageAmount;                         //the field used for input of the principle
	JTextField tPayment;                                //the field used to output monthly payment
        JTextField tTerm;                                   //the field used for input of the user's term
        JTextField tRate;                                   //the field used for input of the user's interest
        JComboBox cbMortgageLoanOptions;                    //drop down menu for loan options
	JTextArea taAmmortization;                          //text area for ammortization
        JScrollPane spAmmortization;                        //scroll bar for ammortization
	protected JButton bCalculate;                       //calculate button
        protected JButton bQuit;                            //quit button
        JLabel lMessages;                                   //label for messages
	DecimalFormat df = new DecimalFormat("$###.00");    //format currency

        private int mortgage;                               //principal
        private int years;                                  //term
        private double rate;                                //interest rate
        private double monthlyPaymentAmt;                   //mortgage payment amount
        private double remainingBalance;                    //remaining balance
        int [] arrLoanTerm;                   //term array
        double[] arrLoanRate;          //interest array
        private double userRate;                            //user declared interest rate
        private double userRate2;                           //user declared interest rate
        private int userTerm;                               //user declared term
        private int userTerm2;                              //user declared term

        public MortgageCalculatorWk4() {
            try {
                BufferedReader scanFile = new BufferedReader(new FileReader("C:/array.txt"));
                for(int i=0; i< arrLoanTerm.length; i++){
                    arrLoanTerm[i] = scanFile.read();
                }
           }
           catch (Exception ex){
            }
            try {
                Scanner scanFile2 = new Scanner(new File("C:/array2.txt"));
                for(int i=0; i<arrLoanRate.length; i++){
                   arrLoanRate[i] = scanFile2.nextDouble();
                }
            }
            catch (Exception ex){
}

            //Create Messages
            JPanel pMessages = new JPanel();
            pMessages.setLayout(new FlowLayout());
            pMessages.add(lMessages = new JLabel("If You Would Like to Calculate a Mortgage Using Unspecified Interest/Term, Please Select 'Own Terms' From the Drop-Down Menu"));
            String[] loanOptions = {"7 years at 5.35%","15 years at 5.5%","30 years at 5.75%"};

            //Create Labels
            JPanel pLabels = new JPanel();
            pLabels.setLayout(new GridLayout(6, 1));
            pLabels.add(new JLabel("Enter Loan Amount"));
            pLabels.add(new JLabel("Choose your mortgage terms"));
            pLabels.add(new JLabel("Term"));
            pLabels.add(new JLabel("Interest Rate"));
            pLabels.add(new JLabel("Your Monthly Payment is:"));

            taAmmortization = new JTextArea(30,20);
            //Create Text Fields
            JPanel pFields = new JPanel();
            pFields.setLayout(new GridLayout(6, 1));
            pFields.add(tMortgageAmount = new JTextField(12));
            pFields.add(cbMortgageLoanOptions = new JComboBox(loanOptions));
            pFields.add(tTerm = new JTextField(12));
            pFields.add(tRate = new JTextField(12));
            pFields.add(tPayment = new JTextField(12));

            //Combine Labels & Text
            JPanel pData = new JPanel();
            pData.setLayout(new BorderLayout());
            pData.add(pLabels, BorderLayout.WEST);
            pData.add(pFields, BorderLayout.CENTER);

            //Create Buttons
            JPanel pButtons = new JPanel();
            pButtons.setLayout(new FlowLayout());
            pButtons.add(bCalculate = new JButton("Calculate"));
            pButtons.add(bQuit = new JButton("Quit"));

            //Create Scroll Bar
            spAmmortization = new JScrollPane(taAmmortization);
            spAmmortization.setPreferredSize(new Dimension(250,375));
            spAmmortization.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

            //Organize GUI
            getContentPane().setLayout(new BorderLayout());
            getContentPane().add(pMessages, BorderLayout.NORTH);
            getContentPane().add(pData, BorderLayout.CENTER);
            getContentPane().add(pButtons, BorderLayout.EAST);
            getContentPane().add(spAmmortization,BorderLayout.SOUTH);

            //Add Listeners
            bCalculate.addActionListener(this);
            bQuit.addActionListener(this);

            tPayment.setEnabled(false);
            taAmmortization.setEnabled(false);
        }

        //Event Handling
        public void actionPerformed(ActionEvent e){
            if (e.getSource() == bCalculate){
                try{
                    String userInput;
                    userInput = tMortgageAmount.getText();
                    mortgage = Integer.parseInt(userInput);
                    rate = arrLoanRate[cbMortgageLoanOptions.getSelectedIndex()]/100 ;
                    years = arrLoanTerm[cbMortgageLoanOptions.getSelectedIndex()];
                    //if (years == 0){
                        //String userRate;
                        //userRate = tRate.getText();
                        //userRate2 = Double.parseDouble(userRate);
                        //String userTerm;
                        //userTerm = tTerm.getText();
                        //userTerm2 = Integer.parseInt(userTerm);
                        //rate = userRate2 / 100;
                        //years = userTerm2;
                        //MonthlyPaymentCalculation();
                        //tPayment.setText(String.valueOf(df.format(monthlyPaymentAmt)));
                        //lMessages.setText("If You Would Like to Calculate a Mortgage Using Unspecified Interest/Term, Please Select 'Own Terms' From the Drop-Down Menu");
                        //remainingBalance = mortgage;
                        //taAmmortization.setText("");
                        //LoanDetailsCalculation();
                        ///repaint();
                    //else{
                    MonthlyPaymentCalculation();
                    tPayment.setText(String.valueOf(df.format(monthlyPaymentAmt)));
                    lMessages.setText("If You Would Like to Calculate a Mortgage Using Unspecified Interest/Term, Please Select 'Own Terms' From the Drop-Down Menu");
                    remainingBalance = mortgage;
                    taAmmortization.setText("");
                    LoanDetailsCalculation();
                    repaint();
                    }
                 catch (Exception ex) {
                    lMessages.setText("Invalid Entry. Please try again.");
                    }
            } else {
                System.exit(0);
            }
    }
              
         public void LoanDetailsCalculation(){
            taAmmortization.append("Month No.\tMonthly Payment\tRemaining Balance\tInterest Paid\n");
            for (int i = 1; i <= years*12; i++){
                double thisPaymentInterest = (rate / 12) * remainingBalance;         // calculate the interest for the current payment
                double thisPaymentPrinciple = monthlyPaymentAmt - thisPaymentInterest;     // calculate the principle amount for the current payment
                remainingBalance = remainingBalance - thisPaymentPrinciple;             // calculate the remaining total balance
                taAmmortization.append(i + "\t" + df.format(monthlyPaymentAmt) + "\t\t" + df.format(remainingBalance) + "\t\t" + df.format(thisPaymentInterest) + "\n");  // output the monthly amounts
            }
        }

          //Mortgage Calculation
        public void MonthlyPaymentCalculation(){
            monthlyPaymentAmt = ((rate / 12) * mortgage) / (1- (Math.pow (1+ (rate / 12), (years * -12))));
        }

       public static void main(String[] args){
            MortgageCalculatorWk4 frame = new MortgageCalculatorWk4();
            frame.setTitle("McBride Mortgage Payment Calculator");
            frame.setSize(800,600);
            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
       }

}

Recommended Answers

All 21 Replies

Place an ex.printStackTrace() in EVERY catch clause.
Never ever ever do what you do in lines 45/46 if you want any chance finding bugs.
When posting here always post the full text of the exception stackTrace, and make sure we have a listing of the code lines it refers to.

When you catch an exception, print out the stack trace using ex.printStackTrace(). Then put the results here so we can see what's going wrong.

Never used that before, but I gave it a shot.

When I first ran the file, I received this information...

java.lang.NullPointerException
at MortgageCalculator.MortgageCalculatorWk4.<init>(MortgageCalculatorWk4.java:56)
at MortgageCalculator.MortgageCalculatorWk4.main(MortgageCalculatorWk4.java:189)
java.lang.NullPointerException
at MortgageCalculator.MortgageCalculatorWk4.<init>(MortgageCalculatorWk4.java:65)
at MortgageCalculator.MortgageCalculatorWk4.main(MortgageCalculatorWk4.java:189)

After inputing figures and trying to calculate, I received this...

java.lang.NullPointerException
at MortgageCalculator.MortgageCalculatorWk4.actionPerformed(MortgageCalculatorWk4.java:137)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6263)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6028)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4630)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
BUILD SUCCESSFUL (total time: 52 seconds)

That's odd kramerd - I thought I had already said exactly the same thing, and in more detail!

and make sure we have a listing of the code lines it refers to.

The line numbers in your exceptions do not correspond to the code you have posted.

Ah probably because I did not copy all the comments about date, author, blah, blah. The two exceptions are referring to the FOR statements in each read statement. Do i need to pre-specify the length of the array or something?

Well, yes.
float[] myArray; just declares a reference variable (pointer).
To have an actual array you need to create a "new" array and define its size
float[] myArray = new float[99];

Sorry, JamesCherrill - you and I were responding to the post at the same time. :)

Okay, but when I do that it's going to cause me to change the code in the read statements correct? Because now, the variables will be mismatched. Do I need to create a second array for each and parse the information from the first?

Like...
arrLoanTerm = scanFile.read();
arrLoanTerm2 = Float.parseFloat(arrLoanTerm);

*note I tried that and receive an error "method parseFloat in class java.lang.Float cannot be applied to given types

My code was just an example of the syntax. I deliberately didn't give you the exact line of code because you will learn more by working it out yourself. I didn't mean that you should use floats, just use whatever the arrays need to be, but initialise/create them following the pattern from my code.

Ahhh you suck!! J/p of course. Thanks for the help. The code is actually running now, but not getting the correct results. After debugging, somehow it has 49 as the number of years and 0.51 as the interest.

The arrays should be 7, 15, 30 and 5.35, 5.5, 5.75 respectively.

Time to start putting a few more System.out.println lines into the code to see exactly where things are going wrong.
What's J/p ?

It's always a bit dangerous using array sizes fixed in the code to read data from a file - if they don't match it all goes to ratsh*t. what happens when the number of periods/rates has to change?
It's a better idea to add a line to the data file, just before that data, showing how many periods/rates to expect. Then you read that number, create arrays of that size, then read the actual data. Futureproofed.

I definitely understand where you're coming from but probably a bit outside the scope of the assignment.

When I go back to debug and look at the array entries, I see 55, 32, 49 for term and 53.0, 46.0, 51.0 for Rate. I no idea where in the world it's pulling these numbers from when my txt files are 7,15,30 and 5.35,5.5,5.75

Oh... and J/P is "just playing" :)

read() reads a single char, so it's probably not what you need to read mutli-character ints, you are reading the char '5' and assigning it to an int - ASCII 53. Ditto read '7' is ASCII 55.

I have to go offline now till tomorrow, so good luck. I'll look again in the morning. An up-to-date source listing may be useful.
J

Hrmmm I see. Unfortunately I don't see any other methods that will read more than one. The rest seem to read strings.

If you use a Scanner to read from the file, then you can use the nextInt() or nextDouble() methods.

Hrmmm I see. Unfortunately I don't see any other methods that will read more than one. The rest seem to read strings.

Yes, read string and parse for int/float etc. Integer.parseInt etc methods - google them.

If you use a Scanner to read from the file, then you can use the nextInt() or nextDouble() methods.

Funny, I had tried the Scanner before but it didn't work. Tried it again this time and it worked... somewhat. Maybe I had it coded wrong. After debugging, I see that the entries for the first array were read properly. But, I get an error and 0.0 results for my second read. There error is...

java.util.InputMismatchException
        at java.util.Scanner.throwFor(Scanner.java:840)
        at java.util.Scanner.next(Scanner.java:1461)
        at java.util.Scanner.nextDouble(Scanner.java:2387)
        at MortgageCalculator.MortgageCalculatorWk4.<init>(MortgageCalculatorWk4.java:67)
        at MortgageCalculator.MortgageCalculatorWk4.main(MortgageCalculatorWk4.java:190)

Apparently this is pointing to mismatched variables, but I don't understand how. arrLoanRate is declared as a double so shouldn't I use the nextDouble()?

package MortgageCalculator;

/**
 *
 * by Michael Hill
 * October 04, 2010
 * PRG421
 * Week 4 Individual Assignment
 *
 * The following program will calculate the ammortization schedule for any loan
 * amount using either preset terms or user defined terms and display the output
 * for the user.
 *
 */

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.text.*;
import java.util.Scanner;
import java.lang.*;


public class MortgageCalculatorWk4 extends JFrame implements ActionListener
{

    JTextField tMortgageAmount;                         //the field used for input of the principle
    JTextField tPayment;                                //the field used to output monthly payment
        JTextField tTerm;                                   //the field used for input of the user's term
        JTextField tRate;                                   //the field used for input of the user's interest
        JComboBox cbMortgageLoanOptions;                    //drop down menu for loan options
    JTextArea taAmmortization;                          //text area for ammortization
        JScrollPane spAmmortization;                        //scroll bar for ammortization
    protected JButton bCalculate;                       //calculate button
        protected JButton bQuit;                            //quit button
        JLabel lMessages;                                   //label for messages
    DecimalFormat df = new DecimalFormat("$###.00");    //format currency

        private int mortgage;                               //principal
        private int years;                                  //term
        private double rate;                                //interest rate
        private double monthlyPaymentAmt;                   //mortgage payment amount
        private double remainingBalance;                    //remaining balance
        int [] arrLoanTerm = new int [3];                   //term array
        double [] arrLoanRate = new double [3];                           //interest array
        private double userRate;                            //user declared interest rate
        private double userRate2;                           //user declared interest rate
        private int userTerm;                               //user declared term
        private int userTerm2;                              //user declared term

        public MortgageCalculatorWk4() {
            try {
                Scanner scanFile = new Scanner(new FileReader("C:/array.txt"));
                for(int i=0; i< arrLoanTerm.length; i++){
                    arrLoanTerm[i] = scanFile.nextInt();
                }
           }
           catch (Exception ex){
               ex.printStackTrace();
            }
            try {
                Scanner scanFile2 = new Scanner (new FileReader("C:/array2.txt"));
                for(int i=0; i<arrLoanRate.length; i++){
                   arrLoanRate[i] = scanFile2.nextDouble();
                }
            }
            catch (Exception ex){
                ex.printStackTrace();
}

            //Create Messages
            JPanel pMessages = new JPanel();
            pMessages.setLayout(new FlowLayout());
            pMessages.add(lMessages = new JLabel("If You Would Like to Calculate a Mortgage Using Unspecified Interest/Term, Please Select 'Own Terms' From the Drop-Down Menu"));
            String[] loanOptions = {"7 years at 5.35%","15 years at 5.5%","30 years at 5.75%"};

            //Create Labels
            JPanel pLabels = new JPanel();
            pLabels.setLayout(new GridLayout(6, 1));
            pLabels.add(new JLabel("Enter Loan Amount"));
            pLabels.add(new JLabel("Choose your mortgage terms"));
            pLabels.add(new JLabel("Term"));
            pLabels.add(new JLabel("Interest Rate"));
            pLabels.add(new JLabel("Your Monthly Payment is:"));

            taAmmortization = new JTextArea(30,20);
            //Create Text Fields
            JPanel pFields = new JPanel();
            pFields.setLayout(new GridLayout(6, 1));
            pFields.add(tMortgageAmount = new JTextField(12));
            pFields.add(cbMortgageLoanOptions = new JComboBox(loanOptions));
            pFields.add(tTerm = new JTextField(12));
            pFields.add(tRate = new JTextField(12));
            pFields.add(tPayment = new JTextField(12));

            //Combine Labels & Text
            JPanel pData = new JPanel();
            pData.setLayout(new BorderLayout());
            pData.add(pLabels, BorderLayout.WEST);
            pData.add(pFields, BorderLayout.CENTER);

            //Create Buttons
            JPanel pButtons = new JPanel();
            pButtons.setLayout(new FlowLayout());
            pButtons.add(bCalculate = new JButton("Calculate"));
            pButtons.add(bQuit = new JButton("Quit"));

            //Create Scroll Bar
            spAmmortization = new JScrollPane(taAmmortization);
            spAmmortization.setPreferredSize(new Dimension(250,375));
            spAmmortization.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

            //Organize GUI
            getContentPane().setLayout(new BorderLayout());
            getContentPane().add(pMessages, BorderLayout.NORTH);
            getContentPane().add(pData, BorderLayout.CENTER);
            getContentPane().add(pButtons, BorderLayout.EAST);
            getContentPane().add(spAmmortization,BorderLayout.SOUTH);

            //Add Listeners
            bCalculate.addActionListener(this);
            bQuit.addActionListener(this);

            tPayment.setEnabled(false);
            taAmmortization.setEnabled(false);
        }

        //Event Handling
        public void actionPerformed(ActionEvent e){
            if (e.getSource() == bCalculate){
                try{
                    String userInput;
                    userInput = tMortgageAmount.getText();
                    mortgage = Integer.parseInt(userInput);
                    rate = arrLoanRate[cbMortgageLoanOptions.getSelectedIndex()]/100 ;
                    years = arrLoanTerm[cbMortgageLoanOptions.getSelectedIndex()];
                    //if (years == 0){
                        //String userRate;
                        //userRate = tRate.getText();
                        //userRate2 = Double.parseDouble(userRate);
                        //String userTerm;
                        //userTerm = tTerm.getText();
                        //userTerm2 = Integer.parseInt(userTerm);
                        //rate = userRate2 / 100;
                        //years = userTerm2;
                        //MonthlyPaymentCalculation();
                        //tPayment.setText(String.valueOf(df.format(monthlyPaymentAmt)));
                        //lMessages.setText("If You Would Like to Calculate a Mortgage Using Unspecified Interest/Term, Please Select 'Own Terms' From the Drop-Down Menu");
                        //remainingBalance = mortgage;
                        //taAmmortization.setText("");
                        //LoanDetailsCalculation();
                        ///repaint();
                    //else{
                    MonthlyPaymentCalculation();
                    tPayment.setText(String.valueOf(df.format(monthlyPaymentAmt)));
                    lMessages.setText("If You Would Like to Calculate a Mortgage Using Unspecified Interest/Term, Please Select 'Own Terms' From the Drop-Down Menu");
                    remainingBalance = mortgage;
                    taAmmortization.setText("");
                    LoanDetailsCalculation();
                    repaint();
                    }
                 catch (Exception ex) {
                    lMessages.setText("Invalid Entry. Please try again.");
                    ex.printStackTrace();
                    }
            } else {
                System.exit(0);
            }
    }

         public void LoanDetailsCalculation(){
            taAmmortization.append("Month No.\tMonthly Payment\tRemaining Balance\tInterest Paid\n");
            for (int i = 1; i <= years*12; i++){
                double thisPaymentInterest = (rate / 12) * remainingBalance;         // calculate the interest for the current payment
                double thisPaymentPrinciple = monthlyPaymentAmt - thisPaymentInterest;     // calculate the principle amount for the current payment
                remainingBalance = remainingBalance - thisPaymentPrinciple;             // calculate the remaining total balance
                taAmmortization.append(i + "\t" + df.format(monthlyPaymentAmt) + "\t\t" + df.format(remainingBalance) + "\t\t" + df.format(thisPaymentInterest) + "\n");  // output the monthly amounts
            }
        }

          //Mortgage Calculation
        public void MonthlyPaymentCalculation(){
            monthlyPaymentAmt = ((rate / 12) * mortgage) / (1- (Math.pow (1+ (rate / 12), (years * -12))));
        }

       public static void main(String[] args){
            MortgageCalculatorWk4 frame = new MortgageCalculatorWk4();
            frame.setTitle("McBride Mortgage Payment Calculator");
            frame.setSize(800,600);
            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
       }

}

Yes, you should use nextDouble() if that is what you are expecting to read from the file. But the InputMismatchException is saying that the scanner found something in the file that it is unable to interpret as a double. Open up the file array2.txt in Notepad or some such editor and make sure there are 3 values that can be read as doubles separated by white space (space, tab or newline).

Yes, you should use nextDouble() if that is what you are expecting to read from the file. But the InputMismatchException is saying that the scanner found something in the file that it is unable to interpret as a double. Open up the file array2.txt in Notepad or some such editor and make sure there are 3 values that can be read as doubles separated by white space (space, tab or newline).

That was exactly it. I was still using commas to separate the entries instead of white space. I had changed the first file for testing and never went back to change the second file.

Thanks to everyone for their help!

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.