Pagination - DevNatan/inventory-framework GitHub Wiki
IF pagination allows you to display a large amount of data in an inventory by separating it into pages.
Pagination is a state value, that is, you have a paging value for each host, a host can be anything that implements StateHost
like for example: a context. Learn more about State Management.
final class MyAbsolutelyInsanePaginatedView extends View {
private final PaginationState paginationState = paginationState(sourceProvider, itemFactory);
}
To create a pagination state you have two essential parameters:
-
sourceProvider
will be used to define the pagination data, e.g.: a list of things. -
itemFactory
will be used to create the items that will be displayed in the view for each paginated element, e.g.: a head of a player.
Composition
In the example below, our data to be paginated is a list of player names that we provide in the sourceProvider
parameter, and for each name we will display a head provided by the itemFactory
parameter.

private final PaginationState paginationState = paginationState(
Arrays.asList("Notch", "DevNatan", "Annie are you ok?"),
(item, $) -> item.withItem(new ItemStack(PLAYER_HEAD))
);
The second parameter, itemFactory
is a BiConsumer<T, V>
being T
what you will use to define your item, it is the same type used to create the items in the slot
, layoutSlot
, etc., and V
is the element being paginated, in our case a String
that's the player name.

private final PaginationState paginationState = paginationState(
Arrays.asList("Notch", "DevNatan", "Annie are you ok?"),
(item, playerName) -> item.withItem(createHead(playerName))
);
private ItemStack createHead(String name) { ... }
TIP: Create a function for creating items that will be paginated to improve readability.
Working with layouts
IF adapts the pagination automatically if there is a defined layout.
Read about how layouts interact with other components.
Look how this code similar to the previous examples but with more items behaves with and without layout.
private final PaginationState paginationState = paginationState(
Arrays.asList("Notch", "DevNatan", "Steve", "Github", "SpiderMan"),
(item, playerName) -> item.withItem(createHead(playerName))
);
No layout | With layout |
---|---|
![]() |
![]() |
Pagination
Dive into Like other states, PaginationState exposes a specific type of value called Pagination
, which is where the paging data of a context is stored.
final Pagination pagination = paginationState.get(context);
It contains several functions such as the number and index of the current page, next and previous pages, pagination data, navigation, among others. Dive into this class to discover the possibilities of what to do with pagination for a context.
Navigation
Browsing is no secret and there are some very explicitly named functions for it.
-
back()
Return to previous page if available. -
advance()
Advances to the next page if any. -
switchTo(n)
Jumps to a specific page index.
Replicating version 2 behavior
In version 2 and earlier there were specific functions to create navigation for pagination like <
and >
in the layout and other predefined things, that doesn't exist anymore.
If you want to replicate the behavior of previous versions you can use layoutSlot
.
<
will be the "navigate backwards" item and >
the "navigate forward" one
final class OctopusView extends View {
private final PaginationState paginationState = paginationState(...);
@Override
public void onInit(ViewConfigBuilder config) {
config.size(3).layout(
" OOOOOOO ",
" OOOOOOO ",
" < > "
);
}
@Override
public void onFirstRender(RenderContext render) {
final Pagination pagination = paginationState.get(render);
render.layoutSlot('<').onClick(pagination::back);
render.layoutSlot('>').onClick(pagination::advance);
}
}
Dynamic Source Provider
In the Composition topic I showed you a pagination with a list of names, a static list of player names but we know that in the real world we have several types of data besides static like dynamic. Inventory Framework allows you to use dynamic data, that is, the data is not defined statically but taken from a continuous source.
Straight to the point, to create dynamic paging just provide a data factory instead of the data directly, that is:
instead of passing a List<...>
, provide Supplier<List<...>>
, Factory<List<...>>
**
Let's see a real world example of dynamic pagination data
This is a view that displays the list of players online on the server.
Obviously players join and leave the server constantly so we couldn't use static data.
Pay close attention to the minimal difference between static and dynamic pagination data.
Static
This data will be the same data that will be used throughout the life cycle of that state, if players leave and enter the server nothing will change, as it is the data provided from a moment in time, that is, it will be the same data throughout life.
private final PaginationState paginationState = paginationState(
Bukkit.getOnlinePlayers(),
(item, value) ->
);
Dynamic
private final PaginationState paginationState = paginationState(
() -> Bukkit.getOnlinePlayers(),
(item, value) ->
);
Handling Page Switch
TBD
Next Topics
Learn how to simplify, shorten and improve interview navigation using the History feature.