Coding Menus - SirCodalot/MenuLib GitHub Wiki
To make a menu, you first need a MenuData that holds information about the menu you're making.
// The first parameter is the title and the second one is the number of rows.
MenuData data = new MenuData(ChatColor.translateAlternateColorCodes('&', "&8&lMy Menu"), 4);
The next step is making a canvas. Canvases are menu components that can hold other menu components, including other canvases. Every menu needs a main canvas. We can make one by doing so:
Canvas main = new Canvas();
data.setCanvas(main);
Now that we have a canvas we can fill it with things. Let's add a help button that closes the inventory and shows players a help message when pressed.
// Making a normal ItemStack and giving it a fancy name and a glow effect
ItemStack item = new ItemStack(Material.BOOK);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColor.BLUE + "Information");
meta.addEnchant(Enchantment.DURABILITY, 1, true);
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
item.setItemMeta(meta);
// Making the Button
StaticItem menuItem = new StaticItem(item);
Button button = new Button(menuItem);
// Setting the action to "exit" makes it close the inventory when clicked. We will cover actions later.
button.setAction("exit");
// The Sudo field is a list of commands that players execute when they click the button. Making them
// execute the help command will show them the help messages
button.setSudo(Collections.singletonList("help"));
// Placing the button inside our main canvas. You can make a new slot by entering either the slot index or x and y values.
main.put(new Slot(4, 1), button);
Let's add a footer to the menu. To keep everything organized and categorized, let's make a new canvas for it.
Canvas footer = new Canvas();
main.put(new Slot(0, 3), footer);
To make things more interesting, let's use animated items in the footer. To make an animated item, you need to make a list of items that'll act as frames.
ItemStack frame1 = new ItemStack(Material.PINK_STAINED_GLASS_PANE);
ItemStack frame2 = new ItemStack(Material.MAGENTA_STAINED_GLASS_PANE);
ItemStack frame3 = new ItemStack(Material.PURPLE_STAINED_GLASS_PANE);
List<ItemStack> frames = Arrays.asList(frame1, frame2, frame3, frame2.clone());
// The first parameter is the frames and the second one is the tick-gap between every frame
AnimatedItem footerBackground = new AnimatedItem(frames, 3);
for (int i = 0; i < 9; i++) {
if (i != 4) // You'll see why I'm skipping this slot soon
footer.put(new Slot(i), new Button(footerBackground.clone()));
}
The last thing I want to add is a close button. It is a simple button that uses the exit action to close the menu.
// Making a normal ItemStack
ItemStack closeItem = new ItemStack(Material.RED_STAINED_GLASS_PANE);
ItemMeta closeMeta = closeItem.getItemMeta();
closeMeta.setDisplayName(ChatColor.RED + "Close Menu");
closeMeta.setLore(Arrays.asList("", ChatColor.GRAY + "Click to Close"));
closeItem.setItemMeta(closeMeta);
// Creating the button
StaticItem closeMenuItem = new StaticItem(closeItem);
Button closeButton = new Button(closeMenuItem);
// Making the button close the inventory
closeButton.setAction("exit");
// Placing it in the middle of our footer
footer.put(new Slot(4), closeButton);
That's it! Our MenuData is ready. You should keep it saved somewhere in your code (maybe even make an enum for MenuDatas :o). When you want to open the menu for a player, run the following code:
new Menu(data).open(player);
Our final code should look like this:
MenuData data = new MenuData(ChatColor.translateAlternateColorCodes('&', "&8&lMy Menu"), 4);
Canvas main = new Canvas();
data.setCanvas(main);
ItemStack item = new ItemStack(Material.BOOK);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColor.BLUE + "Information");
meta.addEnchant(Enchantment.DURABILITY, 1, true);
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
item.setItemMeta(meta);
StaticItem menuItem = new StaticItem(item);
Button button = new Button(menuItem);
button.setAction("exit");
button.setSudo(Collections.singletonList("help"));
main.put(new Slot(4, 1), button);
Canvas footer = new Canvas();
main.put(new Slot(0, 3), footer);
ItemStack frame1 = new ItemStack(Material.PINK_STAINED_GLASS_PANE);
ItemStack frame2 = new ItemStack(Material.MAGENTA_STAINED_GLASS_PANE);
ItemStack frame3 = new ItemStack(Material.PURPLE_STAINED_GLASS_PANE);
List<ItemStack> frames = Arrays.asList(frame1, frame2, frame3, frame2.clone());
AnimatedItem footerBackground = new AnimatedItem(frames, 3);
for (int i = 0; i < 9; i++) {
if (i != 4)
footer.put(new Slot(i), new Button(footerBackground.clone()));
}
ItemStack closeItem = new ItemStack(Material.RED_STAINED_GLASS_PANE);
ItemMeta closeMeta = closeItem.getItemMeta();
closeMeta.setDisplayName(ChatColor.RED + "Close Menu");
closeMeta.setLore(Arrays.asList("", ChatColor.GRAY + "Click to Close"));
closeItem.setItemMeta(closeMeta);
StaticItem closeMenuItem = new StaticItem(closeItem);
Button closeButton = new Button(closeMenuItem);
closeButton.setAction("exit");
footer.put(new Slot(4), closeButton);
And our menu looks like this:
Actions are consumers that buttons execute when clicked. There are a few actions that already come in every menu such as the exit action. For more information, Click Here.
Every menu has a map of strings and actions, so you can add new actions like this:
Menu menu = new Menu(data);
// The first parameter of an action is the player who clicked the button and the second one is the click type
menu.getActions().put("jump", (clicker, clickType) -> clicker.setVelocity(new Vector(0, 2, 0)));
There is an alternative way to make MenuDatas with config files. That way, server owners will have complete control of how the menu looks like and on how it behaves.
To make a MenuData with a file, we first need to get a file and load it into a YamlConfiguration. This is not a part of the library, but I'll write the code here in case you don't remember how to do it:
File file = new File("path.yml");
YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
Now that we loaded a config, we can pass it as a parameter to a MenuData's constructor to turn it into a MenuData.
MenuData data = new MenuData(config);