David
David

Reputation: 1765

Minecraft Spigot/Bukkit plugin throws NullPointerException on equality check

I'm trying to create a menu, and I want to make sure all players have the compass on join.

My code does not work- if you have a no-named compass in your inventory, it just doesn't give you a compass. If I don't check for those == null, my code gives a NullPointerException with the above described conditions.

Eclipse displays no errors. What am I doing wrong?

package me.psrcek.compassMenu.listeners;

import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

public class PlayerJoinListener implements Listener {

    @EventHandler
    public void onJoin(PlayerJoinEvent e) {
        ItemStack[] inv = e.getPlayer().getInventory().getContents();
        
        for (ItemStack item : inv) {
            if (item == null) continue;
            
            if (item.getType().equals(Material.COMPASS)) {
                if (item.getItemMeta().getDisplayName() == null) continue;
                
                if (item.getItemMeta().getDisplayName().equals(ChatColor.RESET + "" + ChatColor.AQUA + "Menu")) {
                    e.getPlayer().sendMessage("found proppertly named compass");
                    return;
                }
            }
        }
        
        ItemStack compass = new ItemStack(Material.COMPASS);
        ItemMeta compassMeta = compass.getItemMeta();
        
        compassMeta.setDisplayName(ChatColor.RESET + "" + ChatColor.AQUA + "Menu");
        
        compass.setItemMeta(compassMeta);
        
        e.getPlayer().getInventory().addItem(compass);
        e.getPlayer().updateInventory();

    }

}

Upvotes: 0

Views: 835

Answers (3)

Jelle den Burger
Jelle den Burger

Reputation: 1468

The .equals method and the == operator are not the same thing.

.equals compares the values of the objects.

== compares the reference (location in memory) of the objects.

Example:

Integer x = 10;
Integer y = 10;

// is false
System.out.println(x == y)

// is true
System.out.println(x.equals(y)) 

Upvotes: 0

Jon Bruce
Jon Bruce

Reputation: 21

I see a couple places from which a NullPointerException could come. First, you are checking in the item is null, and if it is, checking if it is a compass. But if it's null, it can't also be a compass. Try this instead:

if(item != null){
    if(item.getType() == Material.COMPASS){

    }
}

The second spot I saw right away is in that same for loop, when you get the compass's item meta. Well Bukkit doesn't like to say that an itemStack has an itemMeta until you assign it one, so try this instead:

if(item.getType() == Material.COMPASS){
    if(item.hasItemMeta()){
        if(item.getItemMeta().getDisplayName().contains(ChatColor.AQUA + "Menu"){
            p.sendMessage("found properly named compass");
            return;
        }
    }
}

If you want a much simpler way to go about this though, I would recommend using the following example code:

ItemStack compass = new ItemStack(Material.COMPASS);
ItemMeta compassMeta = compass.getItemMeta();

//No need to use ChatColor.RESET before the text has a color
compassMeta.setDisplayName(ChatColor.AQUA + "Menu");

compass.setItemMeta(compassMeta);

for(ItemStack item:e.getPlayer().getInventory().getContents()){
    if(item != null){
        if(item.equals(compass)){
            p.sendMessage("found properly named compass");
            return;
        }
    }
}

Hope this was helpful to you.

Upvotes: 1

David
David

Reputation: 1765

I don't know why this worked, but changing

item.getType().equals(Material.COMPASS)

to

item.getType() == Material.COMPASS

made it work. I always thought those were the same thing.

Upvotes: 1

Related Questions