AbyssalLib Help

Custom GuiElements

If the built-in GUI components do not meet your requirements, you can create custom elements by implementing the GuiElement interface. Elements manage their own visual state and handle raw interaction events.

The GuiElement Interface

The GuiElement interface provides three primary methods you need to implement or override.

Method

Information

render(GuiView, int)

Determines the ItemStack to display in the assigned slot. Return null for an empty slot.

onClick(GuiClickContext)

Fires when the element is clicked. Returns an ActionResult (e.g., PASS or CANCEL) to control the underlying Bukkit event.

onDrag(GuiDragContext)

Fires when an item is dragged across the element's slot. Returns an ActionResult.

Implementing a Custom Element

For this example, we will create a CounterElement. This element will display a diamond, increment its stack size on left-click, and decrement it on right-click.

public class CounterElement implements GuiElement { private int count; public CounterElement(int initialCount) { this.count = Math.max(1, Math.min(64, initialCount)); } @Override public @Nullable ItemStack render(GuiView view, int slot) { ItemStack item = new ItemStack(Material.DIAMOND, count); item.setData(DataComponentTypes.ITEM_NAME, Component.text("Current Count: " + count)); return item; } @Override public ActionResult onClick(GuiClickContext ctx) { // Adjust the count based on the click type if (ctx.clickType().isLeftClick()) { count = Math.min(64, count + 1); } else if (ctx.clickType().isRightClick()) { count = Math.max(1, count - 1); } // Prevent the player from picking up the item return ActionResult.CANCEL; } @Override public ActionResult onDrag(GuiDragContext ctx) { // Prevent items from being dragged into this slot return ActionResult.CANCEL; } }

Applying the Custom Element

Once the class is created, you can apply it to your GUI just like any built-in element using builder.set().

public final class TestGUI { public static void open(Player player) { Gui.Builder builder = Gui.builder(MenuType.GENERIC_9X3, Component.text("Custom Element GUI")); // Place our custom CounterElement in the middle slot (index 13) starting at count 1 builder.set(SlotPosition.top(13), new CounterElement(1)); GuiManager.open(player, builder.build()); } }
05 June 2026