2

I am relatively new in Java and I got stuck with "AWT-EventQueue-0" error. I tried to search a lot but I still can't fix my code.

I am trying to make a Hangman game with numbers, the program creates a random number between 1 and 100. Then the program will create a button grid of 100 buttons. You have 10 guesses after what, the program will show a popup box and ask if you want to play another game. If you win, the program will beep and the popup box will show up.

Here is my GameFrame class, where I create my root panel and buttons grid:

...
public int wrongGuess = 5;

public GameFrame() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(1000, 500);
        rootPanel.setLayout(new BoxLayout(rootPanel, BoxLayout.X_AXIS));
        rootPanel.add(getButtonGrid(), BorderLayout.CENTER);
        rootPanel.add(gp, BorderLayout.CENTER);
        add(rootPanel);
        setFocusable(true);
        setCentered(true);
        setVisible(true);
}

private Container getButtonGrid() {
    JPanel buttonsGrid = new JPanel(new GridLayout(10,10,0,0));
    Dimension d = new Dimension(0,20);
    for (int i = 1; i < buttons.length; i++) {
        buttons[i] = new JButton(String.valueOf(i));
        buttons[i].setPreferredSize(d);
        buttons[i].addActionListener(this);
        buttonsGrid.add(buttons[i]);
    }
    return buttonsGrid;
}

@Override public void actionPerformed(ActionEvent ae) {
    boolean win = false;
    wrongGuess = wrongGuess + 1;
    setWrongGuess(wrongGuess);
    int buttonNumber = Integer.valueOf(((JButton) ae.getSource()).getActionCommand());
    if (buttonNumber == ge.getGuessingNumber()) {
        win = true;
        buttons[buttonNumber].setBackground(new Color(60,179,113));
        buttons[buttonNumber].setOpaque(true);
        Toolkit.getDefaultToolkit().beep();
        ge.start();
    } else {
        if (buttonNumber > ge.getGuessingNumber()) {
            buttons[buttonNumber].setBackground(new Color(220,20,60));
            buttons[buttonNumber].setOpaque(true);
        }
        if (buttonNumber < ge.getGuessingNumber()) {
            buttons[buttonNumber].setBackground(new Color(255,255,102));
            buttons[buttonNumber].setOpaque(true);
        }
    }
    if (wrongGuess == 10) {
        win = true;
        ge.start();
        setWrongGuess(0);
    }
    if (win == true) {
        for (int i = 1; i < buttons.length; i++) {
            buttons[i].setBackground(null);
        }
    }
}
...

Every time when the user has a wrong guess, I want to display a "Hangman part" (ex. arm, leg...etc).

Here is my GamePanel class:

GameFrame gf;

public GamePanel() {
    this.setSize(500, 500);
    this.setVisible(true);
    this.setFocusable(true);
}

public void paint(Graphics comp) {
    super.paintComponent(comp);
    int wrongGuess = gf.wrongGuess;

    if (wrongGuess == 5) {
        comp.drawOval(162, 150, 50, 50);
        comp.drawLine(188, 200, 188, 275);
        comp.drawLine(148, 235, 188, 215);
        comp.drawLine(188, 215, 228, 235);
        comp.drawLine(188, 275, 228, 335);
        comp.drawLine(148, 335, 188, 275);
    }
    repaint();
}

I assuming that I declared "wrongGuess" incorrectly but I don't know what I did wrong. Can anyone please help me to find the right way of solving this error?

My error:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at micro.project.GamePanel.paint(GamePanel.java:21)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5217)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)
at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
at javax.swing.JComponent.paint(JComponent.java:1042)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:79)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:116)
at java.awt.Container.paint(Container.java:1975)
at java.awt.Window.paint(Window.java:3904)
at javax.swing.RepaintManager$4.run(RepaintManager.java:842)
at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
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$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
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)

PS: Sorry for my broken English

Anton Sergeyev
  • 809
  • 1
  • 10
  • 23
  • 1
    [What is a Null Pointer Exception, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it) – MadProgrammer Mar 16 '17 at 19:46
  • My guess is `gf` is `null` – MadProgrammer Mar 16 '17 at 19:46
  • @MadProgrammer I looked at this many times, still confused – Anton Sergeyev Mar 16 '17 at 19:47
  • @MadProgrammer correct, but the problem is that it can't be null because it equals 5 – Anton Sergeyev Mar 16 '17 at 19:48
  • The reference to `GameFrame` in `GamePanel` is `null`. Also, you've overridden `paint` and are calling `super.paintComponent`, not a good idea, override `paintComponent` instead (and call `super.paintComponent`) – MadProgrammer Mar 16 '17 at 19:54
  • @MadProgrammer thank you for the tip, can you please show what you mean? As I said, I am new in java and I want to understand what I am doing – Anton Sergeyev Mar 16 '17 at 19:56
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – VGR Mar 16 '17 at 20:33

2 Answers2

1

The reference to GameFrame is null in GamePanel, instead you need to pass a reference of GameFrame to GamePanel...

GameFrame gf;

public GamePanel(GameFrame gf) {
    this.gf = gf;
    // Pointless as the layout manager will take care of it
    //this.setSize(500, 500);
    // Pointless as Swing components are visible by default
    //this.setVisible(true);
    this.setFocusable(true);
}

@Overrride
protected void paintComponent(Graphics comp) {
    super.paintComponent(comp);
    int wrongGuess = gf.wrongGuess;

    if (wrongGuess == 5) {
        comp.drawOval(162, 150, 50, 50);
        comp.drawLine(188, 200, 188, 275);
        comp.drawLine(148, 235, 188, 215);
        comp.drawLine(188, 215, 228, 235);
        comp.drawLine(188, 275, 228, 335);
        comp.drawLine(148, 335, 188, 275);
    }
    // Don't do this here, this will cause no end of issues
    //repaint();
}

Also, you're overriding paint but calling super.paintComponent, which is breaking the whole paint chain - don't do this unless you really know what you're doing. Instead, as demonstrated, simply override paintComponent

MadProgrammer
  • 323,026
  • 21
  • 204
  • 329
  • Thank you for your advice. Sorry for tons of questions. If I create a constructor in GamePanel class, I won't be able to display my "Hangman panel" because I am calling `GamePanel` in my `GameFrame` class. Which in this case will give me a `Exception in thread "main" java.lang.NullPointerException`. – Anton Sergeyev Mar 16 '17 at 20:05
  • Well, without a fully runnable example which demonstrates your problem, it's impossible to provide a fully qualifiable answer, since you keep adding pieces to the puzzle we don't know about, this is the best we can do with only a partial view of the problem – MadProgrammer Mar 16 '17 at 21:05
  • Thank you very much anyways! I found the solution based on your answer. You helped me a lot :) – Anton Sergeyev Mar 16 '17 at 21:09
0

This is a typical Null Pointer Exception, any time you declare a reference like

GameFrame gf; 

and then reference it like gf.wrongGuess(); without instantiating an object like

gf = new GameFrame();

the gf wouldn't be pointing to any object, it's just a reference to nothing so it throws a NPE

  • Hm... Ok, so in this case do I have to create another class for the root panel and then point these to panels to my root? Because if I say `GameFrame gf = new GameFramer();` The program will give my another error `java.lang.StackOverflowError` – Anton Sergeyev Mar 16 '17 at 19:53
  • How about you just pass a reference of `GameFrame` to `GamePanel` – MadProgrammer Mar 16 '17 at 19:55
  • you should have a constructor in GamePanel that accepts a GameFrame paramater and then assign the object you instantiate in GameFrame in the constructor so gf = the GameFrame object you originally created and passed through the constructor you can then use that same object anywhere in GamePanel – Brendan Robert Mar 16 '17 at 19:57