A Bukkit GUI framework for building inventory-based user interfaces in Minecraft plugins. Part of The SRS Project.
- Abstract base classes for plugin GUIs with built-in lifecycle management
- Paged GUI support with automatic page navigation
- Player selector GUI with select/deselect all, max selection limit, and submit/cancel flow
- Button system with click callbacks and slot blocking
- Built-in i18n support via per-player server-side translation
- Fluent
ItemBuilderfor constructingItemStacks - Automatic event dispatching and cleanup on plugin disable
- Paper and Spigot compatibility
- Java 17+
- Paper API 1.20.1+ (or compatible Spigot fork)
Add the JitPack repository and dependency to your build.gradle:
repositories {
maven { url 'https://jitpack.io/' }
}
dependencies {
implementation 'com.github.TheSRSProject:gui:TAG'
}Replace TAG with a commit hash or release tag.
Extend AbstractPluginGUI and implement drawImmediatelyImpl():
public class MyGUI extends AbstractPluginGUI {
public MyGUI(Plugin plugin, UUID viewer) {
super(plugin, Component.text("My GUI"), viewer);
}
@Override
protected void drawImmediatelyImpl() {
drawFrame();
GUIButtonHelper helper = getButtonHelper();
ItemStack button = new ItemBuilder(Material.DIAMOND)
.setDisplayName("Click me")
.build();
helper.setButton(22, button, (clicker, clickType) -> {
clicker.sendMessage("Clicked!");
return GUIClickResult.CANCEL_CLICK;
});
}
}Then show it to a player:
new MyGUI(plugin, player.getUniqueId()).show();Extend AbstractPagedGUI for content that spans multiple pages:
public class MyPagedGUI extends AbstractPagedGUI {
public MyPagedGUI(Plugin plugin, UUID viewer) {
super(plugin, Component.text("Paged GUI"), viewer);
}
@Override
public OptionalInt getMaxPage() {
return OptionalInt.of(5);
}
@Override
protected void drawImmediatelyImpl(int page) {
drawFrame();
drawButtons(); // draws page navigation buttons
// draw page-specific content here
}
}Extend AbstractPlayersSelectorGUI for selecting online players:
public class MyPlayerSelector extends AbstractPlayersSelectorGUI {
public MyPlayerSelector(Plugin plugin, UUID viewer) {
super(plugin, Component.text("Select Players"), viewer);
}
@Override
protected OptionalInt getMaxSelectablePlayers() {
return OptionalInt.empty(); // no limit
}
@Override
protected boolean onSubmit(Player submitter, Set<UUID> selectedPlayers) {
// handle selection
return true; // return true to close the GUI
}
@Override
protected void afterCancel(Player canceller) {
// handle cancellation
}
}