Solved HashMap returns null

Discussion in 'Spigot Plugin Development' started by LikeWhat, Oct 2, 2016.

  1. Hello Spigot Community

    I'm currently trying to save Player and a String in a HashMap... Thats all fine but the Problem i having is when i try to get the Value from the HashMap all it returns is null.

    Heres is the Code that I'm using:

    Code (Java):

    HashMap<Player, String> se = new HashMap<Player, String>();
    public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) {
        Player p = (Player)s;
        if (cmd.getName().equalsIgnoreCase("se")) {
            if(args.length == 0) {
                return false;
            }
            se.put(p, args[0]);
            p.sendMessage("Saved!")
        }
    }

    @EventHandler
        public void click(InventoryClickEvent e) {
            Player p = (Player) e.getWhoClicked();
            if(e.getInventory().getTitle().equalsIgnoreCase("test")) {
                if(e.getCurrentItem().getItemMeta().getDisplayName().equalsIgnoreCase("testitem")) {
                    p.sendMessage("Your Saved String is " + se.get(p));
                }
            }
        }
    [code]
     
    #1 LikeWhat, Oct 2, 2016
    Last edited: Oct 3, 2016
  2. I don't even know why your code compiles, it should be args.length
     
    • Agree Agree x 4
    • Funny Funny x 1
  3. Choco

    Moderator

    Use implementation declarations for things like this. i.e. Map<Player, String> se = new HashMap<>();

    Check if it's a Player before casting. This is a ClassCastException waiting to happen if a console sends this command

    Preeeeetty sure this is wrong. Not sure how this compiled. "length"?
    EDIT: Sniped on this comment

    Is this registered in your onEnable() and running properly?

    This can return null if anywhere outside an inventory is clicked

    All three of these methods can return null given that
    - The player doesn't have an item in hand
    - The item doesn't have meta
    - The item doesn't have a display name set

    EDIT: I suggest an @Override tag on your onCommand() method just for convention reasons
     
  4. Out of curiosity, which IDE are you using? Or are you using Notepad? I don't see how you could have done that.
     
  5. If it constantly returns null and everything else works properly, try using a HashMap<UUID, String> instead of Player, and store and retrieve using UUIDs.
     
  6. @iso2013 storing players is fine, as long as you are absolutely sure that you remove them from the collection when a player quits.

    @ OP: Let me guess: You created 2 instances of the class; 1 that registers the event and 1 that handles the command. Theg both need to be the same instance.
     
    • Winner Winner x 1
  7. 1st:
    Sorry for the typo I wrote the part with Hand because I forgot to insert it at that point =| (It's acually not important)

    2nd:

    still same =/

    You mean this right?
    Code (Java):
    if (s instanceof ConsoleCommandSender) {
                s.sendMessage("§cOnly for Players");
                return true;
            }
    In the Main Class:
    Code (Java):
     getServer().getPluginManager().registerEvents(new Listeners(), this);
    Listeners() is the Class with the Code.

    It's an Custom generated Inventory that contains this item. I didn't include the Inventory thingy because I thought it is irrelevant.

    Still with the Tag it returns null =|
     
  8. Choco

    Moderator

    Usually people check if it's not an instanceof Player in the odd case Mojang decides to add a new potential command sender implementation, but either way it works, yes. Always nice to check if inventory or the item clicked is null though. Regardless of whether it's a custom inventory or not, people can either click outside of the inventory, or click on a slot without an item in it, both resulting in null values.

    As for why the Map returns null, I'm not quite sure, actually. The command tells you "saved"? If so, also print out the value from the map after it's saved in the command (i.e. get the value from the map and print it, see if it's null). If it's not, well... I actually have no clue in the slightest

    Code (Java):
    map.put(p, args[0]);
    p.sendMessage("Saved");
    p.sendMessage(map.get(p)); // Check if this tells you null, or whatever args[0] is
     
  9. Okay so I did that and it returns the right value. But when I do the thing with the InventoryClickEvent it returns null =/
     
  10. Choco

    Moderator

    Actually, I just realized. @megamichiel left a fantastic point.
    Let's see your onEnable() method
     
  11. Okay...

    Code (Java):

    public void onEnable() {
            getCommand("se").setExecutor(new Listeners());
            getServer().getPluginManager().registerEvents(new Listeners(), this);
        }
     
     
  12. Choco

    Moderator

    Der it is boys :p You're creating two instances of it, once for your command, and one for your listener. Remember, this language is object oriented. For every instance you create, every field, method, and everything contained in that class that is not static will also have a new instance; including all its values. Here's your two options

    1. Create a single instance of Listeners and pass that in to your registries
    Code (Java):
    Listeners listeners = new Listeners();
    this.getCommand("se").setExecutor(listeners);
    Bukkit.getPluginManager().registerEvents(listeners, this);
    2. Make your map static. Though I suggest the first option, this is valid as well
     
  13. Thanks so much :D it's working now. Java is so weird sometimes :confused:
     
  14. It's not weird... That's how object oriented programming languages work.
     
  15. But its weird for me because i used this in many of my Plugins and it worked like a charm =D