import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.text.*;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.*;
import javax.swing.JTabbedPane;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.image.*;
class WarrenMortgageAppWeek5
{
public static void main(String[] args)
{
JFrame Mortgageframe = new MortgageFrame();
Mortgageframe.setVisible(true);
}
} //end of WarrenMortgageAppWeek5 class
class MortgageFrame extends JFrame
{
/* This section will set up the application window
* and size it to fit the controls. It will also
* call a routine called "centerWindow" to calculate
* the user's screen size and center the application.
* Finally it adds the panels that will hold the components.
*
*/
public MortgageFrame()
{
setTitle("Laura Warren Mortgage Calculator Week 5"); //title of frame
setSize(440, 465); //size of frame
centerWindow(this); //calls method to center window
setResizable(false); //prevents sizing
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //sets the default close action for the frame
JPanel panel = new MortgagePanel();
this.add(panel); //adds the panel to the frame's content pane
} // end MortgageFrame method
private void centerWindow(Window w)
{
Toolkit tk = Toolkit.getDefaultToolkit(); //determines number of pixels on any screen
Dimension d = tk.getScreenSize(); //and calculates center
setLocation((d.width-w.getWidth())/2, (d.height-w.getHeight())/2);
} // end of centerWindow method
}// end of MortgageFrame class
// This section will specify the controls (labels, text fields, and buttons)
// It will also declare variables and arrays
class MortgagePanel extends JPanel implements ActionListener
{
private JLabel loanAmountLabel;
private JTextField loanAmountTextField;
private JLabel totalInterestLabel; //label and text field for Annual Interest Rate
private JTextField totalInterestTextField;
private JLabel totalPrincipalLabel; //label and text field for Term of loan
private JTextField totalPrincipalField;
private JLabel monthlyPaymentLabel;
private JTextField monthlyPaymentTextField;
private JLabel errorlbl;
private JLabel rateAndTermLabel;
private JComboBox optionsCombo;
private JTable paymentsTable;
private DefaultTableModel table;
private JButton calculateButton; //the Calculate button
private JButton resetButton; //the Reset button
private JButton exitButton; //the Exit button
private JScrollPane paymentsScrollPane;
int rows = 400; //months not likely to exceed this value
int columns = 4;
int years = 0;
double monthlyRate = 0;
String columnHeadings[] = { "Pmt #", "Beg Bal", "Principle", "Interest" };
String[][]paymentData = new String[rows][columns];
int[] TermYears = {7, 15, 30};
double[] AnnualRate = {5.35, 5.5, 5.75};
DecimalFormat PmtFormat = new DecimalFormat("$#,##0.00");
/* This next section adds the components and panels to the frame.
* The extra label field will display any error messages in red.
* The frame will be divided into panels
* The first is the top panel, which includes the loan amount entry field
* The second contains the error label
* THe fourth contains the input fields for week 3 rate and term selection
* The fifth is the option panel, which contains the combo box
* The sicth is the display of the montly payment amount
* The seventh contains the table that will display amortization
*/
public MortgagePanel()
{
//this section creates the top panel
//holds the user input section for loan amount
JPanel topPanel = new JPanel(); //define the panel within the frame
topPanel.setLayout (new FlowLayout());
loanAmountLabel = new JLabel("Amount of Loan: "); //add Loan Amount label to panel
topPanel.add(loanAmountLabel);
loanAmountTextField = new JTextField(11); //set size and add Loan text field to panel
topPanel.add(loanAmountTextField); //add Loan Amount to panel
//this section creates the area for the feedback label
//messages appear in red
JPanel errorPanel= new JPanel();
errorPanel.setLayout (new FlowLayout());
errorlbl = new JLabel(" "); //set initial value for error label one
errorlbl.setForeground (Color.red);
errorPanel.add(errorlbl); //add error label to panel
//this section creates the area for the option box
JPanel optionPanel = new JPanel();
optionPanel.setLayout(new FlowLayout());
rateAndTermLabel = new JLabel("Rate / Term: ");
optionPanel.add(rateAndTermLabel);
String[]options = {"7 years at 5.35%", "15 years at 5.5%", "30 years at 5.75%"};
optionsCombo = new JComboBox(options);
optionPanel.add(optionsCombo);
//this section contains the calculated monthly payment amount
JPanel monthlyPaymentPanel = new JPanel();
monthlyPaymentLabel = new JLabel("Monthly Payment: "); //add Loan Amount label to panel
monthlyPaymentPanel.add(monthlyPaymentLabel);
monthlyPaymentTextField = new JTextField(11);
monthlyPaymentTextField.setEditable(false); //prevent editing of payment field
monthlyPaymentTextField.setFocusable(false);
monthlyPaymentPanel.add(monthlyPaymentTextField); //add field to panel
//this section contains the total interest paid amount
JPanel totalInterestPanel = new JPanel();
totalInterestLabel = new JLabel("Tot Interest Paid: "); //add Loan Amount label to panel
totalInterestPanel.add(totalInterestLabel);
totalInterestTextField = new JTextField(11);
totalInterestTextField.setEditable(false); //prevent editing of payment field
totalInterestTextField.setFocusable(false);
totalInterestPanel.add(totalInterestTextField); //add field to panel
//this section contains the total interest paid amount
JPanel totalPrinPanel = new JPanel();
totalPrincipalLabel = new JLabel("Tot Principal Paid:"); //add Loan Amount label to panel
totalPrinPanel.add(totalPrincipalLabel);
totalPrincipalField = new JTextField(11);
totalPrincipalField.setEditable(false); //prevent editing of payment field
totalPrincipalField.setFocusable(false);
totalPrinPanel.add(totalPrincipalField); //add field to panel
//This section creates a panel to display the 3 buttons
//(Calculate, Reset, and Exit)
JPanel buttonPanel = new JPanel(); //create a button panel
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); //using FlowLayout grid
calculateButton = new JButton("Calculate"); //set up Calculate button and listener
calculateButton.addActionListener(this);
buttonPanel.add(calculateButton);
resetButton = new JButton("Reset"); //set up Reset button and listener
resetButton.addActionListener(this);
buttonPanel.add(resetButton);
exitButton = new JButton("Exit"); //set up Exit button and listener
exitButton.addActionListener(this);
buttonPanel.add(exitButton);
//this section contains table and graph panes
JTabbedPane tabbedPane = new JTabbedPane();
//amort pane displays amortization table
JPanel amort = new JPanel();
tabbedPane.addTab("Table", amort);
paymentsTable = new JTable();
table = new DefaultTableModel(columnHeadings,4);
paymentsTable.setModel(table);
paymentsTable.setPreferredScrollableViewportSize(new Dimension(500, 375));
paymentsTable.setFillsViewportHeight(true);
paymentsScrollPane = new JScrollPane(paymentsTable);
amort.add(paymentsScrollPane);
table.setDataVector(paymentData, columnHeadings);
//graph pane displays pie graph
JPanel PieChartPanel = new JPanel();
tabbedPane.addTab("Graph", PieChartPanel);
//I'm not sure what to do here
//adds all sections to the main window using the GridLayout structure
this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));;
this.add(topPanel,BorderLayout.CENTER);
this.add(errorPanel,BorderLayout.CENTER);
this.add(optionPanel,BorderLayout.CENTER);
this.add(monthlyPaymentPanel,BorderLayout.CENTER);
this.add(totalInterestPanel,BorderLayout.CENTER);
this.add(totalPrinPanel, BorderLayout.CENTER);
this.add(buttonPanel, BorderLayout.CENTER);
this.add(tabbedPane, BorderLayout.CENTER);
} //end of MortgagePanel method
/*
This section defines what happens when each button is clicked.
* The Exit button will close the application.
* The Reset button will clear all fields.
* The Calculate button will test for missing loan amount
* When valid loan amount is entered, the monthly payment calculates.
*/
public void actionPerformed(ActionEvent e) throws NumberFormatException
{
Object source = e.getSource();
// Exit button has been clicked
if (source == exitButton)
System.exit(0);
// Calculate button has been clicked
if (source == calculateButton)
{
resetTable();
errorlbl.setText(" ");
double loanAmount = 0.0;
double monthlyPayment = 0.0;
double interestRate = 0.0;
//test for missing field by checking length of entry
if(loanAmountTextField.getText().length() == 0)
{
errorlbl.setText("Please enter Loan Amount");
loanAmountTextField.requestFocus();
}
else //loan amount is not blank
{
try
{
loanAmount = Double.parseDouble(loanAmountTextField.getText());
} // end try
catch(NumberFormatException p)
{
//catch null pointer exception if Principal is null
JOptionPane.showMessageDialog(null, "Invalid Entry! Please Try Again",
"ERROR", JOptionPane.ERROR_MESSAGE);
loanAmountTextField.setText("");
loanAmountTextField.requestFocus();
} // end catch number format exception
if (loanAmount <=0)
{
errorlbl.setText("Please enter a positive amount.");
loanAmountTextField.setText("");
loanAmountTextField.requestFocus();
}
else
{
errorlbl.setText("Thank you!");
//select rate and term from combination box
switch (optionsCombo.getSelectedIndex())
{
case 0:
interestRate = 5.35;
years = 7;
break;
case 1:
interestRate = 5.5;
years= 15;
break;
case 2:
interestRate = 5.75;
years = 30;
break;
} // end switch
//format and place monthly payment calculation
//call method to calculate values for Loan Amount
//calculates table
double monthlyRate = interestRate / 12 /100;
int termMonths = years * 12;
monthlyPayment = loanAmount * monthlyRate/(1-(1/Math.pow(1 + monthlyRate,termMonths)));
//declare and initialize variable for amortization calculations
double BeginningBal = Double.parseDouble(loanAmountTextField.getText());
double EndingBal;
double Principal;
double InterestPaid;
double CumInterest = 0;
double CumPrincipal = 0;
//this section loops through all payments and calculates
//Beginning Balance, Principle, and Interest Paid values
for (int MonthCounter = 1; MonthCounter <= termMonths; MonthCounter++ )
{
InterestPaid = BeginningBal * monthlyRate;
Principal = monthlyPayment - InterestPaid;
EndingBal = BeginningBal - Principal;
CumInterest = CumInterest + InterestPaid;
CumPrincipal = CumPrincipal + Principal;
//this section will fill in table values row by row until all payments calculated
paymentData[MonthCounter-1][0] = ""+MonthCounter;
paymentData[MonthCounter-1][1] = PmtFormat.format(BeginningBal);
paymentData[MonthCounter-1][2] = PmtFormat.format(Principal);
paymentData[MonthCounter-1][3] = PmtFormat.format(InterestPaid);
//the Ending Balance for one month becomes the Beginning Balance for the next
BeginningBal = EndingBal;
} // end for
monthlyPaymentTextField.setText(PmtFormat.format(monthlyPayment));
totalInterestTextField.setText(PmtFormat.format(CumInterest));
totalPrincipalField.setText(PmtFormat.format(CumPrincipal));
table.setDataVector(paymentData, columnHeadings);
} // loan amount entered
} // loan amount blank
}// end calculate button
if (source ==resetButton)
{
loanAmountTextField.setText("");
monthlyPaymentTextField.setText("");
totalInterestTextField.setText("");
totalPrincipalField.setText("");
errorlbl.setText(" ");
resetTable();
}//end if source reset
//========================================================
} // end ActionPerformed
public void resetTable()
{
//clear existing values from table and text fields
for(int MonthCounter=0; MonthCounter<=360; MonthCounter++)
{
paymentData[MonthCounter][0]=" ";
paymentData[MonthCounter][1]=" ";
paymentData[MonthCounter][2]=" ";
paymentData[MonthCounter][3]=" ";
}
table.setDataVector(paymentData, columnHeadings);
errorlbl.setText("Values Cleared");
} // end resetTable
class PieChartPanel extends JPanel
{
BufferedImage image;
final int PAD = 30;
Font font;
NumberFormat numberFormat;
public PieChartPanel()
{
font = new Font("Arial", Font.BOLD, 15);
numberFormat = NumberFormat.getPercentInstance();
addMouseListener(new Visibility(this));
addComponentListener(new ComponentAdapter()
{});
}
protected void paintComponent(Graphics graphics)
{
super.paintComponent(graphics);
Graphics2D graphics2d = (Graphics2D)graphics;
graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
createChartImage();
graphics2d.drawImage(image, 0, 0, this);
}
private void createChartImage()
{
//I would like to replace these values by total interest and total principal
int[] marks = { 199994, 220172};
int width = getWidth();
int height = getHeight();
int cp = width/2;
int cq = height/2;
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
g2.setPaint(Color.yellow);
g2.fillRect(0, 0, width, height);
g2.setPaint(Color.black);
int pie = Math.min(width,height) - 2*PAD;
g2.draw(new Ellipse2D.Double(cp - pie/2, cq - pie/2, pie, pie));
double total = 0;
for(int j = 0; j < marks.length; j++)
total += marks[j];
double theta = 0, phi = 0;
double p, q;
for(int j = 0; j < marks.length; j++)
{
p = cp + (pie/2) * Math.cos(theta);
q = cq + (pie/2) * Math.sin(theta);
g2.draw(new Line2D.Double(cp, cq, p, q));
phi = (marks[j]/total) * 2 * Math.PI;
p = cp + (9*pie/24) * Math.cos(theta + phi/2);
q = cq + (9*pie/24) * Math.sin(theta + phi/2);
g2.setFont(font);
String st = String.valueOf(marks[j]);
FontRenderContext frc = g2.getFontRenderContext();
float textWidth = (float)font.getStringBounds(st, frc).getWidth();
LineMetrics lm = font.getLineMetrics(st, frc);
float sp = (float)(p - textWidth/2);
float sq = (float)(q + lm.getAscent()/2);
g2.drawString(st, sp, sq);
p = cp + (pie/2 + 4*PAD/5) * Math.cos(theta + phi/2);
q = cq + (pie/2 + 4*PAD/5) * Math.sin(theta+ phi/2);
st = numberFormat.format(marks[j]/total);
textWidth = (float)font.getStringBounds(st, frc).getWidth();
lm = font.getLineMetrics(st, frc);
sp = (float)(p - textWidth/2);
sq = (float)(q + lm.getAscent()/2);
g2.drawString(st, sp, sq);
theta += phi;
}
g2.dispose();
}
public void toggleVisibility()
{
repaint();
}
}
class Visibility extends MouseAdapter
{
PieChartPanel piechart;
public Visibility(PieChartPanel pc)
{
piechart = pc;
}
}
} // end MortgagePanel class |