Util CustomInventoryAPI [InventoryMenu] (Including handy OnClick() function)

Discussion in 'Resources' started by Banjer_HD, Jul 15, 2018.

Thread Status:
Not open for further replies.
  1. Hey there,
    I want to start this thread of by saying that this util is NOT created by me but I came across a post from @Ultimate_n00b (https://bukkit.org/members/ultimate_n00b.90707285/).

    He shared his util back in 2013 and it is really handy but not well know, it also doesn't have its own thread about it so I just wanted to share his code with you.

    Code:java
    1.  
    2. import java.util.ArrayList;
    3. import java.util.Arrays;
    4. import java.util.List;
    5.  
    6. import org.bukkit.Bukkit;
    7. import org.bukkit.Material;
    8. import org.bukkit.entity.Player;
    9. import org.bukkit.event.EventHandler;
    10. import org.bukkit.event.Listener;
    11. import org.bukkit.event.inventory.InventoryClickEvent;
    12. import org.bukkit.event.inventory.InventoryCloseEvent;
    13. import org.bukkit.event.server.PluginDisableEvent;
    14. import org.bukkit.inventory.Inventory;
    15. import org.bukkit.inventory.ItemStack;
    16. import org.bukkit.inventory.meta.ItemMeta;
    17.  
    18. public class IconMenu implements Listener {
    19.  
    20. private String name;
    21. private int size;
    22. private onClick click;
    23. List<String> viewing = new ArrayList<String>();
    24.  
    25. private ItemStack[] items;
    26.  
    27. public IconMenu(String name, int size, onClick click) {
    28. this.name = name;
    29. this.size = size * 9;
    30. items = new ItemStack[this.size];
    31. this.click = click;
    32. Bukkit.getPluginManager().registerEvents(this, Bukkit.getPluginManager().getPlugins()[0]);
    33. }
    34.  
    35. @EventHandler
    36. public void onPluginDisable(PluginDisableEvent event) {
    37. for (Player p : this.getViewers())
    38. close(p);
    39. }
    40.  
    41. public IconMenu open(Player p) {
    42. p.openInventory(getInventory(p));
    43. viewing.add(p.getName());
    44. return this;
    45. }
    46.  
    47. private Inventory getInventory(Player p) {
    48. Inventory inv = Bukkit.createInventory(p, size, name);
    49. for (int i = 0; i < items.length; i++)
    50. if (items[i] != null)
    51. inv.setItem(i, items[i]);
    52. return inv;
    53. }
    54.  
    55. public IconMenu close(Player p) {
    56. if (p.getOpenInventory().getTitle().equals(name))
    57. p.closeInventory();
    58. return this;
    59. }
    60.  
    61. public List<Player> getViewers() {
    62. List<Player> viewers = new ArrayList<Player>();
    63. for (String s : viewing)
    64. viewers.add(Bukkit.getPlayer(s));
    65. return viewers;
    66. }
    67.  
    68. @EventHandler
    69. public void onInventoryClick(InventoryClickEvent event) {
    70. if (viewing.contains(event.getWhoClicked().getName())) {
    71. event.setCancelled(true);
    72. Player p = (Player) event.getWhoClicked();
    73. Row row = getRowFromSlot(event.getSlot());
    74. if (!click.click(p, this, row, event.getSlot() - row.getRow() * 9, event.getCurrentItem()))
    75. close(p);
    76. }
    77. }
    78.  
    79. @EventHandler
    80. public void onInventoryClose(InventoryCloseEvent event) {
    81. if (viewing.contains(event.getPlayer().getName()))
    82. viewing.remove(event.getPlayer().getName());
    83. }
    84.  
    85. public IconMenu addButton(Row row, int position, ItemStack item, String name, String... lore) {
    86. items[row.getRow() * 9 + position] = getItem(item, name, lore);
    87. return this;
    88. }
    89.  
    90. public Row getRowFromSlot(int slot) {
    91. return new Row(slot / 9, items);
    92. }
    93.  
    94. public Row getRow(int row) {
    95. return new Row(row, items);
    96. }
    97.  
    98. public interface onClick {
    99. public abstract boolean click(Player clicker, IconMenu menu, Row row, int slot, ItemStack item);
    100. }
    101.  
    102. public class Row {
    103. private ItemStack[] rowItems = new ItemStack[9];
    104. int row;
    105.  
    106. public Row(int row, ItemStack[] items) {
    107. this.row = row;
    108. int j = 0;
    109. for (int i = (row * 9); i < (row * 9) + 9; i++) {
    110. rowItems[j] = items[i];
    111. j++;
    112. }
    113. }
    114.  
    115. public ItemStack[] getRowItems() {
    116. return rowItems;
    117. }
    118.  
    119. public ItemStack getRowItem(int item) {
    120. return rowItems[item] == null ? new ItemStack(Material.AIR) : rowItems[item];
    121. }
    122.  
    123. public int getRow() {
    124. return row;
    125. }
    126. }
    127.  
    128. private ItemStack getItem(ItemStack item, String name, String... lore) {
    129. ItemMeta im = item.getItemMeta();
    130. im.setDisplayName(name);
    131. im.setLore(Arrays.asList(lore));
    132. item.setItemMeta(im);
    133. return item;
    134. }
    135.  
    136. }
    137. [/i][/i][/i]


    Usage:
    Code:java
    1.  
    2. IconMenu menu = new IconMenu("IconMenu", 2, new onClick() {
    3. @Override
    4. public boolean click(Player p, IconMenu menu, Row row, int slot, ItemStack item) {
    5. if(row.getRow() == 1){
    6. Bukkit.broadcastMessage(row.getRowItem(slot).getType().name());
    7. }
    8. return true;
    9. }
    10. });
    11. menu.addButton(menu.getRow(1), 0, new ItemStack(Material.STONE), "Stone Button ;)");
    12. menu.addButton(menu.getRow(1), 1, new ItemStack(Material.WOOD), "Wood Button ;)");
    13. menu.addButton(menu.getRow(1), 2, new ItemStack(Material.DIAMOND), "Diamond Button ;)");
    14. menu.addButton(menu.getRow(1), 3, new ItemStack(Material.GOLD_BLOCK), "Gold Button ;)");
    15. menu.addButton(menu.getRow(1), 4, new ItemStack(Material.IRON_BLOCK), "Iron Button ;)");
    16. menu.addButton(menu.getRow(1), 5, new ItemStack(Material.OBSIDIAN), "Obby Button ;)");
    17. menu.addButton(menu.getRow(1), 6, new ItemStack(Material.ANVIL), "Anvil Button ;)");
    18. menu.addButton(menu.getRow(1), 7, new ItemStack(Material.STONE_BUTTON), "Button Button ;)");
    19. menu.addButton(menu.getRow(1), 8, new ItemStack(Material.PORTAL), "Portal Button ;)");
    20. menu.open(p.getPlayer());
    21.  


    In this way you don't need to make an extra InventoryClickEvent.
     
  2. Offline

    PhantomUnicorns

    Looks awesome and all. I recommend making it based upon a manager class and an internal static class. This way there's only one listener, and every single IconMenu you make isn't its own listener.

    EDIT: I made some based upon the manager system.
    Required plugin (open)

    Code:
    import java.util.ArrayList;
    import java.util.List;
    import java.util.function.Consumer;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class IconMenuManager implements Listener {
    
        private static IconMenuManager _manager;
    
        public static void init(JavaPlugin plugin) {
            _manager = new IconMenuManager(plugin);
        }
    
        private List<IconMenu> _iconMenus;
    
        private IconMenuManager(JavaPlugin plugin) {
            this._iconMenus = new ArrayList<>();
    
            Bukkit.getPluginManager().registerEvents(this, plugin);
        }
    
        @EventHandler
        public void onInventoryClick(InventoryClickEvent event) {
            for (IconMenu menu : this._iconMenus) {
                if (menu.equals(event.getInventory())) {
                    event.setCancelled(true);
                    menu._ON_CLICK.accept(event);
                    return;
                }
            }
        }
    
        public static class IconMenu {
    
            private final Inventory _INVENTORY;
            private final String _PLAIN_NAME;
            private final Consumer<InventoryClickEvent> _ON_CLICK;
    
            public IconMenu(String name, int rows, Consumer<InventoryClickEvent> onClick) {
                _manager._iconMenus.add(this);
                this._INVENTORY = Bukkit.createInventory(null, rows * 9, ChatColor.translateAlternateColorCodes('&', name));
                this._PLAIN_NAME = ChatColor.stripColor(this._INVENTORY.getName());
                this._ON_CLICK = onClick;
            }
    
            public void setItem(ItemStack item, int slot) {
                this._INVENTORY.setItem(slot, item);
            }
    
            public void setItem(ItemStack item, int... slots) {
                for (int slot : slots) {
                    this._INVENTORY.setItem(slot, item);
                }
            }
       
            public void open(Player player) {
                player.openInventory(this._INVENTORY);
            }
     
            public Inventory getInventory() {
                return this._INVENTORY;
            }
    
            @Override
            public boolean equals(Object other) {
                if (other instanceof Inventory) {
                    return ChatColor.stripColor(((Inventory) other).getName()).equals(this._PLAIN_NAME);
                } else if (other instanceof IconMenu) {
                    return ((IconMenu) other)._PLAIN_NAME.equals(this._PLAIN_NAME);
                } else {
                    return false;
                }
            }
        }
    }
    

    No required plugin (open)

    Code:
    import java.util.ArrayList;
    import java.util.List;
    import java.util.function.Consumer;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    
    public class IconMenuManager implements Listener {
    
        private static IconMenuManager _manager;
    
        private static void init(IconMenu menu) {
            if (_manager == null) {
                _manager = new IconMenuManager();
            }
            _manager._ICON_MENUS.add(menu);
        }
    
        private final List<IconMenu> _ICON_MENUS;
    
        private IconMenuManager() {
            this._ICON_MENUS = new ArrayList<>();
    
            Bukkit.getPluginManager().registerEvents(this, Bukkit.getPluginManager().getPlugins()[0]);
        }
    
        @EventHandler
        public void onInventoryClick(InventoryClickEvent event) {
            for (IconMenu menu : this._ICON_MENUS) {
                if (menu.equals(event.getInventory())) {
                    event.setCancelled(true);
                    menu._ON_CLICK.accept(event);
                    return;
                }
            }
        }
    
        public static class IconMenu {
    
            private final Inventory _INVENTORY;
            private final String _PLAIN_NAME;
            private final Consumer<InventoryClickEvent> _ON_CLICK;
    
            public IconMenu(String name, int rows, Consumer<InventoryClickEvent> onClick) {
                init(this);
                this._INVENTORY = Bukkit.createInventory(null, rows * 9, ChatColor.translateAlternateColorCodes('&', name));
                this._PLAIN_NAME = ChatColor.stripColor(this._INVENTORY.getName());
                this._ON_CLICK = onClick;
            }
    
            public void setItem(ItemStack item, int slot) {
                this._INVENTORY.setItem(slot, item);
            }
    
            public void setItem(ItemStack item, int... slots) {
                for (int slot : slots) {
                    this._INVENTORY.setItem(slot, item);
                }
            }
       
            public void open(Player player) {
                player.openInventory(this._INVENTORY);
            }
    
            public Inventory getInventory() {
                return this._INVENTORY;
            }
    
            @Override
            public boolean equals(Object other) {
                if (other instanceof Inventory) {
                    return ChatColor.stripColor(((Inventory) other).getName()).equals(this._PLAIN_NAME);
                } else if (other instanceof IconMenu) {
                    return ((IconMenu) other)._PLAIN_NAME.equals(this._PLAIN_NAME);
                } else {
                    return false;
                }
            }
        }
    }
    

    Example (open)

    Code:
        public void onEnable() {
            IconMenuManager.init(this);
            IconMenu iconMenu = new IconMenu("&cTest inventory", 2, (event) -> {
                int slot = event.getSlot();
                if (slot == 0 || slot == 1 || slot == 2) {
                    event.getWhoClicked().sendMessage("Clicked log on slot 1, 2, or 3!");
                }
            });
            iconMenu.setItem(new ItemStack(Material.LOG, 1), 0, 1, 2, 5, 7);
            for (Player player : Bukkit.getOnlinePlayers()) {
                iconMenu.open(player);
                // OR: player.openInventory(iconMenu.getInventory());
            }
        }
    

    For the one that you must provide the plugin, all you have to do is ItemMenuManager.init(JavaPlugin) in onEnable and no bugs. For the other one, nothing required but will probably break on reload because it holds it statically.
    Finally, both might give a warning for the .equals usage, I covered that in my override of the equals method in IconMenu.
     
    Last edited: Jul 16, 2018
    Banjer_HD likes this.
  3. Offline

    AwesomeUniverse

    I was actually creating something like this a few days ago.
     
    Banjer_HD likes this.
  4. Thanks for sharing this with us! I'll definitely will be using this!
     
Thread Status:
Not open for further replies.

Share This Page