Does this mortgage calculator adhere to good coding style or is the Listener class too cluttered? The 2019 Stack Overflow Developer Survey Results Are InIs this a good implementation of the Factory Pattern?Is this a good implementation of a thread-safe singleton using the observer pattern?Is this Sudoku a good use of the Fluent Builder Pattern?Is this a good approach for a BayeuxClient class?Is it a good choice to define my own JSON util class like this?Is this a good example of the composite pattern?Is this non-recursive mergesort efficient and a good way to simulate the recursive version?Why does the new ADT create a static inner class Fragment by default?Is this too much work for 1 listener?Does my Game class have too many responsibilities?

What is the best strategy for white in this position?

The difference between dialogue marks

How to make payment on the internet without leaving a money trail?

What does "sndry explns" mean in one of the Hitchhiker's guide books?

aging parents with no investments

What is the meaning of Triage in Cybersec world?

Deadlock Graph and Interpretation, solution to avoid

Why is Grand Jury testimony secret?

Geography at the pixel level

What is this 4-propeller plane?

I looked up a future colleague on LinkedIn before I started a job. I told my colleague about it and he seemed surprised. Should I apologize?

Why do UK politicians seemingly ignore opinion polls on Brexit?

How to manage monthly salary

Patience, young "Padovan"

Extreme, unacceptable situation and I can't attend work tomorrow morning

Confusion about non-derivable continuous functions

How long do I have to send payment?

Is it possible for the two major parties in the UK to form a coalition with each other instead of a much smaller party?

"What time...?" or "At what time...?" - what is more grammatically correct?

What are the motivations for publishing new editions of an existing textbook, beyond new discoveries in a field?

If a poisoned arrow's piercing damage is reduced to 0, do you still get poisoned?

Are there any other methods to apply to solving simultaneous equations?

How come people say “Would of”?

Is domain driven design an anti-SQL pattern?



Does this mortgage calculator adhere to good coding style or is the Listener class too cluttered?



The 2019 Stack Overflow Developer Survey Results Are InIs this a good implementation of the Factory Pattern?Is this a good implementation of a thread-safe singleton using the observer pattern?Is this Sudoku a good use of the Fluent Builder Pattern?Is this a good approach for a BayeuxClient class?Is it a good choice to define my own JSON util class like this?Is this a good example of the composite pattern?Is this non-recursive mergesort efficient and a good way to simulate the recursive version?Why does the new ADT create a static inner class Fragment by default?Is this too much work for 1 listener?Does my Game class have too many responsibilities?



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








0












$begingroup$


New to Java, just finished the Helsinki MOOC course. I programmed a basic mortgage calculator as my first solo project and while it works, I have a few questions about coding style:



1) The listener and ui classes are cluttered with variables at the top. Is this acceptable or is there a cleaner way of organizing it?



2) Is initializing the variables in the CalcLogic class as strings and then creating new BigDecimal variables in the methods an accepted way of using BigDecimal, or would it better to initialize the variables as BigDecimals?



3) Are there any other coding style or logic issues that are noticeable?



CalcLogic Class:



package mortgagecalculator.logic;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
* Logic for mortgage calculator.
* Input variables for home value, loan term, etc. and outputs EMI, total payment, etc.
*
*/

public class CalcLogic

//Variables for calculating mortgage. propTax, homeIns, etc are not initialized in constructor
private String principal = "0";
private String downPayment = "0";
private String interestRate = "0";
private int loanTerm = 0;
private String propTax = "0";
private String homeIns = "0";
private String hoaFee = "0";
private String pmiRate = "0";

public void setPrincipal(String principal)
this.principal = principal;


public void setDownPayment(String downPayment)
this.downPayment = downPayment;


public void setInterest(String interestRate)
this.interestRate = interestRate;


public void setLoanTerm(int loanTerm)
this.loanTerm = loanTerm;


public void setPropTax(String propTax)
this.propTax = propTax;


public void setHomeIns(String homeIns)
this.homeIns = homeIns;


public void setHOAfee(String hoaFee)
this.hoaFee = hoaFee;


public void setPMIrate(String pmiRate)
this.pmiRate = pmiRate;


//Returns principal minus downpayment
public BigDecimal getInitialAmount()
return new BigDecimal(this.principal).subtract(new BigDecimal(this.downPayment));


//Returns twenty percent of principal
public BigDecimal twentyDown()
BigDecimal twenty = new BigDecimal("20").divide(new BigDecimal("100"));
return new BigDecimal(this.principal).multiply(twenty);


public BigDecimal monthlyInterest()
return new BigDecimal(this.interestRate).divide(new BigDecimal("100"))
.divide(new BigDecimal("12"), 8, RoundingMode.UP);


public BigDecimal monthlyPMI()

try
BigDecimal result = getInitialAmount().divide(new BigDecimal(this.pmiRate).divide(new BigDecimal("100"))
.divide(new BigDecimal("12")), 2, RoundingMode.UP);
return result;

catch (Exception e)
return BigDecimal.ZERO;




public BigDecimal additionalTax()
BigDecimal sum = new BigDecimal(this.propTax);
sum = sum.add(new BigDecimal(this.homeIns)).add(new BigDecimal(this.hoaFee));
return sum;


public BigDecimal getEMI()
BigDecimal value = monthlyInterest().add(BigDecimal.ONE);
value = value.pow(this.loanTerm * 12);

BigDecimal numerator = value.multiply(monthlyInterest()).multiply(getInitialAmount());
BigDecimal denominator = value.subtract(BigDecimal.ONE);

return numerator.divide(denominator, 2, RoundingMode.UP);



public BigDecimal monthlyPayment()
BigDecimal result = getEMI().add(monthlyPMI()).add(additionalTax());
return result;


public BigDecimal totalInterest()
BigDecimal result = getEMI().multiply(new BigDecimal(this.loanTerm * 12));
result = result.subtract(getInitialAmount());
return result;


//Returns month where principal payments first exceed interest payments
public int amortMonth()
BigDecimal remaining = getInitialAmount().setScale(2, RoundingMode.CEILING);

for (int i = 0; i < this.loanTerm * 12; i++)

BigDecimal interPay = remaining.multiply(monthlyInterest()).setScale(2, RoundingMode.CEILING);
BigDecimal princPay = getEMI().subtract(interPay).setScale(2, RoundingMode.CEILING);

if (princPay.compareTo(interPay) == 1)
return i + 1;


remaining = remaining.subtract(princPay).setScale(2, RoundingMode.CEILING);



return 0;





CalcListener Class:



package mortgagecalculator.ui;

import mortgagecalculator.logic.CalcLogic;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.math.BigDecimal;

public class CalcListener implements ActionListener

private JTextField principal;
private JTextField downPayment;
private JTextField interestRate;
private JTextField loanTerm;
private JTextField propTax;
private JTextField homeIns;
private JTextField hoaFee;
private JTextField pmiRate;
private JButton button;
private JTextField EMI;
private JTextField monthlyFee;
private JTextField totalInt;
private JTextField changeMonth;
private CalcLogic calc;

public CalcListener(JTextField principal, JTextField downPayment, JTextField interestRate,
JTextField loanTerm, JTextField propTax, JTextField homeIns,
JTextField hoaFee, JTextField pmiRate, JTextField EMI,
JTextField monthlyFee, JTextField totalInt, JTextField changeMonth, JButton button)
this.principal = principal;
this.downPayment = downPayment;
this.interestRate = interestRate;
this.loanTerm = loanTerm;
this.propTax = propTax;
this.homeIns = homeIns;
this.hoaFee = hoaFee;
this.pmiRate = pmiRate;
this.button = button;
this.EMI = EMI;
this.monthlyFee = monthlyFee;
this.totalInt = totalInt;
this.changeMonth = changeMonth;
this.calc = new CalcLogic();


@Override
public void actionPerformed(ActionEvent ae)

if (ae.getSource() == this.button)

this.calc.setPrincipal(this.principal.getText());
this.calc.setDownPayment(this.downPayment.getText());
this.calc.setInterest(this.interestRate.getText());
this.calc.setLoanTerm(Integer.parseInt(this.loanTerm.getText()));
this.calc.setPropTax(this.propTax.getText());
this.calc.setHomeIns(this.homeIns.getText());
this.calc.setPMIrate(this.pmiRate.getText());
this.calc.setHOAfee(this.hoaFee.getText());

this.EMI.setText(this.calc.getEMI().toString());
this.monthlyFee.setText(this.calc.monthlyPayment().toString());
this.totalInt.setText(this.calc.totalInterest().toString());
this.changeMonth.setText(String.valueOf(this.calc.amortMonth()));







UserInterface Class:



package mortgagecalculator.ui;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.*;
import mortgagecalculator.ui.CalcListener;

public class UserInterface implements Runnable

private JFrame frame;
private JTextField principal;
private JTextField downPayment;
private JTextField interestRate;
private JTextField loanTerm;
private JTextField propTax;
private JTextField homeIns;
private JTextField hoaFee;
private JTextField pmiRate;
private JButton button;
private JTextField EMI;
private JTextField monthlyFee;
private JTextField totalInt;
private JTextField changeMonth;

@Override
public void run()
frame = new JFrame("Mortgage Calculator");
frame.setPreferredSize(new Dimension(1000, 1000));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

createComponents(frame.getContentPane());

frame.pack();
frame.setVisible(true);



private void createComponents(Container container)
generateVariables();
container.setLayout(new GridLayout(3, 1));

container.add(createInputPanel());
container.add(this.button);
container.add(createOutputPanel());



private void generateVariables()
this.principal = new JTextField("");
this.downPayment = new JTextField("");
this.interestRate = new JTextField("");
this.loanTerm = new JTextField("");
this.propTax = new JTextField("");
this.homeIns = new JTextField("");
this.hoaFee = new JTextField("");
this.pmiRate = new JTextField("");
this.EMI = new JTextField("");
this.monthlyFee = new JTextField("");
this.totalInt = new JTextField("");
this.changeMonth = new JTextField("");
this.button = new JButton("Calculate!");

CalcListener calc = new CalcListener(this.principal, this.downPayment, this.interestRate,
this.loanTerm, this.propTax, this.homeIns, this.hoaFee,
this.pmiRate, this.EMI, this.monthlyFee, this.totalInt,
this.changeMonth, this.button);

this.button.addActionListener(calc);


private JPanel createInputPanel()
JPanel panel = new JPanel(new GridLayout(4, 4));
panel.add(new JLabel("Principal"));
panel.add(new JLabel("Down Payment"));
panel.add(new JLabel("Interest Rate (in %)"));
panel.add(new JLabel("Loan term (in years)"));
panel.add(this.principal);
panel.add(this.downPayment);
panel.add(this.interestRate);
panel.add(this.loanTerm);

panel.add(new JLabel("Property Tax (Monthly)"));
panel.add(new JLabel("Home Insurance (Monthly)"));
panel.add(new JLabel("HOA Fees (Monthly)"));
panel.add(new JLabel("PMI Rate (in %)"));
panel.add(this.propTax);
panel.add(this.homeIns);
panel.add(this.hoaFee);
panel.add(this.pmiRate);

return panel;


private JPanel createOutputPanel()
JPanel panel = new JPanel(new GridLayout(4, 2));

panel.add(new JLabel("Equated Monthly Installment"));
panel.add(new JLabel("Monthly w/ fees"));
panel.add(this.EMI);
panel.add(this.monthlyFee);

panel.add(new JLabel("Total Interest Payments"));
panel.add(new JLabel("Month where principal payments > interest"));
panel.add(this.totalInt);
panel.add(this.changeMonth);

return panel;


public JFrame getFrame()
return frame;










share







New contributor




JeremiahDixon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$


















    0












    $begingroup$


    New to Java, just finished the Helsinki MOOC course. I programmed a basic mortgage calculator as my first solo project and while it works, I have a few questions about coding style:



    1) The listener and ui classes are cluttered with variables at the top. Is this acceptable or is there a cleaner way of organizing it?



    2) Is initializing the variables in the CalcLogic class as strings and then creating new BigDecimal variables in the methods an accepted way of using BigDecimal, or would it better to initialize the variables as BigDecimals?



    3) Are there any other coding style or logic issues that are noticeable?



    CalcLogic Class:



    package mortgagecalculator.logic;

    import java.math.BigDecimal;
    import java.math.RoundingMode;

    /**
    * Logic for mortgage calculator.
    * Input variables for home value, loan term, etc. and outputs EMI, total payment, etc.
    *
    */

    public class CalcLogic

    //Variables for calculating mortgage. propTax, homeIns, etc are not initialized in constructor
    private String principal = "0";
    private String downPayment = "0";
    private String interestRate = "0";
    private int loanTerm = 0;
    private String propTax = "0";
    private String homeIns = "0";
    private String hoaFee = "0";
    private String pmiRate = "0";

    public void setPrincipal(String principal)
    this.principal = principal;


    public void setDownPayment(String downPayment)
    this.downPayment = downPayment;


    public void setInterest(String interestRate)
    this.interestRate = interestRate;


    public void setLoanTerm(int loanTerm)
    this.loanTerm = loanTerm;


    public void setPropTax(String propTax)
    this.propTax = propTax;


    public void setHomeIns(String homeIns)
    this.homeIns = homeIns;


    public void setHOAfee(String hoaFee)
    this.hoaFee = hoaFee;


    public void setPMIrate(String pmiRate)
    this.pmiRate = pmiRate;


    //Returns principal minus downpayment
    public BigDecimal getInitialAmount()
    return new BigDecimal(this.principal).subtract(new BigDecimal(this.downPayment));


    //Returns twenty percent of principal
    public BigDecimal twentyDown()
    BigDecimal twenty = new BigDecimal("20").divide(new BigDecimal("100"));
    return new BigDecimal(this.principal).multiply(twenty);


    public BigDecimal monthlyInterest()
    return new BigDecimal(this.interestRate).divide(new BigDecimal("100"))
    .divide(new BigDecimal("12"), 8, RoundingMode.UP);


    public BigDecimal monthlyPMI()

    try
    BigDecimal result = getInitialAmount().divide(new BigDecimal(this.pmiRate).divide(new BigDecimal("100"))
    .divide(new BigDecimal("12")), 2, RoundingMode.UP);
    return result;

    catch (Exception e)
    return BigDecimal.ZERO;




    public BigDecimal additionalTax()
    BigDecimal sum = new BigDecimal(this.propTax);
    sum = sum.add(new BigDecimal(this.homeIns)).add(new BigDecimal(this.hoaFee));
    return sum;


    public BigDecimal getEMI()
    BigDecimal value = monthlyInterest().add(BigDecimal.ONE);
    value = value.pow(this.loanTerm * 12);

    BigDecimal numerator = value.multiply(monthlyInterest()).multiply(getInitialAmount());
    BigDecimal denominator = value.subtract(BigDecimal.ONE);

    return numerator.divide(denominator, 2, RoundingMode.UP);



    public BigDecimal monthlyPayment()
    BigDecimal result = getEMI().add(monthlyPMI()).add(additionalTax());
    return result;


    public BigDecimal totalInterest()
    BigDecimal result = getEMI().multiply(new BigDecimal(this.loanTerm * 12));
    result = result.subtract(getInitialAmount());
    return result;


    //Returns month where principal payments first exceed interest payments
    public int amortMonth()
    BigDecimal remaining = getInitialAmount().setScale(2, RoundingMode.CEILING);

    for (int i = 0; i < this.loanTerm * 12; i++)

    BigDecimal interPay = remaining.multiply(monthlyInterest()).setScale(2, RoundingMode.CEILING);
    BigDecimal princPay = getEMI().subtract(interPay).setScale(2, RoundingMode.CEILING);

    if (princPay.compareTo(interPay) == 1)
    return i + 1;


    remaining = remaining.subtract(princPay).setScale(2, RoundingMode.CEILING);



    return 0;





    CalcListener Class:



    package mortgagecalculator.ui;

    import mortgagecalculator.logic.CalcLogic;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JTextField;
    import javax.swing.JButton;
    import java.math.BigDecimal;

    public class CalcListener implements ActionListener

    private JTextField principal;
    private JTextField downPayment;
    private JTextField interestRate;
    private JTextField loanTerm;
    private JTextField propTax;
    private JTextField homeIns;
    private JTextField hoaFee;
    private JTextField pmiRate;
    private JButton button;
    private JTextField EMI;
    private JTextField monthlyFee;
    private JTextField totalInt;
    private JTextField changeMonth;
    private CalcLogic calc;

    public CalcListener(JTextField principal, JTextField downPayment, JTextField interestRate,
    JTextField loanTerm, JTextField propTax, JTextField homeIns,
    JTextField hoaFee, JTextField pmiRate, JTextField EMI,
    JTextField monthlyFee, JTextField totalInt, JTextField changeMonth, JButton button)
    this.principal = principal;
    this.downPayment = downPayment;
    this.interestRate = interestRate;
    this.loanTerm = loanTerm;
    this.propTax = propTax;
    this.homeIns = homeIns;
    this.hoaFee = hoaFee;
    this.pmiRate = pmiRate;
    this.button = button;
    this.EMI = EMI;
    this.monthlyFee = monthlyFee;
    this.totalInt = totalInt;
    this.changeMonth = changeMonth;
    this.calc = new CalcLogic();


    @Override
    public void actionPerformed(ActionEvent ae)

    if (ae.getSource() == this.button)

    this.calc.setPrincipal(this.principal.getText());
    this.calc.setDownPayment(this.downPayment.getText());
    this.calc.setInterest(this.interestRate.getText());
    this.calc.setLoanTerm(Integer.parseInt(this.loanTerm.getText()));
    this.calc.setPropTax(this.propTax.getText());
    this.calc.setHomeIns(this.homeIns.getText());
    this.calc.setPMIrate(this.pmiRate.getText());
    this.calc.setHOAfee(this.hoaFee.getText());

    this.EMI.setText(this.calc.getEMI().toString());
    this.monthlyFee.setText(this.calc.monthlyPayment().toString());
    this.totalInt.setText(this.calc.totalInterest().toString());
    this.changeMonth.setText(String.valueOf(this.calc.amortMonth()));







    UserInterface Class:



    package mortgagecalculator.ui;

    import java.awt.Container;
    import java.awt.Dimension;
    import java.awt.BorderLayout;
    import java.awt.GridLayout;
    import javax.swing.*;
    import mortgagecalculator.ui.CalcListener;

    public class UserInterface implements Runnable

    private JFrame frame;
    private JTextField principal;
    private JTextField downPayment;
    private JTextField interestRate;
    private JTextField loanTerm;
    private JTextField propTax;
    private JTextField homeIns;
    private JTextField hoaFee;
    private JTextField pmiRate;
    private JButton button;
    private JTextField EMI;
    private JTextField monthlyFee;
    private JTextField totalInt;
    private JTextField changeMonth;

    @Override
    public void run()
    frame = new JFrame("Mortgage Calculator");
    frame.setPreferredSize(new Dimension(1000, 1000));
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    createComponents(frame.getContentPane());

    frame.pack();
    frame.setVisible(true);



    private void createComponents(Container container)
    generateVariables();
    container.setLayout(new GridLayout(3, 1));

    container.add(createInputPanel());
    container.add(this.button);
    container.add(createOutputPanel());



    private void generateVariables()
    this.principal = new JTextField("");
    this.downPayment = new JTextField("");
    this.interestRate = new JTextField("");
    this.loanTerm = new JTextField("");
    this.propTax = new JTextField("");
    this.homeIns = new JTextField("");
    this.hoaFee = new JTextField("");
    this.pmiRate = new JTextField("");
    this.EMI = new JTextField("");
    this.monthlyFee = new JTextField("");
    this.totalInt = new JTextField("");
    this.changeMonth = new JTextField("");
    this.button = new JButton("Calculate!");

    CalcListener calc = new CalcListener(this.principal, this.downPayment, this.interestRate,
    this.loanTerm, this.propTax, this.homeIns, this.hoaFee,
    this.pmiRate, this.EMI, this.monthlyFee, this.totalInt,
    this.changeMonth, this.button);

    this.button.addActionListener(calc);


    private JPanel createInputPanel()
    JPanel panel = new JPanel(new GridLayout(4, 4));
    panel.add(new JLabel("Principal"));
    panel.add(new JLabel("Down Payment"));
    panel.add(new JLabel("Interest Rate (in %)"));
    panel.add(new JLabel("Loan term (in years)"));
    panel.add(this.principal);
    panel.add(this.downPayment);
    panel.add(this.interestRate);
    panel.add(this.loanTerm);

    panel.add(new JLabel("Property Tax (Monthly)"));
    panel.add(new JLabel("Home Insurance (Monthly)"));
    panel.add(new JLabel("HOA Fees (Monthly)"));
    panel.add(new JLabel("PMI Rate (in %)"));
    panel.add(this.propTax);
    panel.add(this.homeIns);
    panel.add(this.hoaFee);
    panel.add(this.pmiRate);

    return panel;


    private JPanel createOutputPanel()
    JPanel panel = new JPanel(new GridLayout(4, 2));

    panel.add(new JLabel("Equated Monthly Installment"));
    panel.add(new JLabel("Monthly w/ fees"));
    panel.add(this.EMI);
    panel.add(this.monthlyFee);

    panel.add(new JLabel("Total Interest Payments"));
    panel.add(new JLabel("Month where principal payments > interest"));
    panel.add(this.totalInt);
    panel.add(this.changeMonth);

    return panel;


    public JFrame getFrame()
    return frame;










    share







    New contributor




    JeremiahDixon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.







    $endgroup$














      0












      0








      0





      $begingroup$


      New to Java, just finished the Helsinki MOOC course. I programmed a basic mortgage calculator as my first solo project and while it works, I have a few questions about coding style:



      1) The listener and ui classes are cluttered with variables at the top. Is this acceptable or is there a cleaner way of organizing it?



      2) Is initializing the variables in the CalcLogic class as strings and then creating new BigDecimal variables in the methods an accepted way of using BigDecimal, or would it better to initialize the variables as BigDecimals?



      3) Are there any other coding style or logic issues that are noticeable?



      CalcLogic Class:



      package mortgagecalculator.logic;

      import java.math.BigDecimal;
      import java.math.RoundingMode;

      /**
      * Logic for mortgage calculator.
      * Input variables for home value, loan term, etc. and outputs EMI, total payment, etc.
      *
      */

      public class CalcLogic

      //Variables for calculating mortgage. propTax, homeIns, etc are not initialized in constructor
      private String principal = "0";
      private String downPayment = "0";
      private String interestRate = "0";
      private int loanTerm = 0;
      private String propTax = "0";
      private String homeIns = "0";
      private String hoaFee = "0";
      private String pmiRate = "0";

      public void setPrincipal(String principal)
      this.principal = principal;


      public void setDownPayment(String downPayment)
      this.downPayment = downPayment;


      public void setInterest(String interestRate)
      this.interestRate = interestRate;


      public void setLoanTerm(int loanTerm)
      this.loanTerm = loanTerm;


      public void setPropTax(String propTax)
      this.propTax = propTax;


      public void setHomeIns(String homeIns)
      this.homeIns = homeIns;


      public void setHOAfee(String hoaFee)
      this.hoaFee = hoaFee;


      public void setPMIrate(String pmiRate)
      this.pmiRate = pmiRate;


      //Returns principal minus downpayment
      public BigDecimal getInitialAmount()
      return new BigDecimal(this.principal).subtract(new BigDecimal(this.downPayment));


      //Returns twenty percent of principal
      public BigDecimal twentyDown()
      BigDecimal twenty = new BigDecimal("20").divide(new BigDecimal("100"));
      return new BigDecimal(this.principal).multiply(twenty);


      public BigDecimal monthlyInterest()
      return new BigDecimal(this.interestRate).divide(new BigDecimal("100"))
      .divide(new BigDecimal("12"), 8, RoundingMode.UP);


      public BigDecimal monthlyPMI()

      try
      BigDecimal result = getInitialAmount().divide(new BigDecimal(this.pmiRate).divide(new BigDecimal("100"))
      .divide(new BigDecimal("12")), 2, RoundingMode.UP);
      return result;

      catch (Exception e)
      return BigDecimal.ZERO;




      public BigDecimal additionalTax()
      BigDecimal sum = new BigDecimal(this.propTax);
      sum = sum.add(new BigDecimal(this.homeIns)).add(new BigDecimal(this.hoaFee));
      return sum;


      public BigDecimal getEMI()
      BigDecimal value = monthlyInterest().add(BigDecimal.ONE);
      value = value.pow(this.loanTerm * 12);

      BigDecimal numerator = value.multiply(monthlyInterest()).multiply(getInitialAmount());
      BigDecimal denominator = value.subtract(BigDecimal.ONE);

      return numerator.divide(denominator, 2, RoundingMode.UP);



      public BigDecimal monthlyPayment()
      BigDecimal result = getEMI().add(monthlyPMI()).add(additionalTax());
      return result;


      public BigDecimal totalInterest()
      BigDecimal result = getEMI().multiply(new BigDecimal(this.loanTerm * 12));
      result = result.subtract(getInitialAmount());
      return result;


      //Returns month where principal payments first exceed interest payments
      public int amortMonth()
      BigDecimal remaining = getInitialAmount().setScale(2, RoundingMode.CEILING);

      for (int i = 0; i < this.loanTerm * 12; i++)

      BigDecimal interPay = remaining.multiply(monthlyInterest()).setScale(2, RoundingMode.CEILING);
      BigDecimal princPay = getEMI().subtract(interPay).setScale(2, RoundingMode.CEILING);

      if (princPay.compareTo(interPay) == 1)
      return i + 1;


      remaining = remaining.subtract(princPay).setScale(2, RoundingMode.CEILING);



      return 0;





      CalcListener Class:



      package mortgagecalculator.ui;

      import mortgagecalculator.logic.CalcLogic;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import javax.swing.JTextField;
      import javax.swing.JButton;
      import java.math.BigDecimal;

      public class CalcListener implements ActionListener

      private JTextField principal;
      private JTextField downPayment;
      private JTextField interestRate;
      private JTextField loanTerm;
      private JTextField propTax;
      private JTextField homeIns;
      private JTextField hoaFee;
      private JTextField pmiRate;
      private JButton button;
      private JTextField EMI;
      private JTextField monthlyFee;
      private JTextField totalInt;
      private JTextField changeMonth;
      private CalcLogic calc;

      public CalcListener(JTextField principal, JTextField downPayment, JTextField interestRate,
      JTextField loanTerm, JTextField propTax, JTextField homeIns,
      JTextField hoaFee, JTextField pmiRate, JTextField EMI,
      JTextField monthlyFee, JTextField totalInt, JTextField changeMonth, JButton button)
      this.principal = principal;
      this.downPayment = downPayment;
      this.interestRate = interestRate;
      this.loanTerm = loanTerm;
      this.propTax = propTax;
      this.homeIns = homeIns;
      this.hoaFee = hoaFee;
      this.pmiRate = pmiRate;
      this.button = button;
      this.EMI = EMI;
      this.monthlyFee = monthlyFee;
      this.totalInt = totalInt;
      this.changeMonth = changeMonth;
      this.calc = new CalcLogic();


      @Override
      public void actionPerformed(ActionEvent ae)

      if (ae.getSource() == this.button)

      this.calc.setPrincipal(this.principal.getText());
      this.calc.setDownPayment(this.downPayment.getText());
      this.calc.setInterest(this.interestRate.getText());
      this.calc.setLoanTerm(Integer.parseInt(this.loanTerm.getText()));
      this.calc.setPropTax(this.propTax.getText());
      this.calc.setHomeIns(this.homeIns.getText());
      this.calc.setPMIrate(this.pmiRate.getText());
      this.calc.setHOAfee(this.hoaFee.getText());

      this.EMI.setText(this.calc.getEMI().toString());
      this.monthlyFee.setText(this.calc.monthlyPayment().toString());
      this.totalInt.setText(this.calc.totalInterest().toString());
      this.changeMonth.setText(String.valueOf(this.calc.amortMonth()));







      UserInterface Class:



      package mortgagecalculator.ui;

      import java.awt.Container;
      import java.awt.Dimension;
      import java.awt.BorderLayout;
      import java.awt.GridLayout;
      import javax.swing.*;
      import mortgagecalculator.ui.CalcListener;

      public class UserInterface implements Runnable

      private JFrame frame;
      private JTextField principal;
      private JTextField downPayment;
      private JTextField interestRate;
      private JTextField loanTerm;
      private JTextField propTax;
      private JTextField homeIns;
      private JTextField hoaFee;
      private JTextField pmiRate;
      private JButton button;
      private JTextField EMI;
      private JTextField monthlyFee;
      private JTextField totalInt;
      private JTextField changeMonth;

      @Override
      public void run()
      frame = new JFrame("Mortgage Calculator");
      frame.setPreferredSize(new Dimension(1000, 1000));
      frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

      createComponents(frame.getContentPane());

      frame.pack();
      frame.setVisible(true);



      private void createComponents(Container container)
      generateVariables();
      container.setLayout(new GridLayout(3, 1));

      container.add(createInputPanel());
      container.add(this.button);
      container.add(createOutputPanel());



      private void generateVariables()
      this.principal = new JTextField("");
      this.downPayment = new JTextField("");
      this.interestRate = new JTextField("");
      this.loanTerm = new JTextField("");
      this.propTax = new JTextField("");
      this.homeIns = new JTextField("");
      this.hoaFee = new JTextField("");
      this.pmiRate = new JTextField("");
      this.EMI = new JTextField("");
      this.monthlyFee = new JTextField("");
      this.totalInt = new JTextField("");
      this.changeMonth = new JTextField("");
      this.button = new JButton("Calculate!");

      CalcListener calc = new CalcListener(this.principal, this.downPayment, this.interestRate,
      this.loanTerm, this.propTax, this.homeIns, this.hoaFee,
      this.pmiRate, this.EMI, this.monthlyFee, this.totalInt,
      this.changeMonth, this.button);

      this.button.addActionListener(calc);


      private JPanel createInputPanel()
      JPanel panel = new JPanel(new GridLayout(4, 4));
      panel.add(new JLabel("Principal"));
      panel.add(new JLabel("Down Payment"));
      panel.add(new JLabel("Interest Rate (in %)"));
      panel.add(new JLabel("Loan term (in years)"));
      panel.add(this.principal);
      panel.add(this.downPayment);
      panel.add(this.interestRate);
      panel.add(this.loanTerm);

      panel.add(new JLabel("Property Tax (Monthly)"));
      panel.add(new JLabel("Home Insurance (Monthly)"));
      panel.add(new JLabel("HOA Fees (Monthly)"));
      panel.add(new JLabel("PMI Rate (in %)"));
      panel.add(this.propTax);
      panel.add(this.homeIns);
      panel.add(this.hoaFee);
      panel.add(this.pmiRate);

      return panel;


      private JPanel createOutputPanel()
      JPanel panel = new JPanel(new GridLayout(4, 2));

      panel.add(new JLabel("Equated Monthly Installment"));
      panel.add(new JLabel("Monthly w/ fees"));
      panel.add(this.EMI);
      panel.add(this.monthlyFee);

      panel.add(new JLabel("Total Interest Payments"));
      panel.add(new JLabel("Month where principal payments > interest"));
      panel.add(this.totalInt);
      panel.add(this.changeMonth);

      return panel;


      public JFrame getFrame()
      return frame;










      share







      New contributor




      JeremiahDixon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.







      $endgroup$




      New to Java, just finished the Helsinki MOOC course. I programmed a basic mortgage calculator as my first solo project and while it works, I have a few questions about coding style:



      1) The listener and ui classes are cluttered with variables at the top. Is this acceptable or is there a cleaner way of organizing it?



      2) Is initializing the variables in the CalcLogic class as strings and then creating new BigDecimal variables in the methods an accepted way of using BigDecimal, or would it better to initialize the variables as BigDecimals?



      3) Are there any other coding style or logic issues that are noticeable?



      CalcLogic Class:



      package mortgagecalculator.logic;

      import java.math.BigDecimal;
      import java.math.RoundingMode;

      /**
      * Logic for mortgage calculator.
      * Input variables for home value, loan term, etc. and outputs EMI, total payment, etc.
      *
      */

      public class CalcLogic

      //Variables for calculating mortgage. propTax, homeIns, etc are not initialized in constructor
      private String principal = "0";
      private String downPayment = "0";
      private String interestRate = "0";
      private int loanTerm = 0;
      private String propTax = "0";
      private String homeIns = "0";
      private String hoaFee = "0";
      private String pmiRate = "0";

      public void setPrincipal(String principal)
      this.principal = principal;


      public void setDownPayment(String downPayment)
      this.downPayment = downPayment;


      public void setInterest(String interestRate)
      this.interestRate = interestRate;


      public void setLoanTerm(int loanTerm)
      this.loanTerm = loanTerm;


      public void setPropTax(String propTax)
      this.propTax = propTax;


      public void setHomeIns(String homeIns)
      this.homeIns = homeIns;


      public void setHOAfee(String hoaFee)
      this.hoaFee = hoaFee;


      public void setPMIrate(String pmiRate)
      this.pmiRate = pmiRate;


      //Returns principal minus downpayment
      public BigDecimal getInitialAmount()
      return new BigDecimal(this.principal).subtract(new BigDecimal(this.downPayment));


      //Returns twenty percent of principal
      public BigDecimal twentyDown()
      BigDecimal twenty = new BigDecimal("20").divide(new BigDecimal("100"));
      return new BigDecimal(this.principal).multiply(twenty);


      public BigDecimal monthlyInterest()
      return new BigDecimal(this.interestRate).divide(new BigDecimal("100"))
      .divide(new BigDecimal("12"), 8, RoundingMode.UP);


      public BigDecimal monthlyPMI()

      try
      BigDecimal result = getInitialAmount().divide(new BigDecimal(this.pmiRate).divide(new BigDecimal("100"))
      .divide(new BigDecimal("12")), 2, RoundingMode.UP);
      return result;

      catch (Exception e)
      return BigDecimal.ZERO;




      public BigDecimal additionalTax()
      BigDecimal sum = new BigDecimal(this.propTax);
      sum = sum.add(new BigDecimal(this.homeIns)).add(new BigDecimal(this.hoaFee));
      return sum;


      public BigDecimal getEMI()
      BigDecimal value = monthlyInterest().add(BigDecimal.ONE);
      value = value.pow(this.loanTerm * 12);

      BigDecimal numerator = value.multiply(monthlyInterest()).multiply(getInitialAmount());
      BigDecimal denominator = value.subtract(BigDecimal.ONE);

      return numerator.divide(denominator, 2, RoundingMode.UP);



      public BigDecimal monthlyPayment()
      BigDecimal result = getEMI().add(monthlyPMI()).add(additionalTax());
      return result;


      public BigDecimal totalInterest()
      BigDecimal result = getEMI().multiply(new BigDecimal(this.loanTerm * 12));
      result = result.subtract(getInitialAmount());
      return result;


      //Returns month where principal payments first exceed interest payments
      public int amortMonth()
      BigDecimal remaining = getInitialAmount().setScale(2, RoundingMode.CEILING);

      for (int i = 0; i < this.loanTerm * 12; i++)

      BigDecimal interPay = remaining.multiply(monthlyInterest()).setScale(2, RoundingMode.CEILING);
      BigDecimal princPay = getEMI().subtract(interPay).setScale(2, RoundingMode.CEILING);

      if (princPay.compareTo(interPay) == 1)
      return i + 1;


      remaining = remaining.subtract(princPay).setScale(2, RoundingMode.CEILING);



      return 0;





      CalcListener Class:



      package mortgagecalculator.ui;

      import mortgagecalculator.logic.CalcLogic;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import javax.swing.JTextField;
      import javax.swing.JButton;
      import java.math.BigDecimal;

      public class CalcListener implements ActionListener

      private JTextField principal;
      private JTextField downPayment;
      private JTextField interestRate;
      private JTextField loanTerm;
      private JTextField propTax;
      private JTextField homeIns;
      private JTextField hoaFee;
      private JTextField pmiRate;
      private JButton button;
      private JTextField EMI;
      private JTextField monthlyFee;
      private JTextField totalInt;
      private JTextField changeMonth;
      private CalcLogic calc;

      public CalcListener(JTextField principal, JTextField downPayment, JTextField interestRate,
      JTextField loanTerm, JTextField propTax, JTextField homeIns,
      JTextField hoaFee, JTextField pmiRate, JTextField EMI,
      JTextField monthlyFee, JTextField totalInt, JTextField changeMonth, JButton button)
      this.principal = principal;
      this.downPayment = downPayment;
      this.interestRate = interestRate;
      this.loanTerm = loanTerm;
      this.propTax = propTax;
      this.homeIns = homeIns;
      this.hoaFee = hoaFee;
      this.pmiRate = pmiRate;
      this.button = button;
      this.EMI = EMI;
      this.monthlyFee = monthlyFee;
      this.totalInt = totalInt;
      this.changeMonth = changeMonth;
      this.calc = new CalcLogic();


      @Override
      public void actionPerformed(ActionEvent ae)

      if (ae.getSource() == this.button)

      this.calc.setPrincipal(this.principal.getText());
      this.calc.setDownPayment(this.downPayment.getText());
      this.calc.setInterest(this.interestRate.getText());
      this.calc.setLoanTerm(Integer.parseInt(this.loanTerm.getText()));
      this.calc.setPropTax(this.propTax.getText());
      this.calc.setHomeIns(this.homeIns.getText());
      this.calc.setPMIrate(this.pmiRate.getText());
      this.calc.setHOAfee(this.hoaFee.getText());

      this.EMI.setText(this.calc.getEMI().toString());
      this.monthlyFee.setText(this.calc.monthlyPayment().toString());
      this.totalInt.setText(this.calc.totalInterest().toString());
      this.changeMonth.setText(String.valueOf(this.calc.amortMonth()));







      UserInterface Class:



      package mortgagecalculator.ui;

      import java.awt.Container;
      import java.awt.Dimension;
      import java.awt.BorderLayout;
      import java.awt.GridLayout;
      import javax.swing.*;
      import mortgagecalculator.ui.CalcListener;

      public class UserInterface implements Runnable

      private JFrame frame;
      private JTextField principal;
      private JTextField downPayment;
      private JTextField interestRate;
      private JTextField loanTerm;
      private JTextField propTax;
      private JTextField homeIns;
      private JTextField hoaFee;
      private JTextField pmiRate;
      private JButton button;
      private JTextField EMI;
      private JTextField monthlyFee;
      private JTextField totalInt;
      private JTextField changeMonth;

      @Override
      public void run()
      frame = new JFrame("Mortgage Calculator");
      frame.setPreferredSize(new Dimension(1000, 1000));
      frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

      createComponents(frame.getContentPane());

      frame.pack();
      frame.setVisible(true);



      private void createComponents(Container container)
      generateVariables();
      container.setLayout(new GridLayout(3, 1));

      container.add(createInputPanel());
      container.add(this.button);
      container.add(createOutputPanel());



      private void generateVariables()
      this.principal = new JTextField("");
      this.downPayment = new JTextField("");
      this.interestRate = new JTextField("");
      this.loanTerm = new JTextField("");
      this.propTax = new JTextField("");
      this.homeIns = new JTextField("");
      this.hoaFee = new JTextField("");
      this.pmiRate = new JTextField("");
      this.EMI = new JTextField("");
      this.monthlyFee = new JTextField("");
      this.totalInt = new JTextField("");
      this.changeMonth = new JTextField("");
      this.button = new JButton("Calculate!");

      CalcListener calc = new CalcListener(this.principal, this.downPayment, this.interestRate,
      this.loanTerm, this.propTax, this.homeIns, this.hoaFee,
      this.pmiRate, this.EMI, this.monthlyFee, this.totalInt,
      this.changeMonth, this.button);

      this.button.addActionListener(calc);


      private JPanel createInputPanel()
      JPanel panel = new JPanel(new GridLayout(4, 4));
      panel.add(new JLabel("Principal"));
      panel.add(new JLabel("Down Payment"));
      panel.add(new JLabel("Interest Rate (in %)"));
      panel.add(new JLabel("Loan term (in years)"));
      panel.add(this.principal);
      panel.add(this.downPayment);
      panel.add(this.interestRate);
      panel.add(this.loanTerm);

      panel.add(new JLabel("Property Tax (Monthly)"));
      panel.add(new JLabel("Home Insurance (Monthly)"));
      panel.add(new JLabel("HOA Fees (Monthly)"));
      panel.add(new JLabel("PMI Rate (in %)"));
      panel.add(this.propTax);
      panel.add(this.homeIns);
      panel.add(this.hoaFee);
      panel.add(this.pmiRate);

      return panel;


      private JPanel createOutputPanel()
      JPanel panel = new JPanel(new GridLayout(4, 2));

      panel.add(new JLabel("Equated Monthly Installment"));
      panel.add(new JLabel("Monthly w/ fees"));
      panel.add(this.EMI);
      panel.add(this.monthlyFee);

      panel.add(new JLabel("Total Interest Payments"));
      panel.add(new JLabel("Month where principal payments > interest"));
      panel.add(this.totalInt);
      panel.add(this.changeMonth);

      return panel;


      public JFrame getFrame()
      return frame;








      java swing finance





      share







      New contributor




      JeremiahDixon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.










      share







      New contributor




      JeremiahDixon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.








      share



      share






      New contributor




      JeremiahDixon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 5 mins ago









      JeremiahDixonJeremiahDixon

      11




      11




      New contributor




      JeremiahDixon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      JeremiahDixon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      JeremiahDixon is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




















          0






          active

          oldest

          votes












          Your Answer





          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );






          JeremiahDixon is a new contributor. Be nice, and check out our Code of Conduct.









          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217168%2fdoes-this-mortgage-calculator-adhere-to-good-coding-style-or-is-the-listener-cla%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          JeremiahDixon is a new contributor. Be nice, and check out our Code of Conduct.









          draft saved

          draft discarded


















          JeremiahDixon is a new contributor. Be nice, and check out our Code of Conduct.












          JeremiahDixon is a new contributor. Be nice, and check out our Code of Conduct.











          JeremiahDixon is a new contributor. Be nice, and check out our Code of Conduct.














          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217168%2fdoes-this-mortgage-calculator-adhere-to-good-coding-style-or-is-the-listener-cla%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          名間水力發電廠 目录 沿革 設施 鄰近設施 註釋 外部連結 导航菜单23°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.7113923°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.71139計畫概要原始内容臺灣第一座BOT 模式開發的水力發電廠-名間水力電廠名間水力發電廠 水利署首件BOT案原始内容《小檔案》名間電廠 首座BOT水力發電廠原始内容名間電廠BOT - 經濟部水利署中區水資源局

          Prove that NP is closed under karp reduction?Space(n) not closed under Karp reductions - what about NTime(n)?Class P is closed under rotation?Prove or disprove that $NL$ is closed under polynomial many-one reductions$mathbfNC_2$ is closed under log-space reductionOn Karp reductionwhen can I know if a class (complexity) is closed under reduction (cook/karp)Check if class $PSPACE$ is closed under polyonomially space reductionIs NPSPACE also closed under polynomial-time reduction and under log-space reduction?Prove PSPACE is closed under complement?Prove PSPACE is closed under union?

          Is my guitar’s action too high? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)Strings too stiff on a recently purchased acoustic guitar | Cort AD880CEIs the action of my guitar really high?Μy little finger is too weak to play guitarWith guitar, how long should I give my fingers to strengthen / callous?When playing a fret the guitar sounds mutedPlaying (Barre) chords up the guitar neckI think my guitar strings are wound too tight and I can't play barre chordsF barre chord on an SG guitarHow to find to the right strings of a barre chord by feel?High action on higher fret on my steel acoustic guitar