0

I have been struggling a lot with a NullPointerException on a class method. The problem is that when I call variables that are initialized on the constructor, they return null. Remember that the KitGUI extends GUI.

package src.foundation.core.game.kit;

import org.bukkit.entity.Player;

import src.foundation.core.GUI;
import src.foundation.core.game.Game;
import src.foundation.core.game.Kit;
import src.foundation.core.util.ItemStackFactory;

public class KitGUI extends GUI
{
    private Game game;
    private Player player;

    public KitGUI(Game game, Player player)
    {
        super(player, "Select Kit", 27);
        this.game = game;
        this.player = player;
    }

    public void addItems()
    {
        for (Kit kit : this.game.getKits())
        {
            // NullPointerException...
            addMenuItem(ItemStackFactory.createItem(kit.getDisplay()));
        }
    }

    public void checkItems()
    {
        for (Kit kit : game.getKits())
        {
            if (getClick().getItemMeta().getDisplayName().contains(kit.getName()))
            {
                game.selectKit(getPlayer(), kit);
                break;
            }
        }
    }
}

And the GUI class:

package src.foundation.core;

import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryInteractEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;

public abstract class GUI extends Module
{
    private String name;
    private int slots;

    private Inventory inventory;

    private Player player;
    private ItemStack choice;

    public GUI(Player player, String name, int slots)
    {
        super("GUI");

        this.name = name;
        this.slots = slots;
        this.player = player;

        this.inventory = Bukkit.createInventory(null, this.slots, this.name);

        addItems();

        this.player.openInventory(inventory);
    }

    public abstract void addItems();

    public abstract void checkItems();

    public void addMenuItem(ItemStack item)
    {
        this.inventory.addItem(item);
    }

    public Inventory getInventory()
    {
        return this.inventory;
    }

    public ItemStack getClick()
    {
        return this.choice;
    }

    public Player getPlayer()
    {
        return this.player;
    }

    @EventHandler
    public void selectChoice(InventoryClickEvent e)
    {
        this.player = (Player) e.getWhoClicked();
        this.choice = e.getCursor();

        e.setCancelled(true);

        if (!(e.getInventory().getName().equals(this.name)))
            return;

        if (e.getCurrentItem() == null || !e.getCurrentItem().hasItemMeta() || !e.getCurrentItem().getItemMeta().hasDisplayName())
            return;

        if (e.getCursor().getItemMeta() == null)
            return;

        if (e.isCancelled() == true)
        {
            checkItems();

            this.player.playSound(this.player.getLocation(), Sound.CHICKEN_EGG_POP, 1.0F, 1.0F);

            this.player.closeInventory();
        }
    }
}

Stack Trace:

Caused by: java.lang.NullPointerException
        at src.foundation.core.game.kit.KitGUI.addItems(KitGUI.java:25) ~[?:?]
        at src.foundation.core.GUI.<init>(GUI.java:32) ~[?:?]
        at src.foundation.core.game.kit.KitGUI.<init>(KitGUI.java:18) ~[?:?]
        at src.foundation.core.game.GameManager.lobbyItemsUse(GameManager.java:2
68) ~[?:?]

Any ideas on where the problem might be? Regards.

Thanos Paravantis
  • 7,393
  • 3
  • 17
  • 24
  • Can you include stacktrace? – Pshemo Sep 28 '14 at 18:30
  • Okay, just added it. – Thanos Paravantis Sep 28 '14 at 18:33
  • In `KitGUI` constructor via `super(player, "Select Kit", 27);` you are invoking `GUI` constructor which invokes `addItems();` method (implemented in `KitGUI` class) which invokes `this.game.getKits()` but since we are in the middle of `super(player, "Select Kit", 27);` `this.game = game;` from `KitGUI` constructor wasn't yet invoked so `geme` is still `null` which means that in `this.game.getKits()` you are actually invoking `null.getKits()` which throws NPE. – Pshemo Sep 28 '14 at 18:42
  • Stay put, let me check that! – Thanos Paravantis Sep 28 '14 at 18:45
  • Hmm, I don't really understand the solution, should I move the addItems() from the constructor? – Thanos Paravantis Sep 28 '14 at 18:57
  • Yes, since it is based on state of fields which are not set yet. Generally you should avoid invoking methods which can be overridden (are not static, private or final) in constructor precisely because of problem you are facing now. – Pshemo Sep 28 '14 at 19:00

0 Answers0