I'm writing a program in Java (a mortgage calculator) with a GUI using SceneBuilder/FXML for a college class and I'm experiencing errors

huangapple go评论82阅读模式
英文:

I'm writing a program in Java (a mortgage calculator) with a GUI using SceneBuilder/FXML for a college class and I'm experiencing errors

问题

I'm still quite a beginner in Java and I'm having a hard time understanding stuff like this program. However, I thought I got a hold of it eventually. Unfortunately, whenever I try to run my program, there are errors and I'm unsure how to fix them.

EDIT: I should also state that I need the slider to go between the values 10, 20, and 30.

Here's my controller program:

// Controller that handles calculateButton and loanDurationSlider events
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;

public class MortgageCalculatorController { 
   // formatters for currency and percentages
   private static final NumberFormat currency = 
      NumberFormat.getCurrencyInstance();
   private static final NumberFormat percent = 
		      NumberFormat.getPercentInstance();
   
   // GUI controls defined in FXML and used by the controller's code
   @FXML 
   private TextField purchasePriceTextField; 

   @FXML
   private Label loanDurationLabel; 

   @FXML
   private Slider loanDurationSlider;

   @FXML
   private TextField loanDurationTextField;
   
   @FXML
   private TextField downPaymentTextField;
   
   @FXML
   private TextField interestRateTextField;

   @FXML
   private TextField monthlyPaymentTextField;
   
   private int loanDuration = Integer.parseInt(loanDurationTextField.getText());

   @FXML
   private void calculateButtonPressed(ActionEvent event) {
      try {
         BigDecimal purchasePrice = new BigDecimal(purchasePriceTextField.getText());
         BigDecimal downPayment = new BigDecimal(downPaymentTextField.getText());
         BigDecimal interestRate = new BigDecimal(interestRateTextField.getText());
         BigDecimal twelve = new BigDecimal(12.0);
         BigDecimal hundred = new BigDecimal(100.0);
         interestRate = interestRate.divide(twelve);
         BigDecimal numerator = interestRate.multiply(interestRate.add(BigDecimal.ONE).pow(loanDuration*12));
         BigDecimal denominator = interestRate.add(BigDecimal.ONE).pow(loanDuration*12).subtract(BigDecimal.ONE);
         BigDecimal monthlyPayment = purchasePrice.multiply(numerator).divide(denominator);
         interestRate = interestRate.multiply(hundred);

         purchasePriceTextField.setText(currency.format(purchasePrice));
         downPaymentTextField.setText(currency.format(downPayment));
         interestRateTextField.setText(percent.format(interestRate));
         monthlyPaymentTextField.setText(currency.format(monthlyPayment));
      }
      catch (NumberFormatException ex) {
         purchasePriceTextField.setText("Enter amount");
         purchasePriceTextField.selectAll();
         purchasePriceTextField.requestFocus();
      }
   }

   // called by FXMLLoader to initialize the controller
   public void initialize() {
      // 0-4 rounds down, 5-9 rounds up 
      currency.setRoundingMode(RoundingMode.HALF_UP);
      
      // listener for changes to loanDurationSlider's value
      loanDurationSlider.valueProperty().addListener(
         new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> ov, 
               Number oldValue, Number newValue) {
               loanDuration = newValue.intValue();
            }
         }
      );
   }
}

And here's my FXML program to go with it:

<!-- FXML content -->

And finally here's the list of errors:

Exception in Application start method
java.lang.reflect.InvocationTargetException
...
Caused by: java.lang.RuntimeException: Exception in Application start method
...
Caused by: javafx.fxml.LoadException: 
...
Caused by: java.lang.NullPointerException
...
Exception running application MortgageCalculator

Please let me know if I need to supply any further information.

英文:

I'm still quite a beginner in Java and I'm having a hard time understanding stuff like this program. However, I thought I got a hold of it eventually. Unfortunately, whenever I try to run my program, there are errors and I'm unsure how to fix them.

EDIT: I should also state that I need the slider to go between the values 10, 20, and 30.

Here's my controller program:

// Controller that handles calculateButton and loanDurationSlider events
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
public class MortgageCalculatorController { 
// formatters for currency and percentages
private static final NumberFormat currency = 
NumberFormat.getCurrencyInstance();
private static final NumberFormat percent = 
NumberFormat.getPercentInstance();
// GUI controls defined in FXML and used by the controller&#39;s code
@FXML 
private TextField purchasePriceTextField; 
@FXML
private Label loanDurationLabel; 
@FXML
private Slider loanDurationSlider;
@FXML
private TextField loanDurationTextField;
@FXML
private TextField downPaymentTextField;
@FXML
private TextField interestRateTextField;
@FXML
private TextField monthlyPaymentTextField;
private int loanDuration = Integer.parseInt(loanDurationTextField.getText());
@FXML
private void calculateButtonPressed(ActionEvent event) {
try {
BigDecimal purchasePrice = new BigDecimal(purchasePriceTextField.getText());
BigDecimal downPayment = new BigDecimal(downPaymentTextField.getText());
BigDecimal interestRate = new BigDecimal(interestRateTextField.getText());
BigDecimal twelve = new BigDecimal(12.0);
BigDecimal hundred = new BigDecimal(100.0);
interestRate = interestRate.divide(twelve);
BigDecimal numerator = interestRate.multiply(interestRate.add(BigDecimal.ONE).pow(loanDuration*12));
BigDecimal denominator = interestRate.add(BigDecimal.ONE).pow(loanDuration*12).subtract(BigDecimal.ONE);
BigDecimal monthlyPayment = purchasePrice.multiply(numerator).divide(denominator);
interestRate = interestRate.multiply(hundred);
purchasePriceTextField.setText(currency.format(purchasePrice));
downPaymentTextField.setText(currency.format(downPayment));
interestRateTextField.setText(percent.format(interestRate));
monthlyPaymentTextField.setText(currency.format(monthlyPayment));
}
catch (NumberFormatException ex) {
purchasePriceTextField.setText(&quot;Enter amount&quot;);
purchasePriceTextField.selectAll();
purchasePriceTextField.requestFocus();
}
}
// called by FXMLLoader to initialize the controller
public void initialize() {
// 0-4 rounds down, 5-9 rounds up 
currency.setRoundingMode(RoundingMode.HALF_UP);
// listener for changes to loanDurationSlider&#39;s value
loanDurationSlider.valueProperty().addListener(
new ChangeListener&lt;Number&gt;() {
@Override
public void changed(ObservableValue&lt;? extends Number&gt; ov, 
Number oldValue, Number newValue) {
loanDuration = newValue.intValue();
}
}
);
}
}

And here's my FXML program to go with it:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;?import javafx.geometry.Insets?&gt;
&lt;?import javafx.scene.control.Button?&gt;
&lt;?import javafx.scene.control.Label?&gt;
&lt;?import javafx.scene.control.Slider?&gt;
&lt;?import javafx.scene.control.TextField?&gt;
&lt;?import javafx.scene.layout.ColumnConstraints?&gt;
&lt;?import javafx.scene.layout.GridPane?&gt;
&lt;?import javafx.scene.layout.RowConstraints?&gt;
&lt;GridPane hgap=&quot;8.0&quot; maxHeight=&quot;-Infinity&quot; maxWidth=&quot;-Infinity&quot; minHeight=&quot;-Infinity&quot; minWidth=&quot;-Infinity&quot; xmlns=&quot;http://javafx.com/javafx/8.0.60&quot; xmlns:fx=&quot;http://javafx.com/fxml/1&quot; fx:controller=&quot;MortgageCalculatorController&quot;&gt;
&lt;columnConstraints&gt;
&lt;ColumnConstraints halignment=&quot;RIGHT&quot; hgrow=&quot;SOMETIMES&quot; minWidth=&quot;10.0&quot; /&gt;
&lt;ColumnConstraints hgrow=&quot;SOMETIMES&quot; minWidth=&quot;10.0&quot; /&gt;
&lt;/columnConstraints&gt;
&lt;rowConstraints&gt;
&lt;RowConstraints minHeight=&quot;10.0&quot; prefHeight=&quot;30.0&quot; vgrow=&quot;SOMETIMES&quot; /&gt;
&lt;RowConstraints minHeight=&quot;10.0&quot; prefHeight=&quot;30.0&quot; vgrow=&quot;SOMETIMES&quot; /&gt;
&lt;RowConstraints minHeight=&quot;10.0&quot; prefHeight=&quot;30.0&quot; vgrow=&quot;SOMETIMES&quot; /&gt;
&lt;RowConstraints minHeight=&quot;10.0&quot; prefHeight=&quot;30.0&quot; vgrow=&quot;SOMETIMES&quot; /&gt;
&lt;RowConstraints minHeight=&quot;10.0&quot; prefHeight=&quot;30.0&quot; vgrow=&quot;SOMETIMES&quot; /&gt;
&lt;/rowConstraints&gt;
&lt;children&gt;
&lt;Label text=&quot;Purchase Price&quot; /&gt;
&lt;Label fx:id=&quot;loanDurationLabel&quot; text=&quot;10&quot; GridPane.rowIndex=&quot;1&quot; /&gt;
&lt;Label text=&quot;Loan Duration&quot; GridPane.rowIndex=&quot;2&quot; /&gt;
&lt;Label text=&quot;Down Payment&quot; GridPane.rowIndex=&quot;3&quot; /&gt;
&lt;Label text=&quot;Interest Rate&quot; GridPane.rowIndex=&quot;4&quot; /&gt;
&lt;Label text=&quot;Monthly Payment&quot; GridPane.rowIndex=&quot;5&quot; /&gt;
&lt;TextField fx:id=&quot;purchasePriceTextField&quot; GridPane.columnIndex=&quot;1&quot; /&gt;
&lt;TextField fx:id=&quot;loanDurationTextField&quot; editable=&quot;false&quot; focusTraversable=&quot;false&quot; GridPane.columnIndex=&quot;1&quot; GridPane.rowIndex=&quot;2&quot; /&gt;
&lt;TextField fx:id=&quot;downPaymentTextField&quot; GridPane.columnIndex=&quot;1&quot; GridPane.rowIndex=&quot;3&quot; /&gt;
&lt;TextField fx:id=&quot;interestRateTextField&quot; GridPane.columnIndex=&quot;1&quot; GridPane.rowIndex=&quot;4&quot; /&gt;
&lt;TextField fx:id=&quot;monthlyPaymentTextField&quot; editable=&quot;false&quot; focusTraversable=&quot;false&quot; GridPane.columnIndex=&quot;1&quot; GridPane.rowIndex=&quot;5&quot; /&gt;
&lt;Slider fx:id=&quot;loanDurationSlider&quot; blockIncrement=&quot;10.0&quot; max=&quot;30.0&quot; value=&quot;10.0&quot; GridPane.columnIndex=&quot;1&quot; GridPane.rowIndex=&quot;1&quot; /&gt;
&lt;Button maxWidth=&quot;1.7976931348623157E308&quot; mnemonicParsing=&quot;false&quot; onAction=&quot;#calculateButtonPressed&quot; text=&quot;Calculate&quot; GridPane.columnIndex=&quot;1&quot; GridPane.rowIndex=&quot;6&quot; /&gt;
&lt;/children&gt;
&lt;padding&gt;
&lt;Insets bottom=&quot;14.0&quot; left=&quot;14.0&quot; right=&quot;14.0&quot; top=&quot;14.0&quot; /&gt;
&lt;/padding&gt;
&lt;/GridPane&gt;

And finally here's the list of errors:

Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:873)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$1(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: javafx.fxml.LoadException: 
/C:/Users/EdenFlorian/Documents/Eclipse%20Workspace/COMP%20SCI%20316%20-%20Week%205%20Assignment/bin/MortgageCalculator.fxml:12
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at MortgageCalculator.start(MortgageCalculator.java:13)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$7(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$4(WinApplication.java:186)
... 1 more
Caused by: java.lang.NullPointerException
at MortgageCalculatorController.&lt;init&gt;(MortgageCalculatorController.java:43)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:927)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
... 17 more
Exception running application MortgageCalculator

Please let me know if I need to supply any further information.

答案1

得分: 1

尝试去掉以下代码:

private int loanDuration = Integer.parseInt(loanDurationTextField.getText());

然后将以下代码段替换为:

BigDecimal numerator = interestRate.multiply(interestRate.add(BigDecimal.ONE).pow(Integer.parseInt(loanDurationTextField.getText())*12));
BigDecimal denominator = interestRate.add(BigDecimal.ONE).pow(Integer.parseInt(loanDurationTextField.getText())*12).subtract(BigDecimal.ONE);

更新以回应评论
你应该可以像这样进行更新:

loanDurationSlider.valueProperty().addListener(
    new ChangeListener<Number>() {
        @Override
        public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue) 
        {
            loanDurationTextField.setText(newValue.intValue().toString())); //或者如果 intValue().toString() 不可用,可以使用 loanDurationTextField.setText(Integer.toString(newValue.intValue()));。
        }
     }
);
英文:

Try getting rid of

private int loanDuration = Integer.parseInt(loanDurationTextField.getText());

Then replace

BigDecimal numerator = interestRate.multiply(interestRate.add(BigDecimal.ONE).pow(loanDuration*12));
BigDecimal denominator = interestRate.add(BigDecimal.ONE).pow(loanDuration*12).subtract(BigDecimal.ONE);

with

BigDecimal numerator = interestRate.multiply(interestRate.add(BigDecimal.ONE).pow(Integer.parseInt(loanDurationTextField.getText())*12));
BigDecimal denominator = interestRate.add(BigDecimal.ONE).pow(Integer.parseInt(loanDurationTextField.getText())*12).subtract(BigDecimal.ONE);

Update to answer comment
You should be able to do something like

loanDurationSlider.valueProperty().addListener(
new ChangeListener&lt;Number&gt;() {
@Override
public void changed(ObservableValue&lt;? extends Number&gt; ov, Number oldValue, Number newValue) 
{
loanDurationTextField.setText(newValue.intValue().toString()));//or loanDurationTextField.setText(Integer.toString(newValue.intValue())); if intValue().toString() is not valid.
}
}
);

huangapple
  • 本文由 发表于 2020年10月9日 04:33:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/64270225.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定