【问题标题】:NullPointerException in a Java Swing application [duplicate]Java Swing 应用程序中的 NullPointerException [重复]
【发布时间】:2015-07-15 00:09:50
【问题描述】:

我有一个实现卡片布局的类:

CardWindow.java

import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import extraction.gui.Diagram;
import extraction.main.Main;

public class CardWindow extends JPanel{

/**
 * 
 */
private static final long serialVersionUID = 1L;
private JFrame f;
private JPanel panel_1, panel_2;
private JButton btnNext, btnBack;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                CardWindow window = new CardWindow();
                window.f.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public CardWindow() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    f = new JFrame();
    f.setBounds(100, 100, 1000, 480);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.getContentPane().setLayout(new CardLayout(0, 0));

    panel_1 = new Main_1();
    panel_2 = new Snd();
    f.getContentPane().add(panel_1);
    f.getContentPane().add(panel_2);
    panel_1.setVisible(true);
    panel_2.setVisible(false);

    btnNext = new JButton("Next");
    btnNext.setBounds(829, 417, 161, 29);
    panel_1.add(btnNext);
    btnNext.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            panel_1.setVisible(false);
            panel_2.setVisible(true);
        }
    });

    btnBack = new JButton("Back");
    btnBack.setBounds(919, 5, 75, 29);
    panel_2.add(btnBack);
    btnBack.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            panel_2.setVisible(false);
            panel_1.setVisible(true);
        }
    });

}
}

Main_1.java

import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JLabel;


public class Main_1 extends JPanel {
private JTextField textField;

/**
 * Create the panel.
 */
public Main_1() {
    setLayout(null);

    textField = new JTextField();
    textField.setBounds(131, 69, 134, 28);
    add(textField);
    textField.setColumns(10);

    JButton btnCalculate = new JButton("Calculate");
    btnCalculate.setBounds(131, 122, 117, 29);
    add(btnCalculate);
btnCalculate.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Calculate cal = new Calculate(textField.getText());
        }
    });


}
}

Snd.java

import javax.swing.JPanel;
import javax.swing.JLabel;


public class Snd extends JPanel {

/**
 * Create the panel.
 */
public Snd() {
    setLayout(null);

    Calculate _cal = new Calculate();

    JLabel label = new JLabel("New label");
    label.setBounds(180, 120, 61, 16);
    add(label);
    label.setText(_cal.getNum().get(0).toString());

}

}

Calculate.java

import java.util.ArrayList;
import java.util.List;


public class Calculate {

private List<Integer> abc;

public Calculate () {

}

public Calculate(String number) {
    abc = new ArrayList<Integer>();
    int num = Integer.valueOf(number);
    for (int i=0;i<num;i++) {
        abc.add(i);
    }
System.out.println(abc);
}

public List<Integer> getNum() {
    return abc;
}
}

我还有另外两个JPanel 课程:Main_1.javaSnd.java

基本上当我打开应用程序时,它会显示Main_1.java。我输入了一些值,它在Calculate.java 中运行了一些东西。然后当我单击下一个按钮btnNext 时,它应该将处理后的数据显示到下一张卡片Snd.java 上。但是我在尝试运行应用程序时收到了java.lang.NullPointerException

NPE 在这一行 label.setText(_cal.getNum().get(0).toString());

错误

java.lang.NullPointerException
at Snd.<init>(Snd.java:18)
at CardWindow.initialize(CardWindow.java:59)
at CardWindow.<init>(CardWindow.java:46)
at CardWindow$1.run(CardWindow.java:33)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

我明白它为什么会产生 NPE,但我不知道如何解决它。当我运行程序时,我不明白为什么它也尝试运行Snd.java,因为我没有点击任何按钮转到下一张卡片,即Snd.java

这只是一个可运行的示例,用于展示我想要实现的目标。基本上我想在Main_1.java 中处理一些东西并将数据传输到Snd.java,在那里我将在那里进行另一个处理。

【问题讨论】:

  • 考虑提供一个runnable example 来证明您的问题。这不是代码转储,而是您正在做的事情的一个示例,它突出了您遇到的问题。这将导致更少的混乱和更好的响应
  • @MadProgrammer ok 已经包含了一个可运行的示例。
  • @vaxquis 不,我完全理解 NPE 是什么。我知道是什么导致了 NPE,但这是因为我无法修复它,所以我在 SO 中发布了它。你仔细阅读我的问题了吗??
  • @sw2 你和我一样错了三次。 a)仅仅因为您不理解我提供给您的主题,并不意味着我没有阅读您的问题;我做到了,但我理解你的代码及其问题的不同之处——而你没有; - 另外,b) 提供的链接显示如何修复它。如果您对修复异常不感兴趣,那是您的决定,c) 您发布的问题是基本的,无论是在定位问题的根源还是在修复它方面。所以不是你的私人军队,我们也不是你的私人调试团队。你的“问题”已经解决了无数次了。
  • @sw2 还有,如果你做了understand perfectly what NPE is,你就不必来 SO 并且会自己修复它;你出现en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect的急性症状

标签: java swing nullpointerexception layout-manager cardlayout


【解决方案1】:

在您的示例中,您的问题是您新创建的Calculate 已将abc 隐式设置为null;您不会在默认构造函数中对其进行初始化。因为是null,所以不能在上面使用isEmpty()等。正确使用

private List<Integer> abc = new ArrayList<Integer>();

在类构造函数/初始化器/任何东西之前使用它来修复它。

【讨论】:

  • 没有。这并不能解决问题,并且与我的问题无关。即使我删除了if 语句,它仍然不起作用。问题在于label.setText。如果我删除这个label.setText,然后尝试运行该程序,它可以工作,并且在控制台中很好地打印出来。
  • @sw2 如果在另外 2 个人给出与我完全相同的答案后,我仍然很确定我错了这个答案 - 适合你自己。
【解决方案2】:

这不是一个完整的答案,更多的是指向(通常)NPEs 如何发生的正确方向。

我把Caluclate.java改成了

import java.util.ArrayList;
import java.util.List;

public class Calculate
{
    private final List<Integer> abc = new ArrayList<>();

    public Calculate(String number) {
        abc.clear ();
        int num = Integer.valueOf(number);
        for (int i = 0; i < num; i++) {
            abc.add(i);
        }
        System.out.println(abc);
    }

    public List<Integer> getNum() {
        return abc;
    }
}

主要区别在于

  1. 该列表一旦初始化,这意味着当您调用getNum () 方法时,您始终可以保证它存在。
  2. 它现在使用 ArrayList.clear () 而不是声明新列表,而不是重新声明它(仍然可能,如果您希望这样做,您不必删除 final 关键字)。

还有一些笔记涉及

  • 利用钻石运算符&lt;&gt;,在Java7中引入
  • 在代码中增加了一些间距,让它呼吸。
  • 删除了构造函数,因为它什么也没做。

当您像在 Snd.java 课程中一样使用代码时,您会遇到问题。

import javax.swing.JPanel;
import javax.swing.JLabel;

public class Snd extends JPanel
{
    /**
     * Create the panel.
     */
    public Snd() {
        setLayout(null);

        Calculate _cal = new Calculate();

        JLabel label = new JLabel("New label");
        label.setBounds(180, 120, 61, 16);
        add(label);
        label.setText(_cal.getNum().get(0).toString()); // problem occurs here
    }
}

为什么?因为abc 没有被初始化。您必须使用其 String 构造函数调用 Calculate。你不是。

【讨论】:

    【解决方案3】:

    在第 59 行的 CardWindow.initialize() 中,您调用:

    panel_2 = new Snd();
    

    这又会导致第 18 行的Snd.&lt;init&gt;() 是:

    label.setText(_cal.getNum().get(0).toString());
    

    如果我们把它分成几行:

    label.setText(
      _cal
      .getNum()     // this returns null
      .get(0)       // causing a NullPointerException here
      .toString());
    

    因为_cal 是这样定义的:

    Calculate _cal = new Calculate();
    

    Calculate 的无参数构造函数为空,将 List&lt;Integer&gt; abc 设置为 null


    如何解决这个问题取决于你想要什么行为。乍一看,Calculate 不应该有一个无参数的构造函数;也许你应该删除它,只有在你有一个数字要传递时才初始化_cal

    既然你说你还不想调用Snd,另一种方法是避免在CardWindow.initialize() 中构造Snd 实例。

    【讨论】:

    • 任何反馈,否决者?我的回答解释了 NPE 的原因并提供了一些可能的修复方法;有什么问题?
    猜你喜欢
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多