The Menu Template
The Menu Template
A Menu<C> is the blueprint of a screen. It is not the live inventory itself.
When you call lotus.openMenu(...), Lotus resolves that template for one player and creates a
MenuView<C, M>.
What C Means
C is the title type:
- Paper uses
Component - Spigot uses
String
That is why most plugin authors implement one of these:
PaperMenuon PaperMenu<String>on Spigot
The Three Required Methods
Every menu answers the same three questions:
- What is the title?
- How big is the inventory?
- What content should be rendered?
public final class ProfileMenu implements PaperMenu {
@Override
public Component title(MenuView<Component, ?> view) {
return Component.text(view.viewer().getName() + "'s Profile");
}
@Override
public Capacity capacity(MenuView<Component, ?> view) {
return Capacity.ofRows(3);
}
@Override
public Content content(MenuView<Component, ?> view) {
return Content.builder(view.capacity())
.set(1, 4, Button.of(new ItemStack(Material.PLAYER_HEAD)))
.build();
}
}
}</CodeTabItem> <CodeTabItem value="spigot" label="Spigot 1.8.8" language="java">{
public final class ProfileMenu implements Menu
@Override
public String title(MenuView<String, ?> view) {
return ChatColor.GOLD + view.viewer().getName() + "'s Profile";
}
@Override
public Capacity capacity(MenuView<String, ?> view) {
return Capacity.ofRows(3);
}
@Override
public Content content(MenuView<String, ?> view) {
return Content.builder(view.capacity())
.set(1, 4, Button.of(new ItemStack(Material.SKULL_ITEM)))
.build();
}
} `}
Treat title(...), capacity(...), and content(...) as pure functions of the current view.
If data comes from elsewhere, read it from the view's DataRegistry or from your own service layer.
Optional Methods You Will Actually Use
| Method | Default | Why override it |
|---|---|---|
name() |
class simple name | Open menus by string, such as commands or config |
type() |
InventoryType.CHEST |
Use HOPPER, DISPENSER, WORKBENCH, and so on |
name()
@Override
public String name() {
return "profile";
}
type()
@Override
public InventoryType type() {
return InventoryType.HOPPER;
}
Make sure type() and capacity() agree with each other. If you return InventoryType.HOPPER,
use a hopper-sized capacity such as Capacity.of(InventoryType.HOPPER).
For chest menus with 1-6 rows, keep type() as CHEST and use Capacity.ofRows(...).
Opening A Menu
lotus.openMenu(player, new ProfileMenu());
You can also seed the new view with data:
DataRegistry seed = DataRegistry.empty()
.put(Keys.TARGET, target.getUniqueId());
lotus.openMenu(player, new ProfileMenu(), seed);
And if the menu was registered earlier:
lotus.openMenu(player, "profile");
Good Beginner Habit
Keep the menu class focused on presentation. Let your plugin services fetch or mutate the real data, and let the menu turn that data into buttons.
Next: The Menu View, the live object you receive everywhere else.