Folio
A modular, fluent, builder-based
paginated inventory GUI framework for Paper 1.21+.
Pure Adventure API · Java 21 · zero dependencies beyond
paper-api.
Features
- Core — InventoryPage · PagedInventory · InventoryItem · InventorySession · InventoryRegistry
- Click — sealed ClickResult (Allow / Cancel / Close / Refresh / Navigate), per-type handlers (left/right/shift/drop/numberKey), bubbling chain (item → page → inventory), per-item cooldowns, async handlers
- Layout — sealed Layout: LinearLayout · GridLayout · MaskLayout (text-block patterns with B / X / .)
- Pagination — auto + manual, configurable navigation slots, MiniMessage page-indicator
- Animation — AnimatedItem with frames, refreshEvery(Duration), slot-diffing renderer (no flicker), pauses when nobody's watching
- Async — CompletableFuture<List<InventoryItem>> source, animated placeholder, error fallback, TTL cache, soft-cancel-on-close
- Filter / Search — Filter predicates with AND / OR / negate, anvil-GUI live search via SearchPrompt, per-session filter state
- Multi-player — SessionMode.SHARED — one Inventory instance, multiple viewers (co-op GUIs, auctions)
- Form / Input — mark slots as inputSlot(...), click NOT cancelled, leftover items returned on close
- Hotbar keys — hotbarBind(1..9, handler) — page-global number-key shortcuts
- Persistence — .persistent("key") — page index saved in player's PersistentDataContainer, restored on rejoin
- Permissions — PermissionGate on page and item level, auto-hide
- Theme — central InventoryTheme (border material, sounds, MiniMessage indicator template)
[HR][/HR]
Quick start — a 28-slot shop
Code (Java):
List
<InventoryItem
> offers
= catalog.
stream
(
)
.
map
(o
-> InventoryItem.
builder
(
)
.
material
(o.
material
(
)
)
.
name
(
Component.
text
(o.
name
(
), NamedTextColor.
YELLOW
)
)
.
lore
(
Component.
text
(
"Preis: "
+ o.
price
(
)
+
"g", NamedTextColor.
GRAY
)
)
.
cooldown
(Duration.
ofMillis
(
500
)
)
.
clickableIf
(p
-> economy.
balance
(p
)
>= o.
price
(
)
)
.
onLeftClick
(ctx
->
{
economy.
charge
(ctx.
player
(
), o.
price
(
)
)
;
ctx.
player
(
).
getInventory
(
).
addItem
(o.
product
(
)
)
;
return ClickResult.
refresh
(
)
;
}
)
.
build
(
)
)
.
toList
(
)
;
InventoryPage page
= InventoryPage.
builder
(
)
.
title
(
Component.
text
(
"Shop", NamedTextColor.
GOLD
)
)
.
rows
(
6
)
.
layout
(MaskLayout.
of
(
""
"
BBBBBBBBB
BXXXXXXXB
BXXXXXXXB
BXXXXXXXB
BXXXXXXXB
BBBBBBBBB
"
""
)
)
.
navigation
(NavigationButtons.
builder
(
)
.
firstSlot
(
45
).
previousSlot
(
47
).
pageIndicatorSlot
(
49
)
.
nextSlot
(
51
).
lastSlot
(
53
).
build
(
)
)
.
items
(offers
)
.
build
(
)
;
registry.
open
(player, PagedInventory.
paginate
(page
)
)
;
[HR][/HR]
Built-in demo
The plugin ships with
/foliodemo <sub> (alias
/invpagedemo) — every feature live, no setup:
- shop — 200 items · mask layout · pagination · cooldowns
- anim — 4 slots cycling 8 wool colors
- async — simulated DB load with animated placeholder
- filter — toggle filter button · live re-pagination
- shared — co-op: two players, one Inventory
- search — anvil-GUI live search → filtered shop
- persist — leave + rejoin → opens at the same page
- keys — hotbar 1..9 actions while hovering
- form — 3 input slots + emerald-confirm with validation
- exit — clear stored persistence state
[HR][/HR]
Install
- Drop folio-1.0.0.jar into plugins/
- Restart the server
- Run /foliodemo shop in-game
To depend on Folio from your own plugin, add to your
plugin.yml:
Code (Text):
depend: [Folio]
And get the registry:
Code (Java):
InventoryRegistry registry
=
(
(InventoryPagePlugin
) Bukkit.
getPluginManager
(
)
.
getPlugin
(
"Folio"
)
).
registry
(
)
;
[HR][/HR]
Requirements
- Paper 1.21+ (uses MenuType.ANVIL · sealed types · pattern matching)
- Java 21
Design defaults
- Click + drag in top inventory always cancelled — opt-in via ClickResult.allow() (sync only)
- Async cancel = soft-discard (no Future.cancel(true) — interrupting JDBC / HTTP is unsafe; the caller owns the future's lifecycle)
- Refresh interval clamped to ≥ 1 tick (50 ms)
- SHARED mode = shared items and shared cursor (predictable for co-op GUIs)
- Indicator template lives in InventoryTheme (one place to retheme the whole plugin)
License: MIT