我正在创建一个使用GUI来显示抵押付款的Java程序。我正在尝试向textArea输出将用于抵押的付款。这是我的代码:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.text.DecimalFormat;
public class MortgageGui extends JFrame implements ActionListener {
// Set two-places for decimal format
DecimalFormat twoPlaces = new DecimalFormat("$0.00");
// Declare variable for calculation
Double loanAmt;
double interestRate;
double monthlyPayment;
int payment;
String amount;
JTextField loanAmount;
JComboBox loanTypeBox;
JLabel paymentOutput;
JTextArea paymentList;
// Build arrays for mortgages
double[] mortgage1 = {7.0, 5.35, 0.0}; // (years, interest, monthly payment)
double[] mortgage2 = {15.0, 5.5, 0.0}; // (years, interest, monthly payment)
double[] mortgage3 = {30.0, 5.75, 0.0}; // (years, interest, monthly payment)
public MortgageGui() {
super("Mortgage Calculator");
setLookAndFeel();
setSize(350, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Loan Amount Panel
JPanel loanAmtPanel = new JPanel();
JLabel loanAmtLabel = new JLabel("Loan Amount: ", JLabel.LEFT);
JTextField loanAmount = new JTextField(10);
loanAmtPanel.add(loanAmtLabel);
loanAmtPanel.add(loanAmount);
// Loan Type Panel
JPanel loanTypePanel = new JPanel();
JLabel loanTypeLabel = new JLabel("Loan Type: ", JLabel.LEFT);
String[] items = {"7 years at 5.35%", "15 years at 5.5%", "30 years at 5.75%"};
JComboBox loanTypeBox = new JComboBox(items);
loanTypePanel.add(loanTypeLabel);
loanTypePanel.add(loanTypeBox);
// Calculate Button Panel
JPanel calculatePanel = new JPanel();
JButton calcButton = new JButton("Calculate Paytment");
calcButton.addActionListener(this);
calculatePanel.add(calcButton);
// Monthly Payment Panel
JPanel paymentPanel = new JPanel();
JLabel paymentLabel = new JLabel("Monthly Payment: ", JLabel.LEFT);
JLabel paymentOutput = new JLabel("Calculated Payment");
paymentPanel.add(paymentLabel);
paymentPanel.add(paymentOutput);
// View Payments Panel
JPanel viewPayments = new JPanel();
JTextArea paymentList = new JTextArea("", 17, 27);
paymentList.setEditable(false);
paymentList.setLineWrap(true);
viewPayments.add(paymentList);
// Add panels to win Panel
JPanel win = new JPanel();
BoxLayout box = new BoxLayout(win, BoxLayout.Y_AXIS);
win.setLayout(box);
win.add(loanAmtPanel);
win.add(loanTypePanel);
win.add(calculatePanel);
win.add(paymentPanel);
win.add(viewPayments);
add(win);
// Make window visible
setVisible(true);
}
private void setLookAndFeel() {
try {
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"
);
} catch (Exception exc) {
// ignore
}
}
public void actionPerformed(ActionEvent e) {
// Clear payment list
paymentList.setText("");
// Get loan amount from textfield
String amount = loanAmount.getText();
loanAmt = Double.valueOf(amount).doubleValue();
// Find which mortgate array to use from combobox
Object obj = loanTypeBox.getSelectedItem();
String loanSelected = obj.toString();
// Run the calculation based on the mortgage arrays
// 7-year loan
if (loanSelected.equals("7 years at 5.35%")) {
// Calculate payment, interest, and remaining
mortgage1[2] = (loanAmt + (loanAmt * (mortgage1[1] / 100))) / (mortgage1[0] * 12);
double interest1 = (loanAmt * (mortgage1[1] / 100)) / 84;
double amountRemaining1 = loanAmt + (loanAmt * (mortgage1[1] / 100));
// Loop through payments
for (int payment = 1; payment <=84; payment++) {
// Deduct one payment from the balance
amountRemaining1 = amountRemaining1 - mortgage1[2];
// Write payment to textArea
paymentList.append("Payment " + payment + ": $" + twoPlaces.format(mortgage1[2]) +
" / " + "Interest: $" + twoPlaces.format(interest1) + " / " +
"Remaining: $" + twoPlaces.format(amountRemaining1) + "\n");
}
} else {
// 15-year loan
if (loanSelected.equals("15 years at 5.5%")) {
// Calculate payment, interest, and remaining
mortgage2[2] = (loanAmt + (loanAmt * (mortgage2[1] / 100))) / (mortgage2[0] * 12);
double interest2 = (loanAmt * (mortgage2[1] / 100)) / 180;
double amountRemaining2 = loanAmt + (loanAmt * (mortgage2[1] / 100));
// Loop through payments
for (int payment = 1; payment <=180; payment++) {
// Deduct one payment from the balance
amountRemaining2 = amountRemaining2 - mortgage2[2];
// Write payment to textArea
paymentList.append("Payment " + payment + ": $" + twoPlaces.format(mortgage2[2]) +
" / " + "Interest: $" + twoPlaces.format(interest2) + " / " +
"Remaining: $" + twoPlaces.format(amountRemaining2) + "\n");
}
} else {
//30-year loan
//Calculate payment, interest, and remaining
mortgage3[2] = (loanAmt + (loanAmt * (mortgage3[1] / 100))) / (mortgage3[0] * 12);
double interest3 = (loanAmt * (mortgage3[1] / 100)) / 360;
double amountRemaining3 = loanAmt + (loanAmt * (mortgage3[1] / 100));
// Loop through payments
for (int payment = 1; payment <=360; payment++) {
// Deduct one payment from the balance
amountRemaining3 = amountRemaining3 - mortgage3[2];
// Write payment to textArea
paymentList.append("Payment " + payment + ": $" + twoPlaces.format(mortgage3[2]) +
" / " + "Interest: $" + twoPlaces.format(interest3) + " / " +
"Remaining: $" + twoPlaces.format(amountRemaining3) + "\n");
}
}
}
}
public static void main(String[] arguments) {
MortgageGui calc = new MortgageGui();
}
}
当我运行程序时,我看到了GUI,但是当我点击按钮计算时,我在控制台中得到了这个:
线程“AWT-EventQueue-0”中的异常java.lang.NullPointerException 在MortgageGui.actionPerformed(MortgageGui.java:100) 在javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018) 在javax.swing.AbstractButton $ Handler.actionPerformed(AbstractButton.java:2341) 在javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402) 在javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) 在javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252) 在java.awt.Component.processMouseEvent(Component.java:6505) 在javax.swing.JComponent.processMouseEvent(JComponent.java:3321) at java.awt.Component.processEvent(Component.java:6270) at java.awt.Container.processEvent(Container.java:2229) at java.awt.Component.dispatchEventImpl(Component.java:4861) at java.awt.Container.dispatchEventImpl(Container.java:2287) at java.awt.Component.dispatchEvent(Component.java:4687) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422) at java.awt.Container.dispatchEventImpl(Container.java:2273) at java.awt.Window.dispatchEventImpl(Window.java:2713) at java.awt.Component.dispatchEvent(Component.java:4687) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707) at java.awt.EventQueue.access $ 000(EventQueue.java:101) at java.awt.EventQueue $ 3.run(EventQueue.java:666) at java.awt.EventQueue $ 3.run(EventQueue.java:664) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(ProtectionDomain.java:87) at java.awt.EventQueue $ 4.run(EventQueue.java:680) at java.awt.EventQueue $ 4.run(EventQueue.java:678) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.awt.EventQueue.dispatchEvent(EventQueue.java:677) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105) 在java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
我无法弄清楚我哪里出错了。请帮忙!
答案 0 :(得分:5)
您正在重新声明类的构造函数
中的paymentList变量 JTextArea paymentList = new JTextArea("", 17, 27);
构造函数内部的变量“阴影”了类字段,因此构造函数不会看到类字段。这个局部变量只在构造函数中可见(因为它是在它内部声明的),并且类字段将保持为null。
解决方案:不要在构造函数中重新声明变量。可以在那里初始化它,但不要重新声明它:
paymentList = new JTextArea("", 17, 27);
更一般地说,您应该始终检查抛出NPE的行上的变量,因为其中一个变量为null。如果你看到它是paymentList,你很快就能识别出我刚给你看的东西,你不需要我们的帮助,这是本论坛的目标 - 让你能够解决问题靠你自己。
修改强>
另请注意,您在代码中多次执行此错误。我会让你找到其他事件。
编辑2:
考虑将JTextArea放在JScrollPane中。考虑使用一些不错的布局管理器,而不是设置GUI的大小,而是让布局管理器为您执行此操作。
答案 1 :(得分:3)
字段:
JTextArea paymentList;
永远不会被初始化,因此当您尝试将值设置为“”时它为null。
loanAmount
同样如此。
@Hovercraft Full Of Eels 解释了为什么他们没有像你认为的那样初始化,在另一个答案中...
奖金提示:行
loanAmt = Double.valueOf(amount).doubleValue();
如果贷款金额为空(或不是有效的双倍),将抛出异常 - 你需要使用try-catch来处理这个
答案 2 :(得分:0)
&#34; loanAmount&#34;,&#34; loanTypeBox&#34;,&#34; paymentList&#34;
对于这三个,你必须注释掉这三行,因为你已经声明了这些,只需要分配;
//JTextField loanAmount = new JTextField(10); // loanAmount: Already declared, only assignment needed
loanAmount = new JTextField(10);
//JComboBox loanTypeBox = new JComboBox(items); // loanTypeBox: Already declared, only assignment needed
loanTypeBox = new JComboBox(items);
//JTextArea paymentList = new JTextArea("", 17, 27);// paymentList: Already declared, only assignment needed
paymentList = new JTextArea("", 17, 27);
这是更新后的代码;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.text.DecimalFormat;
public class MortgageGui extends JFrame implements ActionListener {
// Set two-places for decimal format
DecimalFormat twoPlaces = new DecimalFormat("$0.00");
// Declare variable for calculation
Double loanAmt;
double interestRate;
double monthlyPayment;
int payment;
String amount;
JTextField loanAmount;
JComboBox loanTypeBox;
JLabel paymentOutput;
JTextArea paymentList;
// Build arrays for mortgages
double[] mortgage1 = { 7.0, 5.35, 0.0 }; // (years, interest, monthly
// payment)
double[] mortgage2 = { 15.0, 5.5, 0.0 }; // (years, interest, monthly
// payment)
double[] mortgage3 = { 30.0, 5.75, 0.0 }; // (years, interest, monthly
// payment)
public MortgageGui() {
super("Mortgage Calculator");
setLookAndFeel();
setSize(350, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Loan Amount Panel
JPanel loanAmtPanel = new JPanel();
JLabel loanAmtLabel = new JLabel("Loan Amount: ", JLabel.LEFT);
// JTextField loanAmount = new JTextField(10); // loanAmount: Already declared, only assignment needed
loanAmount = new JTextField(10);
loanAmtPanel.add(loanAmtLabel);
loanAmtPanel.add(loanAmount);
// Loan Type Panel
JPanel loanTypePanel = new JPanel();
JLabel loanTypeLabel = new JLabel("Loan Type: ", JLabel.LEFT);
String[] items = { "7 years at 5.35%", "15 years at 5.5%",
"30 years at 5.75%" };
// JComboBox loanTypeBox = new JComboBox(items); // loanTypeBox: Already declared, only assignment needed
loanTypeBox = new JComboBox(items);
loanTypePanel.add(loanTypeLabel);
loanTypePanel.add(loanTypeBox);
// Calculate Button Panel
JPanel calculatePanel = new JPanel();
JButton calcButton = new JButton("Calculate Paytment");
calcButton.addActionListener(this);
calculatePanel.add(calcButton);
// Monthly Payment Panel
JPanel paymentPanel = new JPanel();
JLabel paymentLabel = new JLabel("Monthly Payment: ", JLabel.LEFT);
JLabel paymentOutput = new JLabel("Calculated Payment");
paymentPanel.add(paymentLabel);
paymentPanel.add(paymentOutput);
// View Payments Panel
JPanel viewPayments = new JPanel();
// JTextArea paymentList = new JTextArea("", 17, 27); // paymentList: Already declared, only assignment needed
paymentList = new JTextArea("", 17, 27);
paymentList.setEditable(false);
paymentList.setLineWrap(true);
viewPayments.add(paymentList);
// Add panels to win Panel
JPanel win = new JPanel();
BoxLayout box = new BoxLayout(win, BoxLayout.Y_AXIS);
win.setLayout(box);
win.add(loanAmtPanel);
win.add(loanTypePanel);
win.add(calculatePanel);
win.add(paymentPanel);
win.add(viewPayments);
add(win);
// Make window visible
setVisible(true);
}
private void setLookAndFeel() {
try {
UIManager
.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception exc) {
// ignore
}
}
public void actionPerformed(ActionEvent e) {
// Clear payment list
paymentList.setText("");
// Get loan amount from textfield
String amount = loanAmount.getText();
loanAmt = Double.valueOf(amount).doubleValue();
// Find which mortgate array to use from combobox
Object obj = loanTypeBox.getSelectedItem();
String loanSelected = obj.toString();
// Run the calculation based on the mortgage arrays
// 7-year loan
if (loanSelected.equals("7 years at 5.35%")) {
// Calculate payment, interest, and remaining
mortgage1[2] = (loanAmt + (loanAmt * (mortgage1[1] / 100)))
/ (mortgage1[0] * 12);
double interest1 = (loanAmt * (mortgage1[1] / 100)) / 84;
double amountRemaining1 = loanAmt
+ (loanAmt * (mortgage1[1] / 100));
// Loop through payments
for (int payment = 1; payment <= 84; payment++) {
// Deduct one payment from the balance
amountRemaining1 = amountRemaining1 - mortgage1[2];
// Write payment to textArea
paymentList.append("Payment " + payment + ": $"
+ twoPlaces.format(mortgage1[2]) + " / "
+ "Interest: $" + twoPlaces.format(interest1) + " / "
+ "Remaining: $" + twoPlaces.format(amountRemaining1)
+ "\n");
}
} else {
// 15-year loan
if (loanSelected.equals("15 years at 5.5%")) {
// Calculate payment, interest, and remaining
mortgage2[2] = (loanAmt + (loanAmt * (mortgage2[1] / 100)))
/ (mortgage2[0] * 12);
double interest2 = (loanAmt * (mortgage2[1] / 100)) / 180;
double amountRemaining2 = loanAmt
+ (loanAmt * (mortgage2[1] / 100));
// Loop through payments
for (int payment = 1; payment <= 180; payment++) {
// Deduct one payment from the balance
amountRemaining2 = amountRemaining2 - mortgage2[2];
// Write payment to textArea
paymentList.append("Payment " + payment + ": $"
+ twoPlaces.format(mortgage2[2]) + " / "
+ "Interest: $" + twoPlaces.format(interest2)
+ " / " + "Remaining: $"
+ twoPlaces.format(amountRemaining2) + "\n");
}
} else {
// 30-year loan
// Calculate payment, interest, and remaining
mortgage3[2] = (loanAmt + (loanAmt * (mortgage3[1] / 100)))
/ (mortgage3[0] * 12);
double interest3 = (loanAmt * (mortgage3[1] / 100)) / 360;
double amountRemaining3 = loanAmt
+ (loanAmt * (mortgage3[1] / 100));
// Loop through payments
for (int payment = 1; payment <= 360; payment++) {
// Deduct one payment from the balance
amountRemaining3 = amountRemaining3 - mortgage3[2];
// Write payment to textArea
paymentList.append("Payment " + payment + ": $"
+ twoPlaces.format(mortgage3[2]) + " / "
+ "Interest: $" + twoPlaces.format(interest3)
+ " / " + "Remaining: $"
+ twoPlaces.format(amountRemaining3) + "\n");
}
}
}
}
public static void main(String[] arguments) {
MortgageGui calc = new MortgageGui();
}
}
输出如下,控制台上没有发现任何错误;