/*PRG 421 WEEK 2
* Write the program in Java (with a graphical user interface)
* and have it calculate and display the mortgage payment amount from
* user input of the amount of the mortgage, the term of the mortgage,
* and the interest rate of the mortgage.
* Allow the user to loop back and enter new data or quit.
* Please insert comments in the program to document the program
*/
package ray8;
/**
*
* @author Ray Corry
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.text.*;
public class Main extends JPanel implements PropertyChangeListener
{
//sets initial values in the field boxes
private double amount = 200000;
private double rate = 7.5;
private int numPeriods = 30;
// field names
private JLabel amountLabel;
private JLabel rateLabel;
private JLabel numPeriodsLabel;
private JLabel paymentLabel;
//sets the names of the labels to strings
private static String amountString = "Enter Loan Amount: ";
private static String rateString = "Enter a number for the annual percentage rate : ";
private static String numPeriodsString = "Enter the term of the loan in years ";
private static String paymentString = "Monthly Payment: ";
//User input fields
private JFormattedTextField amountField;
private JFormattedTextField rateField;
private JFormattedTextField numPeriodsField;
private JFormattedTextField paymentField;
//Formats to format and parse numbers
private NumberFormat amountFormat;
private NumberFormat percentFormat;
private NumberFormat paymentFormat;
public void main ()
{
new BorderLayout();
setUpFormats();
double payment = computePayment(amount,
rate,
numPeriods);
//Create the labels.
amountLabel = new JLabel(amountString);
rateLabel = new JLabel(rateString);
numPeriodsLabel = new JLabel(numPeriodsString);
paymentLabel = new JLabel(paymentString);
//Create the text fields and set them up.
amountField = new JFormattedTextField(amountFormat);
amountField.setValue(new Double(amount));
amountField.setColumns(10);
amountField.addPropertyChangeListener("value", this);
rateField = new JFormattedTextField(percentFormat);
rateField.setValue(new Double(rate));
rateField.setColumns(10);
rateField.addPropertyChangeListener("value", this);
numPeriodsField = new JFormattedTextField();
numPeriodsField.setValue(new Integer(numPeriods));
numPeriodsField.setColumns(10);
numPeriodsField.addPropertyChangeListener("value", this);
paymentField = new JFormattedTextField(paymentFormat);
paymentField.setValue(new Double(payment));
paymentField.setColumns(10);
paymentField.setEditable(false);
paymentField.setForeground(Color.red);
//Tell accessibility tools about label and textfield pairs.
amountLabel.setLabelFor(amountField);
rateLabel.setLabelFor(rateField);
numPeriodsLabel.setLabelFor(numPeriodsField);
paymentLabel.setLabelFor(paymentField);
//Lay out the labels in a panel.
JPanel labelPane = new JPanel(new GridLayout(0,1));
labelPane.add(amountLabel);
labelPane.add(rateLabel);
labelPane.add(numPeriodsLabel);
labelPane.add(paymentLabel);
//Layout the text fields in a panel.
JPanel fieldPane = new JPanel(new GridLayout(0,1));
fieldPane.add(amountField);
fieldPane.add(rateField);
fieldPane.add(numPeriodsField);
fieldPane.add(paymentField);
//Put the panels in this panel, labels on left,
//text fields on right.
setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
add(labelPane, BorderLayout.CENTER);
add(fieldPane, BorderLayout.LINE_END);
}
/** Called when a field's "value" property changes. */
public void propertyChange(PropertyChangeEvent e) {
Object source = e.getSource();
if (source == amountField) {
amount = ((Number)amountField.getValue()).doubleValue();
} else if (source == rateField) {
rate = ((Number)rateField.getValue()).doubleValue();
} else if (source == numPeriodsField) {
numPeriods = ((Number)numPeriodsField.getValue()).intValue();
}
double payment = computePayment(amount, rate, numPeriods);
paymentField.setValue(new Double(payment));
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event dispatch thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Mortgage Calculator that killed Ray");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Add contents to the window.
frame.add (new FormattedTextFieldDemo());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Turn off metal's use of bold fonts
UIManager.put("swing.boldMetal", Boolean.FALSE);
createAndShowGUI();
}
});
}
//Compute the monthly payment based on the loan amount,
//APR, and length of loan.
double computePayment(double loanAmt, double rate, int numPeriods) {
double I, partial1, denominator, answer;
numPeriods *= 12; //get number of months
if (rate > 0.01) {
I = rate / 100.0 / 12.0; //get monthly rate from annual
partial1 = Math.pow((1 + I), (0.0 - numPeriods));
denominator = (1 - partial1) / I;
} else { //rate ~= 0
denominator = numPeriods;
}
answer = (-1 * loanAmt) / denominator;
return answer;
}
//Create and set up number formats. These objects also
//parse numbers input by user.
private void setUpFormats() {
amountFormat = NumberFormat.getNumberInstance();
percentFormat = NumberFormat.getNumberInstance();
percentFormat.setMinimumFractionDigits(3);
paymentFormat = NumberFormat.getCurrencyInstance();
}
}