1.12.2 InventoryClickEvent gets called again when it's not supposed to.

Discussion in 'Spigot Plugin Development' started by CabbageRoll_, Oct 24, 2020.

  1. I have 3 inventory gui's. I am starting off gui 1, when the item gets clicked its supposed to close and go to gui 2. Instead, the click event gets called again , closes inventory again and goes to gui 3.
    What causes this and how can i work around it?
    (one workaround is to place items in a different slot, but what if i need it to be in the same slot?)

    gui 1: https://pastebin.com/48dQU8mn
    gui 2: https://pastebin.com/8iKQhGa6

    I implemented only the stuff needed for the debugging. Don't question the weird choice of blocks inside gui as i first want to make the menu transition properly before going further

    What happens: open gui 1, click item, event closes gui 1 & opens gui 2, event closes gui 2 and opens gui 3
    What i want: open gui 1, click item, event closes gui 1 & opens gui 2
    #1 CabbageRoll_, Oct 24, 2020
    Last edited: Oct 24, 2020
  2. Solution: Just use 1 InventoryClickEvent instead of 1 per GUI.
    Also you don't have to close the inventory. You can just open another one, which will override the other.

    Also instead of working with a HashMap you could just check for the clicked Inventory name:
    Code (Java):
    if(event.getClickedInventory().getName().equalsIgnoreCase("Home")) {/*do*/}
  3. I put the hashmap to prevent players from messing with renamed chests (and don't want to add trailing colors, i thought a hashmap/list of players would be a good way to track it).
    And for the one inventory click event, what if i have about 10 different types of inventories (menus)? Wouldn't the code get too cluttered?
  4. Every InventoryClickEvent listener is called for every inventory click. So your listeners have to make sure they are dealing with the right inventory because they will be called for every click in any inventory.

    in your HomeMenu after you do MultiplayerMenu.openGUI(p); you need to cancel the event. and in your MultiplayerMenu check if the event is cancelled and if so quietly return and do nothing.
  5. It is a really bad idea to just check the inventory title, as you can for example rename chests and their inventory name is changing as well.
  6. If i am actually going to move the listener to separate class how can i utilize a variable that shows the last menu opened? Its kind of like a program window, closing the inventory should minimize it and a command brings it back up where it was.
  7. This is something I just learned (yes old people can learn, eventually...)

    Code (Java):
    public class SellInventory implements InventoryHolder {

        private Inventory inventory = null;

        public SellInventory(Player player) {
            inventory = Main.getInstance().getServer().createInventory(this, 36, "Sell");

        public Inventory getInventory() {
            return inventory;

    And then in my Listener I can do
    Code (Java):
        void onInventoryClick(InventoryClickEvent event) {
            if (event.getInventory().getHolder() instanceof SellInventory) {
    This was the most simple example I could find, to open my inventory for a player I just do
    Code (Text):
    new SellInventory(player);
    Simple, elegant, secure.
    • Agree Agree x 1
    • Winner Winner x 1
  8. In my example, I would make enum listing each type of inventory in my setup then pass it as an arg to the constructor, like new SellInventory(player, LastInventory.HOME);
  9. I have just implemented that portion of code and looks like the listener doesn't get the events.
    Main class:
    getServer().getPluginManager().registerEvents(new Listen(), this);

    Did i miss something?

    OOPSIE I FORGOT TO PUT @EventHandler

    It actually works properly, thanks
    #9 CabbageRoll_, Oct 25, 2020
    Last edited: Oct 25, 2020
  10. Yes sure, was just an example how to prevent the HashMaps. The best way to deal with it would be exactly what @Tarluin wrote.