I'm working on a class project for my intro to Java class. My background is in accounting/finance so I decided to make this simple calculator that helps the user decide what they can afford and how much they can save on interest expense over the loan term. I'm just looking for general feedback on code structure and tips/advice on better ways to clean up the code or make it more efficient.
Regarding layout, I chose to challenge myself and create the GUI without using Window builder and just start typing out the code. As such, I used gridlayout for ease of organization.
import javax.swing.JFrame;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Calculator calculator = new Calculator();
calculator.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
calculator.pack();
calculator.setVisible(true);
}
}
import javax.swing.JFrame;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
public class Calculator extends JFrame {
private JButton b1, b2, b3, b4;
private JTextField t1, t2, t3, t4, t5, t6, t7;
private JLabel l1, l1a, l2, l3, l4, l5, l6, l7, l8, l9, l10;
private JLabel l11, l12, l13, l14, l15, l16, l17, l18, l19, l20;
private JLabel l21, l22, l23, l24, l25, l26;
public Calculator()
{
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
JPanel panel4 = new JPanel();
panel1.setLayout(new GridLayout(6,4,10,0));
panel1.setBorder(BorderFactory.createLineBorder(Color.GRAY));
panel2.setLayout(new GridLayout(2,1));
panel2.setBackground(new Color(83, 116, 246));
panel2.setBorder(BorderFactory.createLineBorder(Color.GRAY));
panel4.setLayout(new GridLayout(6,2,10,0));
panel4.setBorder(BorderFactory.createLineBorder(Color.GRAY));
add(panel1, BorderLayout.PAGE_END);
add(panel2, BorderLayout.PAGE_START);
add(panel4, BorderLayout.CENTER);
//panel 1
l2 = new JLabel("Purchase Price");
t1 = new JTextField(10);
l2.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
l9 = new JLabel("30 Yr Monthly Payment");
l15 = new JLabel("0.00");
l15.setForeground(new Color(0, 0, 153));
l15.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
panel1.add(l2);
panel1.add(t1);
panel1.add(l9);
panel1.add(l15);
l3 = new JLabel("Down Payment (%)");
t2 = new JTextField(10);
l3.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
l10 = new JLabel("Total Interest Paid");
l16 = new JLabel("0.00");
l16.setForeground(new Color(255, 51, 0));
l16.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
panel1.add(l3);
panel1.add(t2);
panel1.add(l10);
panel1.add(l16);
l4 = new JLabel("Interest Rate (APR%)");
t3 = new JTextField(10);
l4.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
l11 = new JLabel("20 Yr Monthly Payment");
l17 = new JLabel("0.00");
l17.setForeground(new Color(0, 0, 153));
l17.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
panel1.add(l4);
panel1.add(t3);
panel1.add(l11);
panel1.add(l17);
l5 = new JLabel("Annual Property Tax");
t4 = new JTextField(10);
l5.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
l12 = new JLabel("Total Interest Paid");
l18 = new JLabel("0.00");
l18.setForeground(new Color(255, 51, 0));
l18.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
panel1.add(l5);
panel1.add(t4);
panel1.add(l12);
panel1.add(l18);
l25 = new JLabel("Include Mortgage Insurance?");
l26 = new JLabel("");
l25.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
l13 = new JLabel("15 Yr Monthly Payment");
l19 = new JLabel("0.00");
l19.setForeground(new Color(0, 0, 153));
l19.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
panel1.add(l25);
panel1.add(l26);
panel1.add(l13);
panel1.add(l19);
b1 = new JButton("Clear");
b2 = new JButton("Payments & Total Interest");
l14 = new JLabel("Total Interest Paid");
l20 = new JLabel("0.00");
l20.setForeground(new Color(255, 51, 0));
l20.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
panel1.add(b1);
panel1.add(b2);
panel1.add(l14);
panel1.add(l20);
ButtonListener bl = new ButtonListener();
b1.addActionListener(bl);
b2.addActionListener(bl);
//panel 2
l1 = new JLabel("Affordability Calculator");
l1a = new JLabel("Calculate Monthly Payments, Total Interest Expense, and your Maximum Affordability");
panel2.add(l1);
panel2.add(l1a);
l1.setFont(new Font("Helvetica", Font.BOLD,14));
l1a.setFont(new Font("Helvetica", Font.ITALIC,12));
l1.setForeground(new Color(255, 255, 255));
l1a.setForeground(new Color(255, 255, 255));
//panel 4
l6 = new JLabel("Gross Monthly Income (From wages and other taxable income)");
t5 = new JTextField(10);
l6.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
panel4.add(l6);
panel4.add(t5);
l7 = new JLabel("Recurring Monthly Debt (Car payments, other loan payments)");
t6 = new JTextField(10);
l7.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
panel4.add(l7);
panel4.add(t6);
l8 = new JLabel("Credit Card Payments (Total minimum amount due)");
t7 = new JTextField(10);
l8.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
panel4.add(l8);
panel4.add(t7);
l21 = new JLabel("Maximum Monthly Payment @ 36% Debt-to-Income");
l22 = new JLabel("0.00");
l22.setForeground(new Color(0, 0, 153));
l22.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
panel4.add(l21);
panel4.add(l22);
l23 = new JLabel("Maximum Monthly Payment @ 45% Debt-to-Income");
l24 = new JLabel("0.00");
l24.setForeground(new Color(0, 0, 153));
l24.setFont(new Font("Arial Rounded MT Bold", Font.PLAIN, 12));
panel4.add(l23);
panel4.add(l24);
b3 = new JButton("Clear");
b4 = new JButton("Calculate Max Affordability");
panel4.add(b3);
panel4.add(b4);
b3.addActionListener(bl);
b4.addActionListener(bl);
}
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
ButtonFunction bf = new ButtonFunction();
NumberFormat nf = NumberFormat.getCurrencyInstance();
if(event.getSource() == b2)
{
try
{
bf.CalcPayInt(Double.parseDouble(t1.getText()), Double.parseDouble(t2.getText()), Double.parseDouble(t3.getText()), Double.parseDouble(t4.getText()));
l15.setText(nf.format(bf.getMonthlyPay30()));
l16.setText(nf.format(bf.getTotalInt1()));
l17.setText(nf.format(bf.getMonthlyPay20()));
l18.setText(nf.format(bf.getTotalInt2()));
l19.setText(nf.format(bf.getMonthlyPay15()));
l20.setText(nf.format(bf.getTotalInt3()));
if(Double.parseDouble(t2.getText()) < 20)
{
l26.setText("Yes - avg $100/mo");
}
else
{
l26.setText("No - 20% or more down");
}
} catch(Exception e)
{
JOptionPane.showMessageDialog(null, "Please enter a valid number");
}
}
if(event.getSource() == b1)
{
t1.setText("");
t2.setText("");
t3.setText("");
t4.setText("");
l26.setText("");
l15.setText("0.00");
l16.setText("0.00");
l17.setText("0.00");
l18.setText("0.00");
l19.setText("0.00");
l20.setText("0.00");
}
if(event.getSource() == b3)
{
t5.setText("");
t6.setText("");
t7.setText("");
l22.setText("0.00");
l24.setText("0.00");
}
if(event.getSource() == b4)
{
try
{
bf.calcDTI(Double.parseDouble(t5.getText()), Double.parseDouble(t6.getText()), Double.parseDouble(t7.getText()));
l22.setText(nf.format(bf.getMaxPay1()));
l24.setText(nf.format(bf.getMaxPay2()));
}
catch(Exception e2)
{
JOptionPane.showMessageDialog(null, "Please enter a valid number");
}
}
}
}
}
public class ButtonFunction {
private double purchasePrice;
private double loanAmount;
private double monthlyIntRate;
private double downPayment;
private double monthlyTax;
private double monthlyPay1;
private double monthlyPay2;
private double monthlyPay3;
private double totalInt1;
private double totalInt2;
private double totalInt3;
private double termMonths1 = 360.0; //30 year term
private double termMonths2 = 240.0; //20 year term
private double termMonths3 = 180.0; //15 year term
private final double PMI = 100.0; //average mortgage insurance monthly cost
private double totalDebt;
private double grossIncome;
private double maxPay1;
private double maxPay2;
private final double DTI1 = .36;
private final double DTI2 = .45;
public void CalcPayInt(double purchasePrice, double downPayment, double intRate, double tax)
{
this.purchasePrice = purchasePrice;
this.downPayment = purchasePrice * (downPayment/100);
this.loanAmount = purchasePrice - this.downPayment;
this.monthlyIntRate = (intRate/100)/12;
this.monthlyTax = tax/12;
//M = P [ i(1 + i)^n ] / [ ((1 + i)^n) - 1]
monthlyPay1 = (loanAmount * ((monthlyIntRate * Math.pow((1 + monthlyIntRate),termMonths1)) /
(Math.pow((1 + monthlyIntRate), termMonths1) - 1))) + monthlyTax;
totalInt1 = ((monthlyPay1 - monthlyTax) * termMonths1) - loanAmount;
monthlyPay2 = (loanAmount * ((monthlyIntRate * Math.pow((1 + monthlyIntRate),termMonths2)) /
(Math.pow((1 + monthlyIntRate), termMonths2) - 1))) + monthlyTax;
totalInt2 = ((monthlyPay2 - monthlyTax) * termMonths2) - loanAmount;
monthlyPay3 = (loanAmount * ((monthlyIntRate * Math.pow((1 + monthlyIntRate),termMonths3)) /
(Math.pow((1 + monthlyIntRate), termMonths3) - 1))) + monthlyTax;
totalInt3 = ((monthlyPay3 - monthlyTax) * termMonths3) - loanAmount;
}
public void calcDTI(double grossIncome, double debt, double creditCards)
{
this.grossIncome = grossIncome;
this.totalDebt = debt + creditCards;
maxPay1 = (grossIncome * DTI1) - totalDebt;
maxPay2 = (grossIncome * DTI2) - totalDebt;
}
public double getMonthlyPay30()
{
if(downPayment < (purchasePrice * 0.20))
{
return monthlyPay1 + PMI;
} else
{
return monthlyPay1;
}
}
public double getMonthlyPay20()
{
if(downPayment < (purchasePrice * 0.20))
{
return monthlyPay2 + PMI;
} else
{
return monthlyPay2;
}
}
public double getMonthlyPay15()
{
if(downPayment < (purchasePrice * 0.20))
{
return monthlyPay3 + PMI;
} else
{
return monthlyPay3;
}
}
public double getTotalInt1()
{
return totalInt1;
}
public double getTotalInt2()
{
return totalInt2;
}
public double getTotalInt3()
{
return totalInt3;
}
public double getMaxPay1()
{
return maxPay1;
}
public double getMaxPay2()
{
return maxPay2;
}
}