Paginated and non-paginated inventories with buttons, items, and more...
Creating a Menu
If you'd like to make a normal non-paginated menu:
final Component title = TextStyle.style("<gray><bold>My Menu");
Menu menu = Menu.menu(title, 54);
// OR:
menu = Menu.menu(title, /* width */ 9, /* height */ 6);
// 54 is an example size, you can do whatever you want.
A paginated menu would be the same but instead of using:
Menu.menu(...)
You would use:
PaginatedMenu.menu(...)
Adding Items to a Menu
Now that you have a menu instance, you can now add items to it freely.
final MenuBase<?> menu = /* ... */;
// If you're using a normal menu:
menu.item(
slot,
ItemBuilder.item(Material.DIAMOND)
);
// If you're using a paginated menu:
menu.item(
PaginatedSlot.paginatedSlot(
slot,
page
),
ItemBuilder.item(Material.DIAMOND)
);
This is not a button, this a item that can be taken and put back.
Adding Buttons to a Menu
Buttons are items that are clickable. You can tell what the button to do after it's clicked on.
final MenuBase<?> menu = /* ... */;
// If you're using a normal menu:
menu.button(
slot, Button.button()
.item(ItemBuilder.item(Material.DIAMOND))
.onClick(event -> {
player.sendRichMessage("<red>You can't get this diamond now!");
event.setCancelled(true);
})
);
// If you're using a paginated menu:
menu.button(
PaginatedSlot.paginatedSlot(
slot,
page
),
Button.button()
.item(ItemBuilder.item(Material.DIAMOND))
.onClick(event -> {
player.sendRichMessage("<red>You can't get this diamond now!");
event.setCancelled(true);
})
);
Inventory Events
If you'd like to add custom implementation for a event listener for when the inventory gets closed or when inventory drag event gets caused you can do the following:
menu.onClose(event -> player.sendRichMessage("<red>How dare you close the menu!"));
menu.onDrag(event -> {
event.setCancelled(true);
player.sendRichMessage("<red>How dare you close the menu!");
});
Opening the Menu
final MenuBase<?> menu = /* ... */;
// To open the first page:
menu.open(player);
// OR
menu.open(player, 1);
// Opening a specific page:
menu.open(player, page);
Borders
If you want to create a border quickly, here's an example:
final MenuBase<?> menu = /* ... */;
menu.border(
Button.button(
ItemBuilder.item(Material.BLACK_STAINED_GLASS_PANE),
event -> event.setCancelled(true)
),
"X X X X X X X X X",
"X . . . . . . . X",
"X . . . . . . . X",
"X . . . . . . . X",
"X . . . . . . . X",
"X X X X X X X X X"
);
Filling
If you want to fill a bunch of slots with the same item, you can use the following example to help you:
final MenuBase<?> menu = /* ... */;
menu.fill(
/* item builder or button */ item,
". . . . . . . . .",
". . . . . . . . .",
". . X X X X X . .",
". . X X X X X . .",
". . . . . . . . .",
". . . . . . . . ."
);
Example
TestMenu.java
package dev.continuum.duels.test;
import dev.manere.utils.item.ItemBuilder;
import dev.manere.utils.menu.Button;
import dev.manere.utils.menu.MenuBase;
import dev.manere.utils.menu.normal.Menu;
import dev.manere.utils.text.color.TextStyle;
import dev.manere.utils.text.font.SmallFont;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class TestMenu {
private final Player player;
private final MenuBase<?> menu;
public TestMenu(final @NotNull Player player) {
this.player = player;
this.menu = Menu.menu(Component.text("Shop"), 9, 3);
}
public void init() {
this.menu.button(11, Button.button()
.item(ItemBuilder.item(Material.END_STONE)
.name(TextStyle.style("<#00ff00>" + SmallFont.convert("end")))
.lore(TextStyle.style("Click to view the end shop"))
)
.onClick(event -> {
event.setCancelled(true);
this.player.closeInventory();
// Open the end menu
})
);
this.menu.button(12, Button.button()
.item(ItemBuilder.item(Material.NETHERRACK)
.name(TextStyle.style("<#00ff00>" + SmallFont.convert("nether")))
.lore(TextStyle.style("Click to view the nether shop"))
)
.onClick(event -> {
event.setCancelled(true);
this.player.closeInventory();
// Open the end menu
})
);
this.menu.button(13, Button.button()
.item(ItemBuilder.item(Material.TOTEM_OF_UNDYING)
.name(TextStyle.style("<#00ff00>" + SmallFont.convert("gear")))
.lore(TextStyle.style("Click to view the gear shop"))
)
.onClick(event -> {
event.setCancelled(true);
this.player.closeInventory();
// Open the end menu
})
);
this.menu.button(14, Button.button()
.item(ItemBuilder.item(Material.COOKED_BEEF)
.name(TextStyle.style("<#00ff00>" + SmallFont.convert("food")))
.lore(TextStyle.style("Click to view the food shop"))
)
.onClick(event -> {
event.setCancelled(true);
this.player.closeInventory();
// Open the end menu
})
);
this.menu.button(15, Button.button()
.item(ItemBuilder.item(Material.AMETHYST_SHARD)
.name(TextStyle.style("<#7f03fc>" + SmallFont.convert("shard shop")))
.lore(TextStyle.style("Click to view the shard shop"))
)
.onClick(event -> {
event.setCancelled(true);
this.player.closeInventory();
// Open the end menu
})
);
}
public void open() {
this.menu.open(player);
}
@NotNull
public Player player() {
return player;
}
@NotNull
public MenuBase<?> menu() {
return menu;
}
}