Skip to content

Create a custom inventory

This example shows how to create a custom inventory and handle click interactions.

Custom inventories allow creating interactive GUIs for players.

→ Deep dive: [[Custom Inventories|Core-API/Inventory-&-UI/Custom-Inventories]] & [[ItemBuilder|Core-API/Items/ItemBuilder]]


Steps

  1. Create a class extending PixelPrivateInventory
  2. Define the inventory layout in setItems()
  3. Handle interactions in onClickInventory(...)
  4. Open the inventory using InventoryHandler

Implementation

package net.mixelpixel.example.bukkit.gui;

import net.kyori.adventure.text.Component;
import net.mixelpixel.core.bukkit.api.inventory.PixelPrivateInventory;
import net.mixelpixel.core.bukkit.api.player.BukkitPixelPlayer;
import net.mixelpixel.core.bukkit.api.util.item.ItemBuilder;
import net.mixelpixel.example.bukkit.ExamplePlugin;
import org.bukkit.Material;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;

public class GigaDiamondInventory extends PixelPrivateInventory<ExamplePlugin> {

    public GigaDiamondInventory(ExamplePlugin plugin, Component title, InventoryType inventoryType, int slots) {
        super(plugin, title, inventoryType, slots);
    }

    @Override
    public void setItems() {
        ItemStack diamond = createBuilder()
                .lore("<gray>Click to gain the giga diamond!</gray>")
                .build();

        setItem(0, diamond);
    }

    @Override
    public void onClickInventory(InventoryClickEvent event) {
        // prevent taking items
        event.setCancelled(true);

        ItemStack currentItem = event.getCurrentItem();

        // ignore empty clicks
        if (currentItem == null || currentItem.getType().equals(Material.AIR)) return;

        BukkitPixelPlayer player = getPlayer();
        var clickedInventory = event.getClickedInventory();

        // ignore clicks outside of the custom inventory
        if (clickedInventory == null || clickedInventory.equals(player.getInventory())) return;

        int slot = event.getSlot();

        if (slot == 0) {
            player.playGenericClickSound();

            ItemStack item = createBuilder().build();
            player.addOrDropItem(item);
        }
    }

    private @NotNull ItemBuilder createBuilder() {
        return ItemBuilder.material(Material.DIAMOND)
                .name("<aqua>Giga Diamond</aqua>")
                .glowing();
    }

}

Opening the inventory

InventoryHandler inventoryHandler = BukkitCoreLibrary.getInventoryHandler();

inventoryHandler.openInventory(
        plugin,
        player,
        GigaDiamondInventory.class,
        "Giga diamond",
        9
);

Explanation

  • PixelPrivateInventory is the base class for custom inventories
  • setItems() defines the GUI layout
  • setItem(slot, item) places items into the inventory
  • onClickInventory(...) handles interactions
  • event.setCancelled(true) prevents default behavior
  • getPlayer() returns the current viewer

Notes

  • Always validate clicks (null / AIR / wrong inventory)
  • Keep inventory logic simple and focused
  • Use helper methods (like createBuilder()) to avoid duplication

Next step

[[Create an input inventory|Core-API/Build-your-first-feature/Inventories-&-UI/Create-an-input-inventory]]