About NegiLib
In EasyMenu 7, UI rendering operations have been cleanly separated into an independent rendering engine named NegiLib.
This page explains why NegiLib is used by EasyMenu and details the developer API for integrating with EasyMenu from external plugins.
Why Separate the UI Renderer?
Traditional menu plugins tightly couple YAML configuration parsing with Bukkit inventory manipulation code.
EasyMenu 7 establishes a clear separation of concerns:
EasyMenu 7 = YAML parsing, menu semantics, actions, condition evaluation, session state
NegiLib 1 = UI rendering, session transport, Folia scheduling, server platform abstraction
Key Advantages
- Unified Configuration for Multiple UIs: EasyMenu decides what to display, while NegiLib determines how to draw it on the current server version. The same YAML works seamlessly for both Chest UIs and Native Dialogs.
- High Concurrency & Stability: NegiLib coordinates asynchronous and main-thread operations across Folia's region scheduler, providing thread safety and high performance across Paper, Purpur, and Folia.
- Future Extensibility: Support for new client interfaces can be introduced without changing EasyMenu YAML syntax or breaking existing menus.
Developer API (EasyMenuApi)
If your plugin needs to open EasyMenu menus for players, use EasyMenuApi.
Only the EasyMenuApi interface, EasyMenuProvider and MenuOpenResult in the org.mituba01.easymenu.api package are public. Every other class is internal.
Dependency
This wiki does not point to a Maven repository for org.mituba01:easymenu. Reference a locally built EasyMenu-7.0.2.jar (or similar) as provided.
The EasyMenu-7.0.2.jar installed on the server supplies the classes at runtime, so never shade the API into your plugin. Also add depend: [EasyMenu] (or softdepend) to your own plugin.yml to guarantee load order.
<dependency>
<groupId>org.mituba01</groupId>
<artifactId>easymenu</artifactId>
<version>7.0.2</version>
<scope>provided</scope>
</dependency>
Methods
| Method | Returns | Description |
|---|---|---|
open(Player, String menuId) | CompletionStage<MenuOpenResult> | An asynchronous method that starts opening the menu and completes once the outcome is known. The same conditions as /submenu apply (such as open-when). |
isMenuLoaded(String menuId) | boolean | Whether the menu is currently in the menu definition cache. |
reload() | CompletionStage<Boolean> | Reloads configuration. Completes with false when the candidate was rejected by validation. |
EasyMenuProvider.get() returns an Optional<EasyMenuApi>; it is empty while EasyMenu is disabled.
MenuOpenResult Values
| Value | Meaning |
|---|---|
OPENED | The menu is on screen. |
NOT_FOUND | No definition exists for the menu ID (or initialization failed). |
DENIED | The menu exists but its open-when condition rejected this player. |
PRESENTATION_UNAVAILABLE | No renderer could satisfy the requested presentation (such as native-required). |
RENDER_FAILED | The selected renderer failed while opening. |
SUPERSEDED | A newer request or a reload replaced this one, so it was not opened. |
isSuccess() returns true only for OPENED. For DENIED and PRESENTATION_UNAVAILABLE, EasyMenu itself sends the player a message explaining why.
Java Usage Example
import org.bukkit.entity.Player;
import org.mituba01.easymenu.api.EasyMenuProvider;
import org.mituba01.easymenu.api.MenuOpenResult;
public void openShopMenu(Player player) {
EasyMenuProvider.get().ifPresent(api ->
api.open(player, "shop").thenAccept(result -> {
if (!result.isSuccess()) {
getLogger().info("shop was not opened: " + result);
}
})
);
}
open is asynchronous, so the thenAccept callback is not guaranteed to run on the player's thread (the region thread on Folia). Hand any Bukkit API calls to the appropriate scheduler in your own plugin.
isMenuLoaded meansisMenuLoaded does not tell you whether a player currently has the menu open. It only reports whether the menu definition is in the cache.
The cache expires entries after cache.submenu-expiry-seconds, and when precache-submenus is false entries appear only once used. A false result does not mean the menu does not exist, and open loads the definition when needed.
Do not use it to check existence; rely on the result of open (such as NOT_FOUND).
EasyMenuApi with open, isMenuLoaded and reload is the interface EasyMenu 7.0.2 exposes for other plugins.
This wiki does not guarantee compatibility across future versions. Verify behavior against the EasyMenu version you target.