Icon Menu

Discussion in 'Resources' started by nisovin, Oct 30, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    HeavyMine13

    timtower Ik that lol, i meant how to set that on an option? Like when i choose a dirt, it will run /warp test
     
  2. Offline

    Flybelette

    Hi !
    I just tryed IconMenu and find it very usefull, but I got a problem, I got two class, the fisrt one just open an Inventory :
    Code:java
    1. IconMenu menu = new IconMenu(ChatColor.GRAY+"Stats de : "+ChatColor.RED+player.getName(), 9, new IconMenu.OptionClickEventHandler() {
    2.  
    3. @Override
    4. public void onOptionClick(IconMenu.OptionClickEvent event) {
    5.  
    6.  
    7. if(event.getPosition() == 6){
    8.  
    9. PlayersEmerald pe = new PlayersEmerald(plugin);
    10. pe.OpenMenu(player);
    11.  
    12. }
    13.  
    14.  
    15.  
    16.  
    17.  
    18. }
    19. }, plugin)
    20. .setOption(2, new ItemStack(Material.IRON_SWORD, 1), ChatColor.GRAY+" Morts"+ChatColor.WHITE+"/"+ChatColor.RED+"Kills", item)
    21. .setOption(4, new ItemStack(Material.CAKE, 1), ChatColor.AQUA+"Achievements", item2)
    22. .setOption(6, new ItemStack(Material.EMERALD, 1), ChatColor.GRAY+" Emeraudes", item3);
    23.  

    And the second, that contain the OpenMenu(Player) Method open a non-IconMenu inventory.
    The problem is : When the player click on the 6th item, it just close the inventory, anyone got a solution ?
    Sorry if it was already asked but I didn't find nothing :/
     
  3. Offline

    HeroWorkbrine

    This looks amazing!
    I'm currently making a plugin where you can make custom minigames: Minigame Builder.
    I'm think I'm going to use this menu to select options!

    Flybelette
    Maybe the sixth item is on position 5 because the first item is on position 0?
     
  4. Offline

    Flybelette

    I already resolved the problem, but thanks ;D
     
  5. Offline

    vemacs

    Here's the modified IconMenu we use that fixes some bugs due to dragging and dropping, and allows menus to be specific to a single player:

    Code:
    import org.bukkit.Bukkit;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.EventPriority;
    import org.bukkit.event.HandlerList;
    import org.bukkit.event.Listener;
    import org.bukkit.event.inventory.ClickType;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.Plugin;
     
    import java.util.Arrays;
     
    public class IconMenu implements Listener {
     
        private String name;
        private int size;
        private OptionClickEventHandler handler;
        private Plugin plugin;
        private Player player;
     
        private String[] optionNames;
        private ItemStack[] optionIcons;
     
        public IconMenu(String name, int size, OptionClickEventHandler handler, Plugin plugin) {
            this.name = name;
            this.size = size;
            this.handler = handler;
            this.plugin = plugin;
            this.optionNames = new String[size];
            this.optionIcons = new ItemStack[size];
            plugin.getServer().getPluginManager().registerEvents(this, plugin);
        }
     
        public IconMenu setOption(int position, ItemStack icon, String name, String... info) {
            optionNames[position] = name;
            optionIcons[position] = setItemNameAndLore(icon, name, info);
            return this;
        }
     
        public void setSpecificTo(Player player) {
            this.player = player;
        }
     
        public boolean isSpecific() {
            return player != null;
        }
     
        public void open(Player player) {
            Inventory inventory = Bukkit.createInventory(player, size, name);
            for (int i = 0; i < optionIcons.length; i++) {
                if (optionIcons[i] != null) {
                    inventory.setItem(i, optionIcons[i]);
                }
            }
            player.openInventory(inventory);
        }
     
        public void destroy() {
            HandlerList.unregisterAll(this);
            handler = null;
            plugin = null;
            optionNames = null;
            optionIcons = null;
        }
     
        @EventHandler(priority = EventPriority.HIGHEST)
        void onInventoryClick(InventoryClickEvent event) {
            if (event.getInventory().getTitle().equals(name) && (player == null || event.getWhoClicked() == player)) {
                event.setCancelled(true);
                if (event.getClick() != ClickType.LEFT)
                    return;
                int slot = event.getRawSlot();
                if (slot >= 0 && slot < size && optionNames[slot] != null) {
                    Plugin plugin = this.plugin;
                    OptionClickEvent e = new OptionClickEvent((Player) event.getWhoClicked(), slot, optionNames[slot], optionIcons[slot]);
                    handler.onOptionClick(e);
                    ((Player) event.getWhoClicked()).updateInventory();
                    if (e.willClose()) {
                        final Player p = (Player) event.getWhoClicked();
                        Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
                            public void run() {
                                p.closeInventory();
                            }
                        });
                    }
                    if (e.willDestroy()) {
                        destroy();
                    }
                }
            }
        }
     
        public interface OptionClickEventHandler {
            public void onOptionClick(OptionClickEvent event);
        }
     
        public class OptionClickEvent {
            private Player player;
            private int position;
            private String name;
            private boolean close;
            private boolean destroy;
            private ItemStack item;
     
            public OptionClickEvent(Player player, int position, String name, ItemStack item) {
                this.player = player;
                this.position = position;
                this.name = name;
                this.close = true;
                this.destroy = false;
                this.item = item;
            }
     
            public Player getPlayer() {
                return player;
            }
     
            public int getPosition() {
                return position;
            }
     
            public String getName() {
                return name;
            }
     
            public boolean willClose() {
                return close;
            }
     
            public boolean willDestroy() {
                return destroy;
            }
     
            public void setWillClose(boolean close) {
                this.close = close;
            }
     
            public void setWillDestroy(boolean destroy) {
                this.destroy = destroy;
            }
     
            public ItemStack getItem() {
                return item;
            }
        }
     
        private ItemStack setItemNameAndLore(ItemStack item, String name, String[] lore) {
            ItemMeta im = item.getItemMeta();
            im.setDisplayName(name);
            im.setLore(Arrays.asList(lore));
            item.setItemMeta(im);
            return item;
        }
     
    }
    Also fixes some other issues I can't remember from the original.
     
    97waterpolo likes this.
  6. Offline

    MordorKing78

    Why dont you work in more classes?
     
  7. Offline

    TGMGamingzz1

    How do i open the menu on a item click event to open up the Menu instead of using the command?

    I got this but dont know if its right or what to do after?
    Code:java
    1. if (e.getAction() == Action.RIGHT_CLICK_AIR) {
     
  8. Offline

    viper_monster

  9. Offline

    TGMGamingzz1

    Nope i cant seem to get that to work? spoljo666
     
  10. Offline

    Langur

    if(e.getAction() != Action.RIGHT_CLICK_AIR) return;
    (CODE HERE)




    this probably wont work just because you aren't clicking air or a block, you are clicking an Item in an inventory.
     
  11. Offline

    viper_monster

    TGMGamingzz1
    Code:java
    1. Player player = event.getPlayer();
    2. IconMenu iconMenu = new IconMenu("§9§lKit selector", 9, new IconMenu.OptionClickEventHandler() {
    3.  
    4. @Override
    5. public void onOptionClick(IconMenu.OptionClickEvent clickEvent) {
    6. clickEvent.setWillClose(true);
    7. }
    8. });
    9.  
    10. iconMenu.setOption(0,
    11. new ItemStack(Material.WOOD_SWORD, 1),
    12. "§aArcher",
    13. "§9Rule the map with your", "§9trusty bow and arrows.");
    14.  
    15. iconMenu.open(player);
     
  12. Offline

    TGMGamingzz1


    I know how to do that but i want the menu to load up after i have right clicked a block or item that was in hand at the time?
     
  13. Offline

    RedmanCometh

    Hey so I really love your IconMenu class however I'm having a fairly annoying issue. I've tried multiple iterations of the class and they don't seem to solve it.

    I've used this class in 3 different plugins and I'm having the same issue with all 3 of them. Initially I thought it was just something I was doing wrong in a loop, but this last test is pretty definitive.
    Code:
               Bukkit.getScheduler().scheduleSyncDelayedTask(FactionMenu.getPlugin(), new Runnable()
               {
                public void run()
                {
                    IconMenu menu2 = new IconMenu("Home Menu", 9, new IconMenu.OptionClickEventHandler()
                    {
                    @Override
                    public void onOptionClick(IconMenu.OptionClickEvent event) 
                    {
                        event.setWillClose(true);
                        String selection = event.getName();
                        TestPlayer.ProcessAction(selection, p);
                    }
                }, TestMenu.getPlugin())
                .setOption(0, new ItemStack(Material.BRICK, 1), "Test", "Test")
                .setOption(1, new ItemStack(Material.SIGN, 1), "Test2", "Test2");
              menu2.open(p);
                }
                    },4);
     
    This is then passed to the TestPlayer.ProcessAction method which is basically:
     
            if(action=="Test")
            {
                p.performCommand("Test");
            }
            if(action.contains("Test2"))
            {
                p.performCommand("Test2);
            }
    
    This will see that the input was "Test" or "Test2" that's actually not a problem at all. What I AM having an issue with is that the event is registered multiple times when a user clicks. So for example one of my plugins warps the user to the arena when they click it and sends them a message. Unfortunately it doesn't just send them one message it sends them somewhere between 1 and 4 (it changes..and the slot doesn't shift the randomnity.) In this example test and test2 are run a bunch of times as well.

    So I've tried almost every craftbukkit/spigot version from 1.7-1.7.5 and that doesn't seem to be the issue. In the last example there is no looping/iteration of items, or anything like that, so it's definitely something in the class. Is using event.getName() part of it? Should I be using the slot int instead?
     
  14. Offline

    WizardCM

    EDIT: FIXED! I feel silly now.

    For those unsure, remember to either .destroy() or setWillDestroy(true) as suggested in the initial post to stop this from happening.

    I'll leave the original post for others to use if they get stuck;

    I'm having a similar issue to @RedmanCometh

    Screenshot:
    [​IMG]
    The message "/friendsdebug" shows ONCE every time I run said command, but each time I click an item, and the UI closes, it runs it for every time it was run before.

    I'm using the code provided by vemacs for the IconMenu class and the example code in the initial post in the structure below.

    Code:java
    1. @Override
    2. public boolean onCommand(final CommandSender sender, Command cmd, String label, String[] args){
    3. if(cmd.getName().equalsIgnoreCase("friendsdebug")) {
    4. IconMenu menu = new IconMenu("My Fancy Menu", 9, new IconMenu.OptionClickEventHandler() {
    5. @Override
    6. public void onOptionClick(IconMenu.OptionClickEvent event) {
    7. event.getPlayer().sendMessage("You have chosen " + event.getName());
    8. event.setWillClose(true);
    9. }
    10. }, this)
    11. .setOption(3, new ItemStack(Material.APPLE, 1), "Food", "The food is delicious")
    12. .setOption(4, new ItemStack(Material.IRON_SWORD, 1), "Weapon", "Weapons are for awesome people")
    13. .setOption(5, new ItemStack(Material.EMERALD, 1), "Money", "Money brings happiness");
    14. menu.open(Bukkit.getPlayer(sender.getName()));
    15. }
    16. }
     
  15. Offline

    Quasindro

    WizardCM
    I don't get it. When I apply menu.destroy() to the event, it just kills the manouvering blocks - so I am able to get myself "custom items" from menu and the messages just don't work. May I ask you for help with it?

    /NVM GOT IT TO WORK
    It's just that i didn't try to use setWillDestroy. Now it works correctly.
     
  16. Offline

    coolguy4744

    Hey guys, I am just wondering how I would make it so that when you right click on bedrock it will display the menu. I've tried a few things although I just keep getting errors. :/
     
  17. Offline

    DevRosemberg

    nisovin How would i go ahead and update the items in the menu? Im coding a server selection system and i wanted to know how to update the page.
     
  18. Offline

    darkness1999

    DevRosemberg nisovin

    I thought about that problem also some time ago, but did not find a question. Thanks for reminding me. I started to think again about this and found a solution:

    Code:java
    1. private HashMap<String, Integer> updater = new HashMap<String, Integer>();
    2. private String titel = "your_title_here";
    3.  
    4. @EventHandler
    5. private void onInventoryOpen(InventoryOpenEvent event) {
    6. if(event.getInventory().getTitle().equals(title)) {
    7. final Inventory inventory = event.getInventory();
    8. HumanEntity player = event.getPlayer();
    9. BukkitTask update = new BukkitRunnable() {
    10. public void run() {
    11. //Do whatever you want
    12. //Example inventory.setItem(slot, itemstack);
    13. }
    14. }.runTaskTimerAsynchronously(DoomsDayZ.plugin, 5*20, 5*20);
    15.  
    16. updater.put(player.getName(), update.getTaskId());
    17. }
    18. }
    19.  
    20. @EventHandler
    21. private void onInventoryClose(InventoryCloseEvent event) {
    22. if(event.getInventory().getTitle().equals(title)) {
    23. HumanEntity player = event.getPlayer();
    24. if(updater.containsKey(player.getName())) {
    25. //Cancel the task because we don't run it all the day
    26. Bukkit.getScheduler().cancelTask(updater.get(player.getName()));
    27. updater.remove(player.getName());
    28. }
    29. }
    30. }
    31.  
     
  19. I went ahead and added some methods to the IconMenu class that vemac edited.
    This edited version adds two more IconMenu.setOption() methods and an IconMenu.setOptions() method.


    Here's the methods that it adds:

    This allows you to define your ItemStack before-hand without having IconMenu redefine it.


    This allows you to use color codes starting with "&" in your names/lores and have IconMenu automagically color them.

    This allows you to set a predefined ItemStack as multiple slots on the GUI screen, such as border items or dividers.
     
  20. Offline

    woutwoot

    Cool, but when I use it, the onOptionClick method gets called twice. (And yes, I use event.setWillClose(true);) I could fix it this way:
    Code:java
    1. if(!once){
    2. event.getPlayer().sendMessage("You clicked " + event.getName());
    3. once = true;
    4. event.setWillClose(true);
    5. }else{
    6. once = false;
    7. event.setWillClose(true);
    8. }

    But I don't think that I'm supposed to do that...
     
  21. woutwoot
    Use event.setWillDestroy(true);
     
  22. Offline

    woutwoot


     
  23. woutwoot
    event.setWillDestroy(); =/= event.setWillClose();
    Closing the event just makes the player exit out of the menu. Destroying the menu allows you to redefine it and not duplicate the same IconMenu instance, resulting in the OptionClickEvent event being fired twice or more. If you define the menu only once and that's it, then you don't need to destroy it. An example of this would be defining it in your onEnable() method and making a static variable for the menu to get its value. If you listen for when something happens, then you define the menu, that results in multiple identical menus being created and therefore their listeners are called multiple times.
     
  24. Offline

    woutwoot

    I only had one static iconMenu, thank you for your help though, but I made my own class now that better suits my needs.
     
  25. Offline

    1Nael1

    can you make it and post a link of it up here so we can just download it ?
     
  26. Offline

    1Nael1

    O
    It doesn't work look:
    [17:34:32 ERROR]: Could not load 'plugins/iconmenu.jar' in folder 'plugins'
    org.bukkit.plugin.InvalidDescriptionException: Invalid plugin.yml
    at org.bukkit.plugin.java.JavaPluginLoader.getPluginDescription(JavaPluginLoader.java:150) ~[craftbukkit.jar:git-Bukkit-1.7.2-R0.3-14-g8f8716c-b3042jnks]
    at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:133) [craftbukkit.jar:git-Bukkit-1.7.2-R0.3-14-g8f8716c-b3042jnks]
    at org.bukkit.craftbukkit.v1_7_R2.CraftServer.loadPlugins(CraftServer.java:350) [craftbukkit.jar:git-Bukkit-1.7.2-R0.3-14-g8f8716c-b3042jnks]
    at org.bukkit.craftbukkit.v1_7_R2.CraftServer.<init>(CraftServer.java:312) [craftbukkit.jar:git-Bukkit-1.7.2-R0.3-14-g8f8716c-b3042jnks]
    at net.minecraft.server.v1_7_R2.PlayerList.<init>(PlayerList.java:63) [craftbukkit.jar:git-Bukkit-1.7.2-R0.3-14-g8f8716c-b3042jnks]
    at net.minecraft.server.v1_7_R2.DedicatedPlayerList.<init>(SourceFile:14) [craftbukkit.jar:git-Bukkit-1.7.2-R0.3-14-g8f8716c-b3042jnks]
    at net.minecraft.server.v1_7_R2.DedicatedServer.init(DedicatedServer.java:126) [craftbukkit.jar:git-Bukkit-1.7.2-R0.3-14-g8f8716c-b3042jnks]
    at net.minecraft.server.v1_7_R2.MinecraftServer.run(MinecraftServer.java:426) [craftbukkit.jar:git-Bukkit-1.7.2-R0.3-14-g8f8716c-b3042jnks]
    at net.minecraft.server.v1_7_R2.ThreadServerApplication.run(SourceFile:618) [craftbukkit.jar:git-Bukkit-1.7.2-R0.3-14-g8f8716c-b3042jnks]
    Caused by: java.io.FileNotFoundException: Jar does not contain plugin.yml
    ... 9 more

    Is there a better 1 that works that i can download?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 29, 2016
  27. Offline

    viper_monster

    1Nael1 "InvalidDescriptionException: Invalid plugin.yml"
     
  28. Offline

    1Nael1

    I know wat a plugin.ym
    D: I've been there and tried it it doesn't work Could you like plz just make the plug.yml for me?

    Its just i don't understand main...

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 29, 2016
Thread Status:
Not open for further replies.

Share This Page