Java JOptionPane Output

2019-08-15 07:58发布

问题:

Can anybody tell me what I am doing wrong here. I need to calculate some values from user-input into some JOptionPane-input-dialog-boxes, then outputting the answers.

I would greatly appreciate any help I get. Thanks In Advance!

  1. Input
    • Number of loans to compare (Could be more than 1)
    • Selling price
    • Down payment
    • You will ask the following for each loan they want to compare
      • Interest rate
      • Number of years
  2. Processing
    • You will need to calculate the monthly payment for each scenario listed in part d for the given interest rates and number of years.
  3. Output
    • Selling price
    • Down Payment
    • Loan Amount
    • List for each scenario
      • interest
      • years
      • payment

Here's my code so far:

    package javamortgagecalculator;
    import javax.swing.JOptionPane;
    import java.util.*;       
    public class JavaMortgageCalculator {
         public static void main(String[] args) {       
              //A. Enter the Number Of Loans to compare
              String numberOfLoansString = JOptionPane.showInputDialog("Enter the Number Of Loans to Compare"); 
              //Convert numberOfLoansString to int
              int numberOfLoans = Integer.parseInt(numberOfLoansString);

              //B. Enter the Selling Price of Home
              String sellingPriceString = JOptionPane.showInputDialog("Enter the Loan Amount");
              //Convert homeCostString to double
              double sellingPrice = Double.parseDouble(sellingPriceString);

              //C. Enter the Down Payment on the Home
              String downPaymentString = JOptionPane.showInputDialog("Enter the down payment on the Home");
              double downPayment = Double.parseDouble(downPaymentString);

              //Get the loanAmount by Subtracting the Down Payment from homeCost
              double loanAmount = sellingPrice - downPayment;

              //D. Ask the following for as many number of loans they wish to compare
              //D1 Get the interest rate
              double[] annualInterestRatesArray = new double[numberOfLoans];
              double[] monthlyInterestRateArray = new double[numberOfLoans];
              int[] numberOfYearsArray = new int[numberOfLoans];
              double[] monthlyPaymentArray = new double[numberOfLoans];
              double[] totalPaymentArray = new double[numberOfLoans];
              int counter = 1;

              for (int i=0; i < numberOfLoans; i++)
              {
                  String annualInterestRateString = JOptionPane.showInputDialog("Enter           the interest rate for Scenario " + counter);
                  double annualInterestRate = Double.parseDouble(annualInterestRateString);
                  annualInterestRatesArray[i] = (annualInterestRate);

                  //Obtain monthly interest rate
                  double monthlyInterestRate = annualInterestRate / 1200;
                  monthlyInterestRateArray[i] = (monthlyInterestRate);

                  //D2 Get the number of years
                  String numberOfYearsString = JOptionPane.showInputDialog("Enter the      number of years for Scenario " + counter);
                  int numberOfYears = Integer.parseInt(numberOfYearsString);
                  numberOfYearsArray[i] = (numberOfYears);

                  //Calculate monthly payment
                  double monthlyPayment = loanAmount * monthlyInterestRate / (1 - 1 / Math.pow(1 + monthlyInterestRate, numberOfYears * 12));
                  //Format to keep monthlyPayment two digits after the decimal point
                  monthlyPayment = (int)(monthlyPayment * 100) / 100.0;
                  //Store monthlyPayment values in an array
                  monthlyPaymentArray[i] = (monthlyPayment);

                  //Calculate total Payment
                  double totalPayment = monthlyPaymentArray[i] * numberOfYears * 12;
                  //Format to keep totalPayment two digits after the decimal point
                  totalPayment = (int)(totalPayment * 100) / 100.0;
                  totalPaymentArray[i] = (totalPayment);

                  counter++;
              }

              StringBuilder sb = new StringBuilder();
              for (int i = 0; i < numberOfLoans; i++) {
                     sb.append(String.format("\t \t \t \t \t \n", sellingPrice, downPayment, loanAmount, Arrays.toString(annualInterestRatesArray),           Arrays.toString(numberOfYearsArray), Arrays.toString(monthlyPaymentArray)));
              }
              String toDisplay=sb.toString();

              JOptionPane.showMessageDialog(null, sb.toString(), toDisplay, JOptionPane.INFORMATION_MESSAGE);             
          }
     }

回答1:

If I was forced, presumably by a large green, and particularly ugly troll masquerading as a programming teacher, to use multiple JOption panes for input and output then here's how I'd tackle the problem. This is meant for your information only... if you hand this in as your own work your teacher will smell a rat, and trolls have google too.

package forums;
import javax.swing.JOptionPane;
import java.text.DecimalFormat;

/**
 * Compares total cost of mortgages (aka ordinary annuity certains)
 */
public class MortgageCalculator
{
  public static void main(String[] args)
  {
    // 1. input
    final double price = Enter.aDouble("the purchase of the property");
    final double deposit = Enter.aDouble("down payment");
    Loan.setPrinciple(price - deposit);

    int numLoans = Enter.anInteger("number of loans to compare");
    Loan[] loans = new Loan[numLoans];
    for ( int i=0; i<numLoans; ++i ) {
      loans[i] = new Loan(
          Enter.aDouble("Annual interest rate for Loan " + (i+1) + "  (eg: 6.75)") / 100.0 / 12.0
        , Enter.anInteger("number of years for Loan " + (i+1) + "  (eg 20)") * 12
      );
    }

    // 3. Output
    final String caption = 
        "Principle " + Format.money(Loan.getPrinciple())
      + " = Price " + Format.money(price) 
      + " - Deposit " + Format.money(deposit);

    StringBuilder results = new StringBuilder(64 + numLoans * 64);
    results.append("Monthly Rate, Months, Monthly Repayment, Total Repayments\n");
    for ( Loan l : loans ) {
      results.append(String.format("%5s, %d, %13s, %13s\n"
        , Format.percent(l.rate)
        , l.periods
        , Format.money(l.payment())
        , Format.money(l.totalPayment())
      ));
    }
    JOptionPane.showMessageDialog(null, results.toString(), caption, JOptionPane.INFORMATION_MESSAGE);
  }

  static class Format
  {
    static java.text.Format MONEY = new DecimalFormat("$#,###.##");
    static String money(double amount) {
      return MONEY.format(amount);
    }

    static java.text.Format PERCENT = new DecimalFormat("0.###%");
    static String percent(double amount) {
      return PERCENT.format(amount);
    }

    static StringBuilder join(String between, Object... values) {
      StringBuilder result = new StringBuilder(values.length * 16);
      if ( values.length > 0 ) {
        result.append(values[0].toString());
        for ( int i=1; i<values.length; ++i ) {
          result.append(between)
            .append(values[i].toString());
        }
      }
      return result;
    }

  } // end class Format

  static class Enter
  {
    public static int anInteger(String fieldDesc) {
      return Integer.parseInt(JOptionPane.showInputDialog("Enter the "+ fieldDesc));
    }

    public static double aDouble(String fieldDesc) {
      return Double.parseDouble(JOptionPane.showInputDialog("Enter the "+ fieldDesc));
    }
  } // end class Enter

} // end class MortgageCalculator

class Loan
{
  private static double principle = 34324.121221312432;
  final double rate;
  final int periods;

  static void setPrinciple(double principle) {
    if (Loan.principle != 34324.121221312432)
      throw new ReadOnlyException("The Principle can't be changed once set.");
    Loan.principle = principle;
  }

  static double getPrinciple() {
    return Loan.principle;
  }

  /**
   * Initialises a new loan objects
   * @param double rate The interest rate per period, as a percentage.
   *  eg: 0.00625 is 7.5% per annum.
   * @param int periods The number of periods of the loan, typically months.
   */
  Loan(double rate, int periods) {
    this.rate = rate;
    this.periods = periods;
  }

  // 2. processing
  double payment() {
    return principle * rate / (1 - 1/Math.pow(1+rate,periods) );
  }

  double totalPayment() {
    return periods * payment();
  }

}

class ReadOnlyException extends RuntimeException 
{
  private static final long serialVersionUID = 0L;
  public ReadOnlyException(String message) {
    super(message);
  }
}

The "list of loans to compare" is represented by an array of Loan objects... I.e: each "loan option" is represented by an instance of the Loan class, which groups all the attributes of a particular loan into one nice tidy "thing" which we can then manipulate as a whole. This a better appraoch than the technique you're using to store loan attributes, which is called "parallel arrays"... and well, umm, it's a bit outdated, in-fact it's got a (greasy) mullet, it's wearing a (too tight) orange safari suit with a (safron pink) head-band... It wasn't a good look in the eighties, and these days, well it's likely to get you beaten-up, arrested, or both; depending on your locale... Basically: We have have better ways now!

The Loan class also has a couple of handy "calculated fields" to do the computations for us. This means that if the WAY we calculate repayments changes for some reason in future, we only have one place to change it, and everything that uses Loans (which could be reading, writing, permuting, totalling, repossessing, or even wholesaling loans) does NOT have to change... they just pick up the change "for free".

In this contrived use-case all our Loans will be for the same ammount, only the interest rates and periods vary... so the Loan class also has a static variable called "principle", which holds THE "common" principle for ALL instances of the Loan class. The principle may only be set once. Any subsequent attempt to set the prinicple will cause a ReadOnlyException to be thrown.

Anyway, I hope that you learn something from seeing another way to tackle some of the sub-problems you may have dicovered while doing this exercise yourself. One tip for the future: Grab your class-mates code for this exercise and read through it... you can learn a LOT from how other people tackle things.

Cheers. Keith.



回答2:

Now you need to examine the result returned by showMessageDialog(), as shown here.



回答3:

String.format("\t \t \t \t \t \n", sellingPrice, ...

That's just going to output 5 tabs. You want

String.format("%s %s %s %s %s %n", sellingPrice, ...


回答4:

for (int i = 0; i < numberOfLoans; i++)
{
    sb.append(/*...snip...*/ Arrays.toString(annualInterestRatesArray), Arrays.toString(numberOfYearsArray), Arrays.toString(monthlyPaymentArray));
}

You haven't told us what the problem is, but I don't think this bit is doing what you want. You're asking the program to print out the entirety of your three arrays every time the loop goes round. Instead, you probably want to access the specific array element for each loan, right? Something like...

for (int i = 0; i < numberOfLoans; i++)
{
    sb.append(/*...snip...*/ annualInterestRatesArray[i], numberOfYearsArray[i], monthlyPaymentArray[i]);
}


回答5:

Your JOptionPane.showMessageDialog(null... is inside a for loop. So it will show it as many times as the value of numberOfLoans2 . If you dont want that, move your

 String toDisplay = sb.toString();

    JOptionPane.showMessageDialog(null, sb.toString(), toDisplay, JOptionPane.INFORMATION_MESSAGE);

outside the for-loop.



回答6:

In your answer printing method the numberOfLoans2 variable is used in two places: in a for loop making the printing happen many times (outer loop) and in a for loop making the mathematic calculation (inner loop). Probably the outer one is with no use, so remove it and the result may be shown once. Remember to remove the ending } on the end of the loop element to keep the structure ok :)