NullPointerException при действии выполнено. Не уверен почему - PullRequest
3 голосов
/ 30 января 2012

Я создаю программу на Java, которая использует графический интерфейс для отображения ипотечного платежа.Я пытаюсь вывести в текстовую область платежи, которые будут сделаны для ипотеки.Вот мой код:

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

Когда я запускаю программу, я вижу графический интерфейс, но когда я нажимаю кнопку для вычисления, я получаю это в консоли:

Исключение в потоке«AWT-EventQueue-0» java.lang.NullPointerException в MortgageGui.actionPerformed (MortgageGui.java:100) в javax.swing.AbstractButton.fireActionPerformed (AbstractButton.java:2018) в javax.swing.AbstractButton $.java: 2341) по адресу javax.swing.DefaultButtonModel.fireActionPerformed (DefaultButtonModel.java:402) по адресу javax.swing.DefaultButtonModel.setPressed (DefaultButtonModel.java:259) по адресу javax.swing.plafButtonLaseJava: 252) в java.awt.Component.processMouseEvent (Component.java:6505) в javax.swing.JComponent.processMouseEvent (JComponent.java:3321) в java.awt.Component.processEvent (Component.java:6270)java.awt.Container.processEvent (Container.java:2229) в java.awt.Component.dispatchEventImpl (Component.java:4861) в java.awt.Container.dispatchEventImpl (Container.java:2287) в java.awt.Component.dispatchEvent (Component.java:4687) в java.awt.LightweightDispatcher.retargetMouseEvent (Container.java:4832) в java.awt.LightproserviceMat.java: 4492) в java.awt.LightweightDispatcher.dispatchEvent (Container.java:4422) в java.awt.Container.dispatchEventImpl (Container.java:2273) в java.awt.Window.dispatchEventImpl (Window.java:27)в java.awt.Component.dispatchEvent (Component.java:4687) в java.awt.EventQueue.dispatchEventImpl (EventQueue.java:707) в java.awt.EventQueue.access $ 000 (EventQueue.java:1awt) в Java..EventQueue $ 3.run (EventQueue.java:666) в java.awt.EventQueue $ 3.run (EventQueue.java:664) в java.security.AccessController.doPrivileged (собственный метод) в java.security.ProtectionDomain $ 1.doIntersectionriProtectionDomain.java:76) в java.security.ProtectionDomain $ 1.doIntersectionPrivilege (ProtectionDomain.java:87) в java.awt.EventQueue $ 4.run (EventQueue.java:680) в java.awt.EventQueue $ 4.run (EventQueue.java:678) в java.security.AccessController.doPrivileged (собственный метод) в java.security.ProtectionDomain $ 1.doIntersectionPrivilege (ProtectionDomain.java:76) в java.awt.Eventpued.EventEventQueue.java:677) в java.awt.EventDispatchThread.pumpOneEventForFilters (EventDispatchThread.java:211) в java.awt.EventDispatchThread.pumpEventsForFilter (EventDispatchThread.javaisp_WD).) в java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:113) в java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:105) в java.awt.EventDispatchThread.run (EventDisp)1008 *

Я не могу понять, где я иду не так.Пожалуйста, помогите!

Ответы [ 3 ]

5 голосов
/ 30 января 2012

Вы переделываете переменную paymentList в конструктор класса

  JTextArea paymentList = new JTextArea("", 17, 27);

Переменная внутри конструктора "затеняет" поле класса, так что конструктор не видит поле класса. Эта локальная переменная видима только внутри конструктора (поскольку она была объявлена ​​внутри него), и поле класса останется нулевым.

Решение: не объявляйте переменную в конструкторе. Можно инициализировать его там, но не объявляйте его повторно:

  paymentList = new JTextArea("", 17, 27);

На более общем замечании вы всегда должны проверять переменные в строке, которая выбрасывает NPE, потому что одна из них равна нулю. Если бы вы увидели, что это был paymentList, вы быстро смогли бы определить, что я вам только что показал, и вам не понадобится наша помощь, что является одной из целей этого форума - чтобы вы могли решать проблемы. по своему усмотрению.

Edit:
Также обратите внимание, что вы делаете эту ошибку более одного раза в своем коде. Я позволю вам найти другие случаи этого.

Редактировать 2:
Подумайте о том, чтобы поместить JTextArea в JScrollPane. Подумайте об использовании некоторых приличных менеджеров компоновки и не устанавливайте размер графического интерфейса, а дайте менеджерам компоновки сделать это за вас.

3 голосов
/ 30 января 2012

Поле:

JTextArea paymentList;

никогда не инициализируется, поэтому оно становится нулевым, когда вы пытаетесь установить значение "".

То же самое относится к loanAmount.

@ Hovercraft Full Of Eels объяснил, почему они не инициализируются так, как вы думаете, в другом ответе ...

Бонусный совет :строка

  loanAmt = Double.valueOf(amount).doubleValue();

вызовет исключение, если сумма кредита будет пустой (или недопустимым двойным) - вам нужно будет использовать try-catch для обработки этого

0 голосов
/ 19 июня 2015

"loanAmount", "loanTypeBox", "paymentList"

Для этих трех, Вы должны закомментировать эти три строки, потому что вы уже объявили их, требуется только назначение;

    //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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...