I have to make a GUI where you will put items that will be saved to a config by clicking on a Confirm button in the gui, but for some reasons when i try to get the gui items all the items are null.
private void saveItems(Player player) { for (ItemStack item : inv.getContents()) { if (item != null) { // Save item } } }
This still doesn't explain what's wrong with the saving. Are you serializing the inventory then saving it to a file? How are you doing it. Post the whole code.
the problem is not with the saving system, it works fine, the only thing is that when i use the method i sent you, all the items get from gui are null and idk why
We are going to need to see some more code: How are you getting the inventory? If it is a player inventory, can we see a picture of it? If you created it, did you fill it? Where is this method being called? You will probably want to check for that confirm "button"
You prolly need to loop thru the slots when saving so that you can put items back in the same slot. Oh and save the slots when you save the items I usually use the slot # as the index for a map
this is the method that i used: Code (Java): private void saveItems(Player player) { for (int row = 1; row <= 4; row++) { for (int column = 1; column <= 7; column++) { int slot = 9 * row + column; if (inv.getItem(slot) != null && !Objects.requireNonNull(inv.getItem(slot)).getType().equals(Material.AIR)) { ItemStack item = inv.getItem(slot); if (item != null) { XItemStack.saveItemStack(item, ChatListener.skullData.get(player), column + row); } } } } } note that the items i want to save are sorrounded by glasses
you dont need Objects.requireNonNull(inv.getItem(slot)) because you just did a check for null if (item != null) { another redundant null check XItemStack.saveItemStack(item, ChatListener.skullData.get(player), column + row); column 3 row 2 = 5 column 2 row 3 = 5 maybe use slot instead?
I have been working on a plugin with a mobile Inventory and used these 2 functions. May not be the most elegant way but you can try saving the Hashmap data in your config. Code (Text): HashMap<Player, ItemStack[]> savedInventory = new HashMap<Player, ItemStack[]>(); /** * Saves the inventory inv of p in the HashMap savedInventory */ public void saveInv(Player p, Inventory inv) { ItemStack[] invtosave = new ItemStack[inv.getSize()]; for (int i = 0; i < inv.getSize(); i++) { invtosave[i] = inv.getItem(i); savedInventory.put(p, invtosave); } } /** * Loads the inventory of p from HashMap */ public void loadInv(Player p, Inventory inv) { ItemStack[] empty = new ItemStack[inv.getSize()]; //Checks for HM entry if (savedInventory.get(p) == null) { for (int i = 0; i < inv.getSize(); i++) { empty[i] = null; } inv.setContents(empty); } else { for (int i = 0; i < inv.getSize(); i++) { inv.setContents(savedInventory.get(p)); } } }
it's better to use UUID instead of Player, as a key in hashmaps, 1. less memory usage, u can not compare 2 players object, (only inside properties as UUID). in the save method u can just clone the inv's contents. for your save method did not could understand why you using void and not opening the inventory, so I just return it, and changing it's contents if there is already saved one. it will not save item's order tho.
1. No 2. You can Even thou your point is valid, the reasoning is not. Please stop spreading wrong information
It's code from a project a few months ago which i abandoned. This was mostly written in theory without proper testing and focus on efficiency. Even though i can't think of a reason why uuid would use up more memory (maybe you could explain that), thank you for pointing out those improvements. Definitely more elegant that way
The whole more memory thing is fake news (really) but you should use the uuid, storing the player object in a hash map requires you to make extra code to get it out of there if they log off or loose connection. player object in a map causes a hard reference, any object with a hard reference will not get cleaned up by garbage collection. So player logs out its in a map so player doesnt get removed and wont because they arent actually on to meet any of your action requirements so now you have memory that cant be freed up, thats called a memory leak. Its just less code to use the uuid and safer.
Code (Java): private void saveItems(Player player) { for (int i = 0; i <= inv.getSize() - 1; i++) { ItemStack item = inv.getItem(i); if (item != null) { if (!item.getItemMeta().getDisplayName().equals("§3Grind§bSkulls") && !item.getItemMeta().getDisplayName().equals("§aDone")) { XItemStack.saveItemStack(item, ChatListener.skullData.get(player), i); } } } } i tried this but its still not working
https://hub.spigotmc.org/javadocs/spigot/org/bukkit/inventory/ItemStack.html#hasItemMeta-- if(item != null && item.hasItemMeta()) // check the item has meta before you blindly try to get info from meta that could be null for (int i = 0; i <= inv.getSize() - 1; i++) should be for (int i = 0; i < inv.getSize(); i++) I never use the special color character, instead use https://hub.spigotmc.org/javadocs/s...ateAlternateColorCodes-char-java.lang.String- It could be the color thing but I am unsure. It gave me problems years ago and I stopped using it. you could alos use https://hub.spigotmc.org/javadocs/spigot/org/bukkit/ChatColor.html#stripColor-java.lang.String- to strip the colors out of the string before you check
i had to add inv.getSize() - 1 otherwise it have get me an ArrayOutOfBounds exception. And i don't think that the problem is with colors because when i click on done button i don't get any error in console
the <= let it go out of bounds just < keeps it in bounds in this instance if you are getting null errors, you need to check that the item has meta and that the it has the key you want before you try to use .equals
Code (Java): private void saveItems(Player player) { for (int i = 0; i < inv.getSize(); i++) { ItemStack item = inv.getItem(i); if (item != null && item.hasItemMeta()) { if (!item.getItemMeta().getDisplayName().equals("§3Grind§bSkulls") && !item.getItemMeta().getDisplayName().equals("§aDone")) { XItemStack.saveItemStack(item, ChatListener.skullData.get(player), i); } } } } i tried this but the problem is that like the plugin won't recognise the item that i add to the gui in game and when i click on done button nothing happens and any of the items in the gui aren't saved