InvUI Documentation

repository·main·Indexed 19 days ago

https://github.com/nichtstudiocode/invui

An Inventory GUI library for Minecraft Paper servers providing high-level abstractions for creating complex user interfaces. It supports various inventory types (Chest, Anvil, Smithing, etc.) and GUI layouts including Paged, Tab, and Scroll. Key features include the IngredientMatrix for crafting-style grids, CustomBoundItem and CustomItem builders for dynamic and asynchronous item loading, and first-class support for Adventure's MiniMessage and localization via ItemBuilder.

Tokens
3.3K
Snippets
8
Records
13
Agent score
65%

What's inside InvUI

  1. Overview of InvUI features

    main

    InvUI is an Inventory GUI library for Minecraft Paper servers that provides several high-level abstractions for creating complex user interfaces:

    • Supported Inventory Types: Chest, Anvil, Brewer, Cartography, Crafter, Crafting, Furnace, Grindstone, Merchant, Smithing, and Stonecutter.
    • GUI Layout Types: Normal, Paged, Tab, and Scroll.
    • Embeddable Inventories: Powerful event systems allow for customizing input (e.g., restricting item types) and slot behavior (e.g., custom maximum stack sizes).
    • Text & Localization: First-class support for Adventure's MiniMessage and easy localization via the built-in ItemBuilder.
  2. Install InvUI via Maven

    main

    To use InvUI in your Paper server project, add the XenonDevs repository and the InvUI dependency to your pom.xml file. Replace VERSION with the specific version compatible with your Minecraft server version.

    <repositories>
        <repository>
            <id>xenondevs</id>
            <url>https://repo.xenondevs.xyz/releases</url>
        </repository>
    </repositories>
    
    <dependencies>
        <dependency>
            <groupId>xyz.xenondevs.invui</groupId>
            <artifactId>invui</artifactId>
            <version>VERSION</version>
        </dependency>
    </dependencies>
  3. Define an IngredientMatrix for crafting inventories

    main

    An IngredientMatrix represents a grid of ingredients, typically used for crafting-style inventories. It is an immutable structure defined by a width, a height, and a structure string that maps the layout of ingredients.

    To create one, you provide:

    1. width and height of the grid.
    2. A structure string of length width * height where each character represents an ingredient type.
    3. An ingredientMap that maps these characters to Ingredient objects.

    If an Ingredient is defined as an Ingredient.Element(SlotElementSupplier), the matrix will automatically invoke the supplier to generate SlotElements for the corresponding slots. You can also use Markers within your ingredients to identify specific slots (e.g., for content lists).

    // Conceptual usage of the IngredientMatrix constructor
    int width = 3;
    int height = 3;
    String structure = "ABCDEFGHI"; // 9 characters for 3x3
    
    Map<Character, Ingredient> ingredientMap = new HashMap<>();
    ingredientMap.put('A', ingredientA);
    // ... add other ingredients
    
    IngredientMatrix matrix = new IngredientMatrix(width, height, structure, ingredientMap);
  4. Check InvUI version compatibility

    main

    InvUI versioning is tied to specific Minecraft versions. Since v2, it is no longer a multi-version library. Ensure you select the correct InvUI version for your server environment:

    Minecraft versionInvUI version
    26.22.2.0 - 2.3.x
    26.1.22.0.0 - 2.1.x
    1.14.0 - 1.21.111.49
  5. Configure item update behavior

    main

    You can control how and when a CustomItem refreshes its visual state using the following builder methods:

    • updatePeriodically(int period): Sets a fixed interval (in ticks) at which the item's ItemProvider is re-evaluated. This is required for cycling items or items that change based on time.
    • updateOnClick(): Automatically triggers a window notification (refresh) whenever the item is clicked. This is useful for items that change state (e.g., a toggle button) upon interaction.
  6. Configure item providers for CustomBoundItem

    main

    The ItemProvider determines what the item looks like. CustomBoundItem.Builder provides several ways to set this:

    • Static: .setItemProvider(ItemProvider itemProvider)
    • Player-dependent: .setItemProvider(Function<? super Player, ? extends ItemProvider> itemProvider)
    • GUI and Player-dependent: .setItemProvider(BiFunction<? super Player, ? super G, ? extends ItemProvider> itemProvider)
    • Cycling: .setCyclingItemProvider(int period, List<? extends ItemProvider> itemProviders) cycles through a list of providers every period ticks.
    • Asynchronous: Use .async(ItemProvider placeholder, Supplier<? extends ItemProvider> itemProviderSupplier) or .async(ItemProvider placeholder, CompletableFuture<? extends ItemProvider> itemProviderFuture) to prevent blocking the main thread while loading items.
    // Cycling through items every 20 ticks
    builder.setCyclingItemProvider(20, List.of(item1, item2, item3));
    
    // Async loading with a placeholder
    builder.async(placeholderItem, () -> fetchRealItem());
  7. Configure asynchronous item loading

    main

    If an ItemProvider requires heavy computation or network calls, use the .async() methods to prevent blocking the main server thread. You can provide a placeholder item to display immediately, and then supply the actual item via a Supplier or a CompletableFuture.

    When the async task completes, the item will automatically update and notify all open windows to refresh the display.

    // Using a Supplier
    Item asyncItem = new CustomItem.Builder()
        .async(placeholderItem, () -> fetchRealItem())
        .build();
    
    // Using a CompletableFuture
    CompletableFuture<ItemProvider> future = CompletableFuture.supplyAsync(() -> fetchProvider());
    Item asyncItem = new CustomItem.Builder()
        .async(placeholderItem, future)
        .build();
  8. Handle events in CustomBoundItem

    main

    You can chain multiple handlers to a CustomBoundItem using add...Handler methods. These handlers are executed in the order they are added.

    MethodParametersDescription
    addClickHandlerBiConsumer<? super Item, ? super Click>Triggered on item click.
    addClickHandlerTriConsumer<? super Item, ? super G, ? super Click>Triggered on item click; provides access to the bound Gui instance.
    addBundleSelectHandlerQuadConsumer<? super Item, ? super G, ? super Player, ? super Integer>Triggered when a bundle selection occurs; provides the Player and the selected slot.
    addBindHandlerBiConsumer<? super Item, ? super G>Triggered when the item is bound to a GUI.
    addUnbindHandlerBiConsumer<? super Item, ? super G>Triggered when the item is unbound from a GUI.
    addModifierConsumer<? super Item>A final transformation applied to the item instance before it is returned by build().
  9. Use specialized builders for Paged, Scroll, and Tab Guis

    main

    Instead of using the generic CustomBoundItem.Builder, use these specialized static inner classes to ensure the item automatically reacts to specific GUI state changes:

    • CustomBoundItem.Paged: Automatically triggers item updates when the page changes or the total page count changes in a PagedGui.
    • CustomBoundItem.Scroll: Automatically triggers item updates when the scroll position or line count changes in a ScrollGui.
    • CustomBoundItem.Tab: Automatically triggers item updates when the active tab changes in a TabGui.
    // Use Paged builder to react to page changes
    BoundItem<PagedGui<?>> pagedItem = new CustomBoundItem.Paged()
        .setItemProvider(myProvider)
        .build();
    
    // Use Scroll builder to react to scrolling
    BoundItem<ScrollGui<?>> scrollItem = new CustomBoundItem.Scroll()
        .setItemProvider(myProvider)
        .build();
    
    // Use Tab builder to react to tab switches
    BoundItem<TabGui> tabItem = new CustomBoundItem.Tab()
        .setItemProvider(myProvider)
        .build();
  10. Create cycling items with setCyclingItemProvider

    main

    The setCyclingItemProvider(int period, List<? extends ItemProvider> itemProviders) method allows an item to cycle through a list of different ItemProviders automatically.

    • The item will update its appearance every period ticks.
    • The index of the provider used is calculated as (currentTick / period) % itemProviders.size().
    • If only one provider is provided in the list, it behaves like a standard static item.
    Item cyclingItem = new CustomItem.Builder()
        .setCyclingItemProvider(20, List.of(providerA, providerB, providerC))
        .build();
  11. Retrieve slots and elements from an IngredientMatrix

    main

    Once an IngredientMatrix is constructed, you can query it to find specific slots, ingredient keys, or UI elements at specific coordinates or indices.

    Querying Keys

    • getKey(int i): Gets the ingredient key at the given index.
    • getKey(int x, int y): Gets the ingredient key at the given coordinates.

    Querying Slots

    • getSlots(char key): Returns an unmodifiable list of all Slot objects associated with a specific ingredient key, ordered left-to-right, top-to-bottom.
    • getSlots(Marker marker): Returns an unmodifiable list of Slot objects that are marked with the specified Marker.
    • getContentListSlots(): A convenience method to get all slots marked as either Markers.CONTENT_LIST_SLOT_HORIZONTAL or Markers.CONTENT_LIST_SLOT_VERTICAL.

    Querying SlotElements

    • getSlotElement(int i): Gets the SlotElement at the given index.
    • getSlotElement(int x, int y): Gets the SlotElement at the given coordinates.
  12. Create a custom item with CustomItem.Builder

    main

    Use CustomItem.Builder to create items with custom logic for how they look (via ItemProvider), how they respond to clicks, and how they respond to being selected in a bundle. This is useful for items that need to change dynamically based on the player or external state.

    Key capabilities:

    • Dynamic Providers: Set an ItemProvider that can change based on the Player viewing it.
    • Event Handlers: Chain multiple click and selection handlers using addClickHandler and addBundleSelectHandler.
    • Asynchronous Loading: Use .async() to show a placeholder item while a real item is being fetched from a Supplier or CompletableFuture.
    • Automatic Updates: Configure the item to refresh its appearance periodically via updatePeriodically(int period) or whenever it is clicked via updateOnClick().
    Item customItem = new CustomItem.Builder()
        .setItemProvider(player -> myDynamicItemProvider(player))
        .addClickHandler((item, click) -> {
            // Handle click logic here
        })
        .updateOnClick()
        .build();