英文:
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'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:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane hgap="8.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="MortgageCalculatorController">
<columnConstraints>
<ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES" minWidth="10.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Purchase Price" />
<Label fx:id="loanDurationLabel" text="10" GridPane.rowIndex="1" />
<Label text="Loan Duration" GridPane.rowIndex="2" />
<Label text="Down Payment" GridPane.rowIndex="3" />
<Label text="Interest Rate" GridPane.rowIndex="4" />
<Label text="Monthly Payment" GridPane.rowIndex="5" />
<TextField fx:id="purchasePriceTextField" GridPane.columnIndex="1" />
<TextField fx:id="loanDurationTextField" editable="false" focusTraversable="false" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<TextField fx:id="downPaymentTextField" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<TextField fx:id="interestRateTextField" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<TextField fx:id="monthlyPaymentTextField" editable="false" focusTraversable="false" GridPane.columnIndex="1" GridPane.rowIndex="5" />
<Slider fx:id="loanDurationSlider" blockIncrement="10.0" max="30.0" value="10.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Button maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#calculateButtonPressed" text="Calculate" GridPane.columnIndex="1" GridPane.rowIndex="6" />
</children>
<padding>
<Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
</padding>
</GridPane>
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.<init>(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<Number>() {
@Override
public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue)
{
loanDurationTextField.setText(newValue.intValue().toString()));//or loanDurationTextField.setText(Integer.toString(newValue.intValue())); if intValue().toString() is not valid.
}
}
);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论