actionPerformed处的NullPointerException。不知道为什么

时间:2012-01-29 21:26:45

标签: java swing nullpointerexception

我正在创建一个使用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)

我无法弄清楚我哪里出错了。请帮忙!

3 个答案:

答案 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();
    }
}

输出如下,控制台上没有发现任何错误;

enter image description here