0

For my plugin I want to get the users input from a custom anvil UI. When a player enters a command, it opens a custom anvil UI where they can enter a string by renaming a item. When they press the item in the output slot I want to get that name so I can process the entered string in my code.

I have tried to do this with the spigot-API, but when I click on the item in the output slot the event is triggered but the whole anvil inventory is reset before I can get the name of the clicked item.

code

public final class Test extends JavaPlugin implements Listener
{
   @Override
    public void onEnable()
    {
        this.getServer().getPluginManager().registerEvents(this, this);
        getCommand("openGui").setExecutor(new Command(this));
    }
    
    @EventHandler 
    public void OnInventoryClick(InventoryClickEvent e) 
    {     
        if(e.getInventory().getHolder() instanceof MenuHolder)     
        {        
            //gets input from user from the display name of the clicked item
            String input = e.getCurrentItem().getItemMeta().getDisplayName().toString(); 
            e.getView().getPlayer().sendMessage("Users input: " + input);
    
            //cancels and closes the custom anvil UI
            e.setCancelled(true); 
            e.getView().getPlayer().closeInventory();
        } 
    }  
}

public class Command implements CommandExecutor
{
    @Override
    public boolean onCommand(CommandSender sender, Command command, String s, String[] args)
    {
        if(sender instanceof Player)
        {
            Player player = (Player)sender;

            //created a new Anvil Menu
            Inventory inv = Bukkit.createInventory(new MenuHolder(), InventoryType.ANVIL, "Custom menu");
        
            //adds a custom item with no displayName to the input slot of the new anvil menu
            ItemStack paper = new ItemStack(Material.PAPER);
            ItemMeta paperMeta = paper.getItemMeta();
            paperMeta.setDisplayName("");     
            paper.setItemMeta(paperMeta);          
            inv.setItem(0, paper);       
           
            player.openInventory(inv); 
        }
    }
}


//InventoryHolder class to easily identify custom Inventories
public class MenuHolder implements InventoryHolder
{
    public Inventory getInventory()
    {
        return  null;
    }
}

test-1

    @EventHandler
    public void onInventoryClick(InventoryClickEvent e)
    {
        if(e.getInventory().getHolder() instanceof MenuHolder)
        {

            //Test 1
            if(e.getInventory().getHolder() instanceof MenuHolder)
            {
                if(e.getCurrentItem() != null)
                {
                    ItemMeta input = e.getCurrentItem().getItemMeta();
                    if(input != null)
                    {
                        e.getView().getPlayer().sendMessage("Users input1: " + input.getDisplayName());
                    }
                    else
                    {
                        e.getView().getPlayer().sendMessage("CurrantItem ItemStack does not have a ItemMeta");
                    }
                }
                else
                {
                    e.getView().getPlayer().sendMessage("CurrentItem does not have a item");
                }

                //-----------------------------------------------

                //test 2
                if(e.getView().getCursor() != null)
                {
                    ItemMeta input2 = e.getView().getCursor().getItemMeta();
                    if(input2 != null)
                    {
                        e.getView().getPlayer().sendMessage("Users input: " + input2.getDisplayName());
                    }
                    else
                    {
                        e.getView().getPlayer().sendMessage("Curser ItemStack does not have a ItemMeta");
                    }
                }
                else
                {
                    e.getView().getPlayer().sendMessage("Curser does not have a item");
                }
            }
        }
    }

    when pressing the inputslot(slot 0):
    test1 = Users input: (The default set string)
    test2 = Curser ItemStack does not have a ItemMeta

    when pressing the outputslot(slot 2):
    test1 = CurrentItem does not have a item
    test2 = Curser ItemStack does not have a ItemMeta

test-2

public class MenuHolder implements InventoryHolder
{
    public MenuTypes menuType;
    private final Player player;

    public MenuHolder (MenuTypes menuType, Player player)
    {
        this.menuType = menuType;
        this.player = player;
    }

    public Player getPlayer() {
        return player;
    }

    public Inventory getInventory()
    {
        return  null;
    }
}

    @EventHandler
    public void onPrepareAnvilEvent(PrepareAnvilEvent e) {
        AnvilInventory inv = e.getInventory();

        if(e.getResult() == null)
        {
            e.getView().getPlayer().sendMessage("result was null");
            return;
        }

        if(!e.getResult().hasItemMeta())
        {
            e.getView().getPlayer().sendMessage("result does not have a item meta");
            return;
        }

        e.getView().getPlayer().sendMessage("Wrote: " + e.getResult().getItemMeta().getDisplayName());
    }

3
  • I don't know much about Spigot, but I did find the docs mention not to call HumanEntity.closeInventory() from within a clickEvent. Probably not the cause of the problem though.
    – Kaia
    Commented Aug 21 at 19:21
  • e.getCursor() would get the item that's currently in the cursor. If you call that, does it hold the data of the clicked item, or is it also blank?
    – Kaia
    Commented Aug 21 at 19:22
  • I have tried your approach and I added the test code and conclusion in the question.
    – Entropire
    Commented Aug 21 at 20:13

1 Answer 1

0

You can do firstly add player to holder, then register listener to event, like this:

//InventoryHolder class to easily identify custom Inventories
public class MenuHolder implements InventoryHolder {
    
    private final Player player;

    public MenuHolder(Player player) {
         this.player = player;
    }

    public Player getPlayer() {
        return player;
    }

    public Inventory getInventory() {
        return null;
    }
}

public class AnvilListener implements Listener {
    @EventHandler
    public void onPrepareAnvilEvent(PrepareAnvilEvent e) {
        AnvilInventory inv = e.getInventory();
        if(inv.getHolder() instanceof MenuHolder holder) {
             Player player = holder.getPlayer();
             player.sendMessage("Wrote: " + (e.getResult() != null && e.getResult().hasItemMeta() ? e.getResult().getItemMeta().getDisplayName() : ""));
        }
    }
}

And for the command:

public class Command implements CommandExecutor {
    @Override
    public boolean onCommand(CommandSender sender, Command command, String s, String[] args) {
        if(sender instanceof Player player) {
            //created a new Anvil Menu
            Inventory inv = Bukkit.createInventory(new MenuHolder(player), InventoryType.ANVIL, "Custom menu");
        
            //adds a custom item with no displayName to the input slot of the new anvil menu
            ItemStack paper = new ItemStack(Material.PAPER);
            ItemMeta paperMeta = paper.getItemMeta();
            paperMeta.setDisplayName("");     
            paper.setItemMeta(paperMeta);          
            inv.setItem(0, paper);       
           
            player.openInventory(inv); 
        }
    }
}

Don't forget to register the listener with Bukkit.getPluginManager().registerEvents(new AnvilListener(), this);.

2
  • this approach only work when i removed the if statement that checks for the item holder. and i used a normal anvil. when using the custom anvil the event does not seem the get called.
    – Entropire
    Commented Aug 21 at 20:29
  • i have put the code that i have change in the question under test-2
    – Entropire
    Commented Aug 21 at 20:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.