-2

I have a class that implements card layout:

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

I have two other JPanel classes: Main_1.java, Snd.java

Basically when I open the application, it will show Main_1.java. I enter some values and it run something in Calculate.java. Then when I click the next button btnNext, it's supposed to display the processed data onto the next card Snd.java. But I got java.lang.NullPointerException when trying to run the application.

NPE at this line label.setText(_cal.getNum().get(0).toString());

Error

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)

I understand why it's giving NPE but I don't know how to solve it. When I run the program, I don't understand why it's trying to run Snd.java as well because I didn't click any button to go to the next card, which is Snd.java.

This is just a runnable example which is to show what I want to achieve. Basically I want to process something in Main_1.java and transfer the data to Snd.java where I will do another process there.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
sw2
  • 357
  • 6
  • 13
  • 2
    Consider providing a [runnable example](https://stackoverflow.com/help/mcve) which demonstrates your problem. This is not a code dump, but an example of what you are doing which highlights the problem you are having. This will result in less confusion and better responses – MadProgrammer Jul 15 '15 at 01:21
  • @MadProgrammer ok already include a runnable example. – sw2 Jul 15 '15 at 01:58
  • @vaxquis No. I understand perfectly what NPE is. I know what's causing the NPE but it's because I can't fix it that I posted in SO. Have you read my question thoroughly?? – sw2 Jul 15 '15 at 02:36
  • 1
    @sw2 you're thrice as wrong as I though. a) Just because you don't understand the topic I provided to you, doesn't mean I haven't read your question; I did, with the very difference I understand your code and its problem - and you don't; - also, b) the link provided shows *how to fix it*. If you ain't interested in fixing your exception, that's your call, c) the problem you posted is elementary, both in locating the source of the problem, and in fixing it. SO ain't your personal army, and we ain't your private debugging team. Your "problem" has been solved already countless times. –  Jul 15 '15 at 02:42
  • 2
    @sw2 also, if you did `understand perfectly what NPE is`, you wouldn't have to come to SO and would've fix it by yourself; you're showing acute symptoms of https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect –  Jul 15 '15 at 02:44

3 Answers3

0

In your example, your problem is that your newly created Calculate has abc set to null implicitly; you don't initialize it in the default constructor. Since it's null, you can't use isEmpty() etc. on it. Use proper

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

in the class constructor/initalizer/whatever before using it to fix it.

  • No. This doesn't solve the problem and not related to my problem. Even if I remove the `if` statement, it still doesn't work. The problem lies on the `label.setText`. If I remove this `label.setText`, then try to run the program, it works, and it prints out nicely in the console. – sw2 Jul 15 '15 at 02:44
  • @sw2 if you're still so sure I was wrong about this one after 2 other people giving you exactly the same answer as me - suit yourself. –  Jul 15 '15 at 12:04
-1

This is not a complete answer, more a pointer in the right direction of how (commonly) NPEs occur.

I changed in Caluclate.java to

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

The main difference is that

  1. The list is once initialized, meaning you can always guarantee that it exists when you invoke your getNum () method.
  2. Instead of redeclaring it (still possible, do not you have to remove the final keyword if you want that to be possible) it now makes use of the ArrayList.clear () instead of declaring a new list.

Some more notes involve

  • Making use of the diamond operator <>, introduced in Java7
  • Added some more spacing in the code, let it breath.
  • Removed the constructor as it did nothing.

You will have trouble with your code when using it like you are in your Snd.java class.

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

Why? Because abc wasn't initialized. You had to invoke Calculate with its String constructor. Which you weren't.

Emz
  • 1,280
  • 1
  • 14
  • 29
-2

In CardWindow.initialize() on line 59 you call:

panel_2 = new Snd();

This, in turn, leads to Snd.<init>() on line 18 which is:

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

If we break this into separate lines:

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

Because _cal is defined like so:

Calculate _cal = new Calculate();

And the no-argument constructor for Calculate is empty, leaving List<Integer> abc set to null.


How you fix this depends on what behavior you want. At a glance, it doesn't look like Calculate should have a no-argument constructor; perhaps you should remove it and only initialize _cal once you have a number to pass.

Since you say you don't want to call Snd yet, an alternative would be to avoid constructing a Snd instance in CardWindow.initialize().

dimo414
  • 47,227
  • 18
  • 148
  • 244
  • Any feedback, downvoter? My answer explains the cause of the NPE and offers some possible fixes; what's the problem? – dimo414 Jul 15 '15 at 15:52