0

What I am trying to do is to create an add that calculates the monthly mortgage payment given the loan amount, interest rate and term. But I am having a lot of problems with adding data into the tableview. I created a class called "Payment" and what I did was in the controller class I created an array of Payment objects called "payments". Each Payment object would represent a row in the tableview. I then created an observedArrayList using

ObservableList items=FX.Collections.observatbleArrayList(payments)

and added the ObservableList into the tableview using tableview.setItems(items).

But only 2 values from each Payment object showed up in each row. Namely, only the value of "month" and "remaining value" showed in each row. But remaining value is shown under the column for "payment" so it appear under the wrong column. Please see below for the codes in my controller as well as my Payment class:

import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;


public class MortgagecalculatorController implements Initializable {

   @FXML
   private TextField loanAmount;
   @FXML
   private ComboBox<Double> interest;
   @FXML
   private ComboBox<Integer> mTerm;
   @FXML
   private Button calculateButton;
   @FXML
   private TextField totalPayment;
   @FXML
   private TableView<Payment> tView;

/**
    * Initializes the controller class.
    */
   @Override
   public void initialize(URL url, ResourceBundle rb) {
      // TODO
      for (double i = 3.25; i <= 5; i = i + 0.01) {
         double temp = ((double) Math.round(i * 100)) / 100;
         interest.getItems().add(temp);
      }
      mTerm.getItems().addAll(5, 10, 15, 30);

      TableColumn monthColumn = new TableColumn("Month Number");
      monthColumn.setPrefWidth(100);
      monthColumn.setCellValueFactory(new PropertyValueFactory<>("month"));

      TableColumn paymentColumn = new TableColumn("Payment");
      paymentColumn.setPrefWidth(140);
      paymentColumn.setCellValueFactory(new PropertyValueFactory<>("monthlyPayment"));

      TableColumn principleColumn = new TableColumn("Principle Paid");
      principleColumn.setPrefWidth(140);
      paymentColumn.setCellValueFactory(new PropertyValueFactory<>("principle"));

      TableColumn interestColumn = new TableColumn("Interest Paid");
      interestColumn.setPrefWidth(140);
      paymentColumn.setCellValueFactory(new PropertyValueFactory<>("interest"));

      TableColumn totalInterestColumn = new TableColumn("Total Interest Paid");
      totalInterestColumn.setPrefWidth(140);
      paymentColumn.setCellValueFactory(new PropertyValueFactory<>("total"));

      TableColumn remainingColumn = new TableColumn("Remaining Value");
      remainingColumn.setPrefWidth(140);
      paymentColumn.setCellValueFactory(new PropertyValueFactory<>("remaining"));

      tView.getColumns().addAll(monthColumn, paymentColumn, principleColumn, interestColumn, totalInterestColumn, remainingColumn);

      interest.setValue(3.25);
      mTerm.setValue(5);
   }

   @FXML
   private void handleCalculateButton(ActionEvent event) {
      double loan;
      if (loanAmount.getText().isEmpty()) {
         System.out.println("Please enter loan amount");
         return;
      }
      if (isNumeric(loanAmount.getText())) {
         loan = Double.parseDouble(loanAmount.getText());
      } else {
         System.out.println("loan amount entered is non-numeric");
         return;
      }
      int months = mTerm.getValue() * 12;
      double monthlyInterest = (interest.getValue() / 100) / 12;
      double monthlyPayment = loan * monthlyInterest / (1 - (Math.pow(1 / (1 + monthlyInterest), months)));
      Payment[] payments = new Payment[months];
      double rValue = loan;
      double totalInterest = 0;
      System.out.println("monthly payment: "+monthlyPayment);
      for (int i = 0; i < payments.length; i++) {
         double interestPaid = rValue * monthlyInterest;
         double principle = monthlyPayment - interestPaid;
         totalInterest = totalInterest + interestPaid;
         rValue = rValue - principle;
         payments[i] = new Payment(String.valueOf(i + 1), monthlyPayment, principle, interestPaid, totalInterest, rValue);
      }
      ObservableList<Payment> items = FXCollections.observableArrayList(payments);
      tView.setItems(items);
   }

   public static boolean isNumeric(String str) {
      try {
         Double.parseDouble(str);
         return true;
      } catch (NumberFormatException e) {
         return false;
      }
   }

}
public class Payment {
   private String month;
   private double monthlyPayment;
   private double principle;
   private double interest;
   private double total;
   private double remaining;

   public Payment(String mon, double pay,double principle, double interest,double totalInterest, double rValue ){
   this.month=mon;
   this.monthlyPayment=pay;
   this.principle=principle;
   this.interest=interest;
   this.total=totalInterest;
   this.remaining=rValue;
}

   public String getMonth(){
      return month;
   }
   public double getMonthlyPayment(){
      return monthlyPayment;
   }
   public double getPrinciple(){
      return principle;
   }
   public double getInterest(){
      return interest;
   }
   public double getTotal(){
      return total;
   }
   public double getRemaining(){
      return remaining;
   }


}
1
  • 1
    Copy and paste error on your calls to setCellValueFactory (you use paymentColumn every time except the first). Commented Apr 1, 2020 at 1:59

1 Answer 1

0

You are constantly overriding the CellValueFactory of paymentColumn by (most likely copy-pasting) this line:

paymentColumn.setCellValueFactory(new PropertyValueFactory<>("monthlyPayment"));

You are changing the value, but not the TableColumn.

For each TableColumn starting from principleColumn, you need to set the right CellValueFactory. For example, for principleColumn you need to do this:

TableColumn principleColumn = new TableColumn("Principle Paid");
principleColumn.setPrefWidth(140);
principleColumn.setCellValueFactory(new PropertyValueFactory<>("principle"));

Notice the last line, you need to use principleColumn.setCellValueFactory(...) in this case.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for pointing it out. Yeah I copied and pasted my lines cause I got lazy. I got stuck for hours as a result of that. Thanks again

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.