View Single Post
  #1 (permalink)  
Old 07-30-2007, 12:48 AM
rhivka rhivka is offline
Member
 
Join Date: Jul 2007
Posts: 11
rhivka is on a distinguished road
Problem with Sequential File and Arrays
Hey guys! I'm new to this forum, but I am desperately needing some help with this program. I normally post to Experts-Exchange but I'm getting no help there. I'm afraid I'm in over my head with this one. I've been working on this a few days now and I just can't get it working. I've tried to clean it up and separate the logic from the UI (I know you Java guru's hate when it's not seperate)...but any changes in these areas throw up more errors so I apologize if my code is a mess. The program is a mortgage calculator that should read the interest rates and terms for the arrays from an external text file. Then add a graph that displays the change in principal balance over the life of the loan.

Maybe I'm making it into a lot more than it is...but any help to clean up this mess would be greatly appreciated!

Code:
import java.awt.*; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Locale; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.Reader; import java.text.MessageFormat; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; public class Wk5SunniMortgageCalculator extends JFrame implements ActionListener { int term = 0; double principal = 0; double rate = 0; double monthlyPayment = 0; double interest = 0; int notePeriod = 0; int[] termArray; double[] rateArray; private float[] monthlyPrincipal; private float[] interestPaid; //reading from sequential file public void load() { Reader fis; try { fis = new InputStreamReader(getClass().getResourceAsStream("data.txt")); BufferedReader b = new BufferedReader( fis ); String[] line = b.readLine( ).split(","); termArray = new int[line.length]; for ( int i = 0; i < line.length; i++ ) { termArray[ i ] = Integer.parseInt(line[i].trim()); } line = b.readLine( ).split(","); rateArray = new double[line.length]; for ( int i = 0; i < line.length; i++ ) { rateArray[ i ] = Double.parseDouble(line[i].trim()); } b.close(); fis.close(); } catch ( Exception e1 ) { e1.printStackTrace( ); } } JPanel row1 = new JPanel(); JLabel mortgageLabel = new JLabel("MORTGAGE PAYMENT CALCULATOR", JLabel.CENTER); JPanel row2 = new JPanel(new GridLayout(1, 2)); JLabel principalLabel = new JLabel("Mortgage Principal $",JLabel.LEFT); JTextField principalTxt = new JTextField(10); JPanel row3 = new JPanel(new GridLayout(1, 2)); JLabel termLabel = new JLabel("Mortgage Term (Yrs)",JLabel.LEFT); JTextField termTxt = new JTextField(10); JPanel row4 = new JPanel(new GridLayout(1, 2)); JLabel rateLabel = new JLabel("Interest Rate (%)", JLabel.LEFT); JTextField rateTxt = new JTextField(10); JPanel row5 = new JPanel(new GridLayout(1, 2)); JLabel presetLabel = new JLabel("Preset Term and Interest Rate:", JLabel.LEFT); JPanel row6 = new JPanel(); JComboBox choices = new; JComboBox(); MessageFormat mf = new MessageFormat("{0} years at {1,number,#.##}%"); JLabel choiceLabel = new JLabel(" (choose rate)"); for (int i = 0; i < termArray.length; i++) { options.addItem(mf.format(new Object[] { new Integer(termArray [i]), new Double(rateArray[i])})); } JPanel row6 = new JPanel(new GridLayout(1, 2)); JLabel monthlyPaymentLabel = new JLabel("Monthly Payment $", JLabel.LEFT); JTextField monthlyPaymentTxt = new JTextField(10); //create buttons JPanel button = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10)); JButton graphButton = new JButton("Display Graph"); JButton amortizeButton = new JButton("Amortize Payments"); JButton clearButton = new JButton("Clear"); JButton exitButton = new JButton("Exit"); JButton calculateButton = new JButton("Calculate"); //create textarea to display Amortize output JTextArea displayArea = new JTextArea(10, 45); JScrollPane scroll = new JScrollPane(displayArea); public Wk5SunniMortgageCalculator() { super ("Mortgage Payment Calculator by S Kemen"); setSize(550, 500); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container pane = getContentPane(); } public void init() { Border rowborder = new EmptyBorder( 3, 10, 3, 10 ); pane.add(row1); row1.add(mortgageLabel); row1.setMaximumSize( new Dimension( 10000, row1.getMinimumSize().height)); row1.setBorder( rowborder); pane.add(row2); row2.add(principalLabel); row2.add(principalTxt); row2.setMaximumSize( new Dimension( 10000, row2.getMinimumSize().height)); row2.setBorder( rowborder); pane.add(row3); row3.add(termLabel); row3.add(termTxt); row3.setMaximumSize( new Dimension( 10000, row3.getMinimumSize().height)); row3.setBorder( rowborder); pane.add(row4); row4.add(rateLabel); row4.add(rateTxt); row4.setMaximumSize( new Dimension( 10000, row4.getMinimumSize().height)); row4.setBorder( rowborder); pane.add(row5); row5.add(presetLabel); row5.setMaximumSize( new Dimension( 10000, row4.getMinimumSize().height)); row5.setBorder( rowborder); pane.add(row6); row6.add(choiceLabel); row6.setMaximumSize( new Dimension( 10000, row4.getMinimumSize().height)); row6.setBorder( rowborder); radioPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 4, 4 )); radioPanel.add(choices); pane.add(radioPanel); radioPanel.setMaximumSize( new Dimension( 10000, radioPanel.getMinimumSize().height)); radioPanel.setBorder( rowborder); pane.add(row7); row7.add(monthlyPaymentLabel); row7.add(monthlyPaymentTxt); monthlyPaymentTxt.setEnabled(false); //set payment amount uneditable row7.setMaximumSize( new Dimension( 10000, row5.getMinimumSize().height)); row7.setBorder( rowborder); //Add buttons button.add(calculateButton); button.add(clearButton); button.add(exitButton); button.add(amortizeButton); button.add(graphButton); pane.add(button); button.setMaximumSize( new Dimension( 10000, button.getMinimumSize().height)); //scroll text pane for Amortize output scroll.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); pane.add(scroll); pane.setLayout(new BoxLayout( pane, BoxLayout.Y_AXIS)); setVisible(true); setContentPane(pane); //add listeners for buttons and combo box choice.addActionListener(this); clearButton.addActionListener(this); exitButton.addActionListener(this); calculateButton.addActionListener(this); amortizeButton.addActionListener(this); graphButton.addActionListener(this); } private JFrame mFrame = null; public void actionPerformed(ActionEvent event) { Object command = event.getSource(); if(command == calculateButton) //function for Calculate button { try { principal = Double.parseDouble(principalTxt.getText()); } catch(NumberFormatException e) { //catch null pointer exception if Principal is null JOptionPane.showMessageDialog(null, "Invaild Entry! Please Try Again", "ERROR", JOptionPane.ERROR_MESSAGE); } try { //Get input from Term text box, checked first before combo box term = Integer.parseInt(termTxt.getText()); rate = Double.parseDouble(rateTxt.getText()); //Input from Rate text box } //If Term and Rate are null, buttons are checked for input values catch(NumberFormatException e) { //Set rate and term based on which item in the combobox is selected //Still have to fill in this area for the combo box arrays if else { //If no option is selected and combo box null, this is an actual error. JOptionPane.showMessageDialog(null, "Invaild Entry! Please Try Again", "ERROR", JOptionPane.ERROR_MESSAGE); } } interest = rate / 100 / 12; //Monthly interst rate notePeriod= term * 12; //Number of months over which loan is amortized //calculation formula monthlyPayment = (principal * interest) / (1 - Math.pow(1 + interest, -notePeriod)); //formatting variables DecimalFormat df = new DecimalFormat("\u00A4#,##0.00"); //currency DecimalFormat pf = new DecimalFormat("#,##0.00%"); //percentages DecimalFormat mi = new DecimalFormat("#,##0.000%"); //percentages monthlyPaymentTxt.setText("" + df.format(monthlyPayment)); } if(command == clearButton) //Function for Clear button { principalTxt.setText(null); monthlyPaymentTxt.setText(null); rateTxt.setText(null); termTxt.setText(null); displayArea.setText(null); } if(command == exitButton) //Function for Exit button { System.exit(0); } if (command == amortizeButton) //Function for Amortize button { //Amoritization variables double loanBalance = notePeriod * monthlyPayment; double interestPaid = 0; //Interest paid on the loan double monthlyPrincipal = 0; //Principal in each monthly payment double principalBalance = principal; //running total of principal after payment String titles = "Month\t Principal\t\tInterest\t\tBalance\n"; //String for output displayArea.setText(titles); displayArea.append(""); //Inserts a blank line //This loop is used to calculate and display the payment schedule information for(int counter = 0; counter < term * 12 - 0; counter++) //start outer loop { //start inner loop nterestPaid = principalBalance * interest; monthlyPrincipal = monthlyPayment - interestPaid; loanBalance = loanBalance - monthlyPayment; principalBalance = principalBalance - monthlyPrincipal; //formatting variables DecimalFormat df = new DecimalFormat("\u00A4#,##0.00"); //currency DecimalFormat pf = new DecimalFormat("#,##0.00%"); //percentages DecimalFormat mi = new DecimalFormat("#,##0.000%"); //percentages //formatting for output displayArea.setCaretPosition(0); displayArea.append((counter +1) + ")\t"+df.format(monthlyPrincipal)+"\t\t" +df.format(interestPaid)+"\t\t"+df.format(principalBalance)+"\n"); } } if (command == graphButton) //Function for Graph button { mFrame = new JFrame("Mortgage Payment Graph"); mFrame.getContentPane().add(new GraphPanel(monthlyPrincipal, interestPaid)); mFrame.setSize(800,600); mFrame.setLocation(200,100); } } class GraphPanel extends JPanel { final int HPAD = 60, VPAD = 40; int[] data; float[] principleData; float[] interestData; public GraphPanel(float[] p, float[] i) { principleData = p; interestData = i; font = new Font("lucida sans regular", Font.PLAIN, 16); setBackground(Color.white); } protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setFont(font); FontRenderContext frc = g2.getFontRenderContext(); int w = getWidth(); int h = getHeight(); // scales float xInc = (w - HPAD - VPAD) / (interestData.length - 1);//11f; //distance between each plot float yInc = (h - 2*VPAD) / 10f; int[] dataVals = getDataVals(); //min and max values for y-axis float yScale = dataVals[2] / 10f; // ordinate (y - axis) g2.draw(new Line2D.Double(HPAD, VPAD, HPAD, h - VPAD)); // plot tic marks float x1 = HPAD, y1 = VPAD, x2 = HPAD - 3, y2; for(int j = 0; j < 10; j++) { g2.draw(new Line2D.Double(x1, y1, x2, y1)); y1 += yInc; } // labels String text; LineMetrics lm; float xs, ys, textWidth, height; for(int j = 0; j <= 10; j++) { text = String.valueOf(dataVals[1] - (int)(j * yScale)); textWidth = (float)font.getStringBounds(text, frc).getWidth(); lm = font.getLineMetrics(text, frc); height = lm.getAscent(); xs = HPAD - textWidth - 7; ys = VPAD + (j * yInc) + height/2; g2.drawString(text, xs, ys); if(j == 0) g2.drawString("Principal", xs, ys - 15); } // abcissa (x - axis) g2.draw(new Line2D.Double(HPAD, h - VPAD, w - VPAD, h - VPAD)); // tic marks x1 = HPAD; y1 = h - VPAD; y2 = y1 + 3; for(int j = 0; j < interestData.length; j++) { g2.draw(new Line2D.Double(x1, y1, x1, y2)); x1 += xInc; } // labels ys = h - VPAD; for(int j = 0; j < interestData.length; j++) { text = String.valueOf(j + 1); textWidth = (float)font.getStringBounds(text, frc).getWidth(); lm = font.getLineMetrics(text, frc); height = lm.getHeight(); xs = HPAD + j * xInc - textWidth/2; g2.drawString(text, xs, ys + height); if( j == (interestData.length - 1)) g2.drawString("Year", (int)w /2 , ys + height + 15); } // plot data float yy2 = 0, yy1 = 0, xx2 = 0, xx1; x1 = HPAD; xx1 = HPAD; yScale = (float)(h - 2*VPAD) / dataVals[2]; for(int j = 0; j < interestData.length; j++) { g.setColor(Color.blue); y1 = VPAD + (h - 2*VPAD) - (principalData[j] - dataVals[0]) * yScale; g2.fillOval((int)x1, (int)y1 - 2, 5, 5); if(j > 0) g2.draw(new Line2D.Double(x1, y1, x2, y2)); x2 = x1; y2 = y1; x1 += xInc; g.setColor(Color.red); yy1 = VPAD + (h - 2*VPAD) - (interestData[j] - dataVals[0]) * yScale; g2.fillOval((int)xx1, (int)yy1 - 1, 5, 5); if(j > 0) g2.draw(new Line2D.Double(xx1, yy1, xx2, yy2)); xx2 = xx1; yy2 = yy1; xx1 += xInc; } } private int[] getDataVals() { int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; int j = interestData.length -1; max = (int)principleData[j]; min = (int)interestData[j]; int span = max - min; return new int[] { min, max, span }; } } public static void main (String[] arguments) //Main Method { Wk5SunniMortgageCalculator smc = new Wk5SunniMortgageCalculator(); smc.setVisible(true); smc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } //End of program
The external file (data.txt) contains the following:
7,5.35
15,5.5
20,5.65
30,5.75

Feel free to criticize or offer advice Thank you!
Reply With Quote
Sponsored Links