-1

I am trying to remove a component from a jpanel but it keeps giving me a NullpointerException. I am trying to remove a component from the jpanel and then add a label in its place.

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;


public class Minefield extends JFrame
{
private final int ROWS= 3;
private final int COLS=3;
public JButton[][] grid ;
private GridBagConstraints c;
private JPanel display;
public Minefield()
{
    grid = new JButton[ROWS][COLS];
    JPanel display = new JPanel();
    add(display);
    display.setLayout(new GridBagLayout());
     c = new GridBagConstraints();  
    c.fill = GridBagConstraints.HORIZONTAL; 
    c.fill = GridBagConstraints.VERTICAL; 
    MouseHandler handler = new MouseHandler();
    for(int row=0;row<ROWS;row++)
    {
        for(int col =0;col<COLS;col++)
        {
            grid[row][col]=new JButton(""+row+","+col);
            c.gridx = col;  
            c.gridy = row;
            display.add(grid[row][col],c);
            grid[row][col].addMouseListener(handler);
        }
    }

}
private class MouseHandler  implements MouseListener
{
    public void mouseClicked(MouseEvent event)
    {
        for(int row=0;row<ROWS;row++)
        {
            for(int col =0;col<COLS;col++)
            {
                if(event.getSource()== grid[row][col])
                {

                    remove(grid[row][col]);
                    display.revalidate();
                }
            }
        }
    }
    public void mousePressed(MouseEvent me){}
    public void mouseReleased(MouseEvent me){}
    public void mouseEntered(MouseEvent me){}
    public void mouseExited(MouseEvent me){}
}

}

And here is the error it gives me

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at Minefield$MouseHandler.mouseClicked(Minefield.java:48)
    at java.desktop/java.awt.AWTEventMulticaster.mouseClicked(Unknown Source)
    at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
    at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.desktop/java.awt.Component.processEvent(Unknown Source)
    at java.desktop/java.awt.Container.processEvent(Unknown Source)
    at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.desktop/java.awt.EventQueue.access$600(Unknown Source)
    at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
    at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
    at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)

Line 48 is display.revalidate().

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
Richard Teunen
  • 79
  • 1
  • 1
  • 5
  • 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) See [What is a stack trace, and how can I use it to debug my application errors?](http://stackoverflow.com/q/3988788/418556) – Andrew Thompson Aug 17 '18 at 16:04

1 Answers1

4

You have declared two variables named display:

public class Minefield extends JFrame
{
    // ...

    private JPanel display;
    public Minefield()
    {
        grid = new JButton[ROWS][COLS];
        JPanel display = new JPanel();
        // ...

This second variable is local in the constructor. When you call display.revalidate(), you are accessing the private field which has not been initialized.

To fix the problem, you can just remove the declaration:

display = new JPanel();

Better, yet, you can initialize the field inline:

public class Minefield extends JFrame
{
    // ...
    private JPanel display = new JPanel();

Then remove the line JPanel display = new JPanel(); from the constructor.

Note

You are doing more work than necessary in mouseClicked(). You do not need any for loop. You can just use event.getSource() directly for the same effect:

private class MouseHandler  implements MouseListener
{
    public void mouseClicked(MouseEvent event)
    {
        remove(event.getSource());
        display.revalidate();
    }
    public void mousePressed(MouseEvent me){}
    public void mouseReleased(MouseEvent me){}
    public void mouseEntered(MouseEvent me){}
    public void mouseExited(MouseEvent me){}
}

After closer examination, I see that both this and your original code have a flaw that might affect other parts of your application that aren't shown here (or that you haven't written yet). The mouseClicked() function will remove a button from being displayed, but you still have a reference to the button in grid. This might cause problems if you try to access the buttons in the grid array and assume that they are rendered in the JPanel.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268