Paged inventories
Every inventory will be a class that extends VitalInventory and is annotated with @VitalInventory.Info, as well as @VitalPagedInventory.Info.
Both annotations are needed here because a paged inventory is essentially a normal inventory.
@VitalPagedInventory.Info(fromSlot = 10, toSlot = 16)
@VitalInventory.Info(type = VitalInventory.Type.GENERIC_9X1, name = "My paged inventory", background = Material.COBBLESTONE)
public class MyPagedInventory extends VitalPagedInventory {
}
You define a background for your paged inventory using the info annotation, by default, the background will be AIR (empty slots).
The @VitalPagedInventory.Info annotation will define all of your paged inventory specific data, like fromSlot and toSlot.
These properties define the "paged area" of your inventory.
Essentially, a paged inventory is a normal inventory, where a specific area may contain content that changes based on the current page you are on.
The example shown above defines an inventory where slot 10 to 16 will change depending on what page you are currently on.
To fill this inventory with items, just like in a normal inventory, use the setItem(Player, int, ItemStack, Function<InventoryClickEvent>) method.
As you can see from the method signature, this method can receive a function that takes in an InventoryClickEvent, which will automatically be called when this item is clicked by a player.
Simply set all items in the onUpdate(Player) lifecycle.
@VitalPagedInventory.Info(fromSlot = 10, toSlot = 16)
@VitalInventory.Info(type = VitalInventory.Type.GENERIC_9X1, name = "My paged inventory", background = Material.COBBLESTONE)
public class MyPagedInventory extends VitalPagedInventory {
@Override
public void onUpdate(Player player) {
setItem(player, 0, new ItemStack(Material.STICK), e -> {
// Do something when this item is clicked.
});
// ...
}
}
To open this inventory for a player, use open(Player).
myPagedInventory.open(myPlayer);
Additionally, you can also pass in a previous inventory, so players can automatically navigate back to a previous inventory by just clicking outside the inventory view (background).
myPagedInventory.open(myPlayer, myPreviousInventory);
Vital will automatically handle all events and route them to your correct inventory and the item that was clicked.
Note that every player that opens an inventory menu will have its very own and unique inventory.
Inventories are never shared across multiple players and will always be different when newly opened.
That's why we want to mostly set our items during theonUpdate(Player)lifecycle instead ofonUpdate().Some special cases are, of course, if you do not need to show translated items or player-specific data.
Set page content
To display items that change depending on what page you are on, you would use the onPageChange(int, Player) lifecycle to set items.
For all other items that will NOT change even if you switch pages, you can keep using the onUpdate(Player) lifecycle.
Note that every player will always have its own unique current page and max page just like they have their own unique inventory view every time they open an inventory.
That's why we have to also pass in the player when we want to change pages usingsetPage(int, Player), etc.
Your paged inventory may look something like this:
@VitalPagedInventory.Info(fromSlot = 10, toSlot = 16)
@VitalInventory.Info(type = VitalInventory.Type.GENERIC_9X1, name = "My paged inventory", background = Material.COBBLESTONE)
public class MyPagedInventory extends VitalPagedInventory {
private final List<String> SOME_DATA_I_GOT_FROM_MY_DATABASE = List.of(
"One",
"Two",
"Three",
"Four",
"Five"
);
@Override
public void onUpdate(Player player) {
// Slot 9 and 17 are the "page changers".
// Here we use the size of SOME_DATA_I_GOT_FROM_MY_DATABASE to set the new page so Vital can automatically calculate and update the max page for our player.
// We can then (if we want) display this max page somewhere. If you don't need it, you can ignore this.
setItem(player, 9, new ItemStack(Material.RED_STAINED_GLASS_PANE), e -> setPage(getPage(player) - 1, player, SOME_DATA_I_GOT_FROM_MY_DATABASE.size()));
setItem(player, 17, new ItemStack(Material.GREEN_STAINED_GLASS_PANE), e -> setPage(getPage(player) + 1, player, SOME_DATA_I_GOT_FROM_MY_DATABASE.size()));
}
@Override
public void onPageChange(int page, Player player) {
// "sliceForPage" automatically gives us a list of elements that matches our current page.
// Vital calculates the number of items that can exist per page from our @VitalPagedInventory.Info annotation (fromSlot, toSlot).
final var pageContent = sliceForPage(player, SOME_DATA_I_GOT_FROM_MY_DATABASE);
// Then we can simply set all slots to the elements we got from "sliceForPage".
final var fromSlot = getInfo(VitalPagedInventory.Info.class).fromSlot();
for (int i = 0; i < pageContent.size(); i++) {
final var content = pageContent.get(i);
final var slot = fromSlot + i;
setItem(player, slot, build a new item with the content name or something, e -> {
// Do something when this item is clicked.
});
}
}
}
The example shown above can be used as a good starting point for your own paged inventory.
Please refer to the Javadoc for more detailed information on certain methods.
Lifecycles
| Lifecycle | Usage |
|---|---|
onOpen(Player) | Perform an action when the given player opens this inventory (set items ONCE, etc.). |
onUpdate() | Perform an action when this inventory is updated for all players (set items that are always the same for all players, no translations, no specific data, etc.). |
onUpdate(Player) | Perform an action when this inventory is updated for the given player (set items for that player, translated data, specific data, etc.). |
onClick(InventoryClickEvent) | Perform an action when a slot is clicked in this inventory. Should only rarely be used since all click events are automatically routed to your item when you use setItem. |
onPageChange(int, Player) | Use this method to set your page-specific content (items that will change depending on what page you are currently on). |
onClose(Player) | Perform an action when this inventory is closed for the given player (play sound, remove stuff, etc.). |