### Maven Dependency Setup Source: https://context7.com/nichtstudiocode/invui/llms.txt Add the XenonDevs Maven repository and the InvUI artifact as a dependency in your Maven project. ```xml xenondevs https://repo.xenondevs.xyz/releases xyz.xenondevs.invui invui 2.1.0 provided ``` -------------------------------- ### Gradle Dependency Setup Source: https://context7.com/nichtstudiocode/invui/llms.txt Add the XenonDevs Maven repository and the InvUI artifact as a dependency in your Gradle project using Kotlin DSL. ```gradle repositories { maven { url = uri("https://repo.xenondevs.xyz/releases") } } dependencies { implementation("xyz.xenondevs.invui:invui:2.1.0") } ``` -------------------------------- ### Window Management Source: https://context7.com/nichtstudiocode/invui/llms.txt Demonstrates how to create and manage GUI windows, including standard split windows and specialized types like AnvilWindow. It covers setting titles, defining GUIs, handling player interactions, and dynamic title updates. ```APIDOC ## `Window` — Displaying GUIs and Handling Open/Close Events `Window` is the link between a `Gui` and a Bukkit inventory shown to a specific player. Use `Window.builder()` for a standard split window (upper GUI + player inventory) or `Window.mergedBuilder()` for a single merged GUI. Special window types (Anvil, Furnace, Stonecutter, etc.) have their own factories. ```java import net.kyori.adventure.text.Component; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; import xyz.xenondevs.invui.window.AnvilWindow; // Standard split window (chest-style, upper GUI + player hotbar below) Window window = Window.builder() .setTitle("Treasure Chest") .setGui(gui) .setViewer(player) .addOpenHandler(() -> System.out.println(player.getName() + " opened the menu")) .addCloseHandler(() -> System.out.println(player.getName() + " closed the menu")) .build(); window.open(); // Change the title dynamically after opening window.setTitle(Component.text("Updated Title")); // Anvil window — upper GUI is a 3-slot (left, right, output); captures rename input AnvilWindow anvilWindow = AnvilWindow.builder() .setTitle("Search…") .setUpperGui(Gui.empty(3, 1)) .setLowerGui(gui) .setViewer(player) .addRenameHandler(text -> System.out.println("Player typed: " + text)) .build(); anvilWindow.open(); ``` ``` -------------------------------- ### Normal GUI with Structure Source: https://context7.com/nichtstudiocode/invui/llms.txt Build a bordered 9x4 chest GUI using Gui.builder() and a structure string. Unrecognized characters in the structure are left empty. ```java import org.bukkit.Material; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.item.ItemBuilder; import xyz.xenondevs.invui.window.Window; // Build a bordered 9x4 chest GUI Item borderItem = Item.simple(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setName(" ")); Gui gui = Gui.builder() .setStructure( "# # # # # # # # #", "# . . . . . . . #", "# . . . . . . . #", "# # # # # # # # #" ) .addIngredient('#', borderItem) .build(); // Show to a player with a chest window Window.builder() .setTitle("My Menu") .setGui(gui) .setViewer(player) .build() .open(); ``` -------------------------------- ### Create a Normal GUI with GUIBuilder Source: https://github.com/nichtstudiocode/invui/wiki/Normal-GUI Use GUIBuilder to construct a normal GUI with a specified size and structure. Define item placements using a string-based layout. ```java Item border = new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE)) GUI gui = new GUIBuilder<>(GUIType.NORMAL, 9, 4) .setStructure("" + "# # # # # # # # #" + "# . . . . . . . #" + "# . . . . . . . #" + "# # # # # # # # #") .addIngredient('#', border) .build(); ``` -------------------------------- ### ItemBuilder with Placeholders and Localization Source: https://context7.com/nichtstudiocode/invui/llms.txt Demonstrates using `ItemBuilder` with MiniMessage placeholders that are resolved at build time. It shows how to build an item with a player's specific locale. ```java ItemBuilder localized = new ItemBuilder(Material.BOOK) .setName("'s Journal") .addLoreLines("Last login: ") .setPlaceholder("player_name", player.getName()) .setPlaceholder("player_color", "") .setPlaceholder("last_login", "2024-01-15"); ItemStack result = localized.build(); // builds with Locale.US ItemStack forLocale = localized.build(player.locale()); // builds with player's locale ``` -------------------------------- ### GUI Animations Source: https://context7.com/nichtstudiocode/invui/llms.txt Explains how to use the `Animation` class to create pop-in effects for GUI slots. It details configuring animation speed, slot selection patterns, intermediary items, sound effects, and completion callbacks. ```APIDOC ## `Animation` — Slot Pop-In Effects `Animation` lets slots in a GUI "pop in" in a defined order with a configurable tick delay between frames. While an animation runs, the GUI is frozen (no player interaction). Animations support custom slot filters, intermediary item providers, sound effects, and finish callbacks. ```java import org.bukkit.Material; import org.bukkit.Sound; import xyz.xenondevs.invui.gui.Animation; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.item.ItemBuilder; Gui gui = Gui.builder() .setStructure( "a a a a a a a a a", "a a a a a a a a a", "a a a a a a a a a" ) .addIngredient('a', Item.simple(new ItemBuilder(Material.DIAMOND))) .build(); // Horizontal snake animation with a sound effect on each frame Animation animation = Animation.builder() .setTickDelay(2) .setSlotSelector(() -> Animation.horizontalSnakeSlotSelector()) .setIntermediary(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setName(" ")) .addSoundEffect(Sound.BLOCK_NOTE_BLOCK_PLING, 1.0f, 1.5f) .addFinishHandler(state -> System.out.println("Animation complete!")) .build(); gui.playAnimation(animation); // Cancel a running animation if needed // gui.cancelAnimation(); ``` ``` -------------------------------- ### Create and Apply a Structure Source: https://github.com/nichtstudiocode/invui/wiki/Structure Define a GUI layout using characters and ingredients, then apply it to a GUI builder or an existing GUI. Ingredients like Marker.ITEM_LIST_SLOT, BackItem, and ForwardItem can be used. ```java Structure structure = new Structure("\n # # # # # # # # #\n # x x x x x x x #\n # x x x x x x x #\n # # # < # > # # #") .addIngredient('x', Marker.ITEM_LIST_SLOT) // where paged items should be put .addIngredient('#', new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName("§r")) // this will just create a SimpleItem with the given ItemBuilder .addIngredient('<', new BackItem()) .addIngredient('>', new ForwardItem()); // use it in a GUI Builder new GUIBuilder(GUIType.PAGED_ITEMS, 9, 4).setStructure(structure); // or use it on an existing GUI gui.applyStructure(structure); ``` -------------------------------- ### Build a Paged GUI with a list of items Source: https://github.com/nichtstudiocode/invui/wiki/Paged-GUI Constructs a paged GUI using 'GUIBuilder' to display a list of items. It defines the GUI structure, assigns slots for paged items, borders, and navigation controls, and sets the items to be displayed. ```java Item border = new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName("§r")); // an example list of items to display List items = Arrays.stream(Material.values()) .filter(material -> !material.isAir() && material.isItem()) .map(material -> new SimpleItem(new ItemBuilder(material))) .collect(Collectors.toList()); // create the gui GUI gui = new GUIBuilder<>(GUIType.PAGED_ITEMS, 9, 4) .setStructure("" + "# # # # # # # # #" + "# x x x x x x x #" + "# x x x x x x x #" + "# # # < # > # # #") .addIngredient('x', Markers.ITEM_LIST_SLOT) // where paged items should be put .addIngredient('#', border) .addIngredient('<', new BackItem()) .addIngredient('>', new ForwardItem()) .setItems(items) .build(); // show the window new SimpleWindow(player, "InvUI", gui).show(); ``` -------------------------------- ### Plugin Initialization Source: https://context7.com/nichtstudiocode/invui/llms.txt Initialize InvUI in your plugin's onEnable method by supplying the plugin instance to the InvUI singleton before creating any GUIs. ```java import xyz.xenondevs.invui.InvUI; import org.bukkit.plugin.java.JavaPlugin; public class MyPlugin extends JavaPlugin { @Override public void onEnable() { InvUI.getInstance().setPlugin(this); } } ``` -------------------------------- ### Gui.fill Source: https://context7.com/nichtstudiocode/invui/llms.txt Fills the entire GUI with a specified item. ```APIDOC ## `Gui.fill` ### Description Fills the entire GUI with the provided item. ### Method `void fill(Item item)` ### Parameters - **item** (Item) - The item to fill the GUI with. ### Request Example ```java Gui gui = Gui.empty(9, 6); Item glass = Item.simple(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE).setName(" ")); gui.fill(glass); ``` ``` -------------------------------- ### Build a Paged GUI with other GUIs as pages Source: https://github.com/nichtstudiocode/invui/wiki/Paged-GUI Constructs a paged GUI where each page is another GUI. It defines the structure, navigation controls, and sets a list of GUIs to be displayed as pages. ```java GUI gui = new GUIBuilder<>(GUIType.PAGED_GUIs, 9, 5) .setStructure("" + "x x x x x x x x x" + "x x x x x x x x x" + "x x x x x x x x x" + "x x x x x x x x x" + ". . < . . . > . .") .addIngredient('x', Markers.ITEM_LIST_SLOT) // where paged items should be put (in this case: the parts of the nested GUI) .addIngredient('<', new BackItem()) .addIngredient('>', new ForwardItem()) .setGUIs(Arrays.asList(page1GUI, page2GUI)) .build(); // show the window new SimpleWindow(player, "InvUI", gui).show(); ``` -------------------------------- ### Set Up Server-Side Localization Source: https://context7.com/nichtstudiocode/invui/llms.txt Register translation maps for each Locale using Languages.getInstance().addLanguage(). ItemBuilder automatically resolves translatable keys based on the viewer's locale when building items. ```java import xyz.xenondevs.invui.i18n.Languages; import xyz.xenondevs.invui.item.ItemBuilder; import org.bukkit.Material; import java.util.Locale; import java.util.Map; // Register translations in onEnable Languages languages = Languages.getInstance(); languages.addLanguage(Locale.ENGLISH, Map.of( "menu.title", "Main Menu", "item.sword.name", "Firesword", "item.sword.lore", "Burns enemies on hit" )); languages.addLanguage(Locale.GERMAN, Map.of( "menu.title", "Hauptmenü", "item.sword.name", "Feuerschwert", "item.sword.lore", "Setzt Feinde beim Treffen in Brand" )); // ItemBuilder resolves keys automatically for the viewer's locale ItemBuilder swordBuilder = new ItemBuilder(Material.DIAMOND_SWORD) .setName("item.sword.name") // treated as a translation key (MiniMessage format) .addLoreLines("item.sword.lore"); // When the window is opened, InvUI calls getItemProvider(player) // which calls swordBuilder.get(player.locale()), resolving the correct translation ``` -------------------------------- ### Fill GUI with Items Source: https://context7.com/nichtstudiocode/invui/llms.txt Fills the entire GUI with a specified item. Useful for creating backgrounds or placeholder elements. ```java import org.bukkit.Material; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.item.ItemBuilder; Gui gui = Gui.empty(9, 6); // Fill the entire GUI with a placeholder Item glass = Item.simple(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE).setName(" ")); gui.fill(glass); ``` -------------------------------- ### Custom Click Handling Item with Item.builder() Source: https://context7.com/nichtstudiocode/invui/llms.txt Creates an item that counts clicks and updates its display. `updateOnClick()` automatically calls `notifyWindows()` on each click, so manual calls are not needed in the handler. ```java import org.bukkit.Material; import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.item.ItemBuilder; // An item that counts clicks and updates its display accordingly int[] clickCount = {0}; Item counterItem = Item.builder() .setItemProvider(player -> new ItemBuilder(Material.DIAMOND) .setName("Clicks: " + clickCount[0])) .updateOnClick() // calls notifyWindows() automatically on each click .addClickHandler(click -> { if (click.clickType().isLeftClick()) { clickCount[0]++; } else { clickCount[0] = 0; } // notifyWindows() is called by updateOnClick(); no manual call needed here }) .build(); ``` -------------------------------- ### Create a Tabbed GUI with Switchable Sub-GUIs using TabGui Source: https://context7.com/nichtstudiocode/invui/llms.txt Use TabGui to manage multiple nested GUIs as tabs. Individual tabs can be null for conditional disabling. Markers.ITEM_LIST_SLOT defines the content rendering area. ```java import org.bukkit.Material; import xyz.xenondevs.invui.gui.*; import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.item.ItemBuilder; import xyz.xenondevs.invui.window.Window; import java.util.List; // Build two sub-GUIs used as tab content Gui tab1Content = Gui.builder() .setStructure("d d d d d d d d d") .addIngredient('d', Item.simple(new ItemBuilder(Material.DIAMOND).setName("Diamonds"))) .build(); Gui tab2Content = Gui.builder() .setStructure("g g g g g g g g g") .addIngredient('g', Item.simple(new ItemBuilder(Material.GOLD_INGOT).setName("Gold"))) .build(); // Tab selector buttons Item tab1Btn = Item.builder() .setItemProvider(p -> new ItemBuilder(Material.DIAMOND).setName("Diamonds Tab")) .addClickHandler((item, click) -> ((TabGui) click.gui()).setTab(0)) .build(); Item tab2Btn = Item.builder() .setItemProvider(p -> new ItemBuilder(Material.GOLD_INGOT).setName("Gold Tab")) .addClickHandler((item, click) -> ((TabGui) click.gui()).setTab(1)) .build(); Structure structure = new Structure( "1 2 # # # # # # #", "x x x x x x x x x", "x x x x x x x x x", "x x x x x x x x x" ) .addIngredient('#', Item.simple(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setName(" "))) .addIngredient('x', Markers.ITEM_LIST_SLOT) .addIngredient('1', tab1Btn) .addIngredient('2', tab2Btn); TabGui gui = TabGui.builder() .setStructure(structure) .setTabs(List.of(tab1Content, tab2Content)) .addTabChangeHandler((from, to) -> System.out.println("Tab: " + from + " → " + to)) .build(); Window.builder() .setTitle("Tabbed Menu") .setGui(gui) .setViewer(player) .build() .open(); ``` -------------------------------- ### Structure with Global and Per-Structure Ingredients Source: https://context7.com/nichtstudiocode/invui/llms.txt Defines a reusable GUI structure using characters mapped to ingredients. Global ingredients are registered once with `Structure.addGlobalIngredient`, while per-structure ingredients are added using `addIngredient`. ```java import org.bukkit.Material; import xyz.xenondevs.invui.gui.Structure; import xyz.xenondevs.invui.gui.Markers; import xyz.xenondevs.invui.item.ItemBuilder; // Register global ingredients once (e.g. in onEnable) Structure.addGlobalIngredient('#', new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setName(" ")); Structure.addGlobalIngredient('x', Markers.ITEM_LIST_SLOT); // paged/scroll content slot // Per-structure ingredients (page navigation buttons) Structure structure = new Structure( "# # # # # # # # #", "# x x x x x x x #", "# x x x x x x x #", "# # # < # > # # #" ) .addIngredient('<', () -> Item.builder() // supplier creates a new instance per slot .setItemProvider(p -> new ItemBuilder(Material.RED_STAINED_GLASS_PANE).setName("◀ Back")) .build()) .addIngredient('>', () -> Item.builder() .setItemProvider(p -> new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE).setName("Forward ▶")) .build()); ``` -------------------------------- ### Create GUI Manually Source: https://github.com/nichtstudiocode/invui/wiki/InvUI-Basics Manually create a SimpleGUI and set items using coordinates or slot indices. Structures can also be applied to manually created GUIs. ```java // create the GUI GUI gui = new SimpleGUI(9, 4); // set items using x and y coordinates gui.setItem(0, 0, item); // set an item using the slot index gui.setItem(10, item); // use a Structure to add items (like in the GUI Builder) Structure structure = new Structure("" + "# # # # # # # # #" + "# . . . . . . . #" + "# . . . . . . . #" + "# # # # # # # # #") .addIngredient('#', item); gui.applyStructure(structure); ``` -------------------------------- ### Implement ScrollGui for Line-based Scrolling Source: https://context7.com/nichtstudiocode/invui/llms.txt Use ScrollGui to arrange content in lines and allow player scrolling. Define scroll navigation items and use Markers.ITEM_LIST_SLOT for content placement. Requires setting up a Structure and binding it to content. ```java import org.bukkit.Material; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.gui.Markers; import xyz.xenondevs.invui.gui.Structure; import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.item.ItemBuilder; import xyz.xenondevs.invui.window.Window; import java.util.List; List rows = List.of( Item.simple(new ItemBuilder(Material.DIAMOND).setName("Row 1")), Item.simple(new ItemBuilder(Material.GOLD_INGOT).setName("Row 2")), Item.simple(new ItemBuilder(Material.EMERALD).setName("Row 3")), Item.simple(new ItemBuilder(Material.REDSTONE).setName("Row 4")), Item.simple(new ItemBuilder(Material.LAPIS_LAZULI).setName("Row 5")) ); Item scrollUp = Item.builder() .setItemProvider(p -> new ItemBuilder(Material.ARROW).setName("▲ Scroll Up")) .addClickHandler((item, click) -> { ScrollGui scrollGui = (ScrollGui) click.gui(); scrollGui.setLine(Math.max(0, scrollGui.getLine() - 1)); }) .build(); Item scrollDown = Item.builder() .setItemProvider(p -> new ItemBuilder(Material.ARROW).setName("▼ Scroll Down")) .addClickHandler((item, click) -> { ScrollGui scrollGui = (ScrollGui) click.gui(); scrollGui.setLine(Math.min(scrollGui.getMaxLine(), scrollGui.getLine() + 1)); }) .build(); Structure structure = new Structure( "^ x x x x x x x x", "v x x x x x x x x" ) .addIngredient('x', Markers.ITEM_LIST_SLOT) .addIngredient('^', scrollUp) .addIngredient('v', scrollDown); ScrollGui gui = ScrollGui.itemsBuilder() .setStructure(structure) .setContent(rows) .addScrollHandler((from, to) -> System.out.println("Scrolled: " + from + " → " + to)) .build(); Window.builder() .setTitle("Scroll Menu") .setGui(gui) .setViewer(player) .build() .open(); ``` -------------------------------- ### Create GUI with GUIBuilder Source: https://github.com/nichtstudiocode/invui/wiki/InvUI-Basics Use GUIBuilder to define a GUI's type, dimensions, structure, and fill it with items. The structure string uses characters to represent different item types. ```java GUI gui = new GUIBuilder<>(GUIType.NORMAL, 9, 4) .setStructure("" + "# # # # # # # # #" + "# . . . . . . . #" + "# . . . . . . . #" + "# # # # # # # # #") .addIngredient('#', new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE))) .build(); ``` -------------------------------- ### Create an Embeddable, Event-Driven Inventory with VirtualInventory Source: https://context7.com/nichtstudiocode/invui/llms.txt VirtualInventory allows embedding inventories into GUIs with custom stack sizes and event handling. It supports serialization for persistence. ```java import org.bukkit.Material; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.Structure; import xyz.xenondevs.invui.inventory.VirtualInventory; import xyz.xenondevs.invui.inventory.event.ItemPreUpdateEvent; import xyz.xenondevs.invui.item.ItemBuilder; import xyz.xenondevs.invui.window.Window; // 9-slot virtual inventory with custom per-slot max stack sizes int[] maxStackSizes = new int[9]; java.util.Arrays.fill(maxStackSizes, 16); // max 16 per slot VirtualInventory inv = new VirtualInventory(maxStackSizes); // Only allow players to place DIAMOND or EMERALD items inv.addPreUpdateHandler((ItemPreUpdateEvent event) -> { var newItem = event.getNewItem(); if (newItem != null && newItem.getType() != Material.DIAMOND && newItem.getType() != Material.EMERALD) { event.setCancelled(true); } }); // Notify when the inventory changes inv.addPostUpdateHandler(event -> System.out.println("Slot " + event.getSlot() + " updated")); // Embed into a GUI Gui gui = Gui.builder() .setStructure( "# # # # # # # # #", "# i i i i i i i i", // 'i' maps to the virtual inventory "# # # # # # # # #" ) .addIngredient('#', new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE)) .build(); gui.setInventory('i', inv); Window.builder() .setTitle("Storage") .setGui(gui) .setViewer(player) .build() .open(); // Serialize / deserialize for persistence (e.g. to a database or file) byte[] data = inv.serialize(); VirtualInventory loaded = VirtualInventory.deserialize(data); ``` -------------------------------- ### Implement Slot Pop-In Animations Source: https://context7.com/nichtstudiocode/invui/llms.txt Animations freeze the GUI while playing. Configure tick delay, slot selection patterns (e.g., horizontal snake), intermediary items, sound effects, and finish callbacks. Animations can be cancelled if needed. ```java import org.bukkit.Material; import org.bukkit.Sound; import xyz.xenondevs.invui.gui.Animation; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.item.ItemBuilder; Gui gui = Gui.builder() .setStructure( "a a a a a a a a a", "a a a a a a a a a", "a a a a a a a a a" ) .addIngredient('a', Item.simple(new ItemBuilder(Material.DIAMOND))) .build(); // Horizontal snake animation with a sound effect on each frame Animation animation = Animation.builder() .setTickDelay(2) .setSlotSelector(() -> Animation.horizontalSnakeSlotSelector()) .setIntermediary(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setName(" ")) .addSoundEffect(Sound.BLOCK_NOTE_BLOCK_PLING, 1.0f, 1.5f) .addFinishHandler(state -> System.out.println("Animation complete!")) .build(); gui.playAnimation(animation); // Cancel a running animation if needed // gui.cancelAnimation(); ``` -------------------------------- ### Implement PagedGui for Paginated Item Display Source: https://context7.com/nichtstudiocode/invui/llms.txt Use PagedGui to split content across multiple pages. Define navigation items and use Markers.ITEM_LIST_SLOT for content placement. Requires setting up a Structure and binding it to content. ```java import org.bukkit.Material; import xyz.xenondevs.invui.gui.PagedGui; import xyz.xenondevs.invui.gui.Markers; import xyz.xenondevs.invui.gui.Structure; import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.item.ItemBuilder; import xyz.xenondevs.invui.window.Window; import java.util.List; import java.util.stream.Collectors; import java.util.Arrays; // Build a list of items — one SimpleItem per non-air material List items = Arrays.stream(Material.values()) .filter(m -> !m.isAir() && m.isItem()) .map(m -> Item.simple(new ItemBuilder(m))) .collect(Collectors.toList()); // Page-navigation items that are aware of the paged GUI they are placed in Item backItem = Item.builder() .setItemProvider(p -> new ItemBuilder(Material.RED_STAINED_GLASS_PANE) .setName("◀ Previous page")) .addClickHandler((item, click) -> { // obtain the bound paged gui from the click context PagedGui pagedGui = (PagedGui) click.gui(); if (pagedGui.getPage() > 0) pagedGui.setPage(pagedGui.getPage() - 1); }) .build(); Item forwardItem = Item.builder() .setItemProvider(p -> new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE) .setName("Next page ▶")) .addClickHandler((item, click) -> { PagedGui pagedGui = (PagedGui) click.gui(); if (pagedGui.getPage() < pagedGui.getPageCount() - 1) pagedGui.setPage(pagedGui.getPage() + 1); }) .build(); Structure structure = new Structure( "# # # # # # # # #", "# x x x x x x x #", "# x x x x x x x #", "# # # < # > # # #" ) .addIngredient('#', Item.simple(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setName(" "))) .addIngredient('x', Markers.ITEM_LIST_SLOT) .addIngredient('<', backItem) .addIngredient('>', forwardItem); PagedGui gui = PagedGui.itemsBuilder() .setStructure(structure) .setContent(items) .addPageChangeHandler((oldPage, newPage) -> System.out.println("Page changed: " + oldPage + " → " + newPage)) .build(); Window.builder() .setTitle("Item Browser — Page ") .setGui(gui) .setViewer(player) .build() .open(); ``` -------------------------------- ### Create and Manage GUI Windows Source: https://context7.com/nichtstudiocode/invui/llms.txt Use Window.builder() for standard split GUIs or Window.mergedBuilder() for merged GUIs. Special window types like AnvilWindow have their own factories. You can dynamically update the window title after opening. ```java import net.kyori.adventure.text.Component; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; import xyz.xenondevs.invui.window.AnvilWindow; // Standard split window (chest-style, upper GUI + player hotbar below) Window window = Window.builder() .setTitle("Treasure Chest") .setGui(gui) .setViewer(player) .addOpenHandler(() -> System.out.println(player.getName() + " opened the menu")) .addCloseHandler(() -> System.out.println(player.getName() + " closed the menu")) .build(); window.open(); // Change the title dynamically after opening window.setTitle(Component.text("Updated Title")); // Anvil window — upper GUI is a 3-slot (left, right, output); captures rename input AnvilWindow anvilWindow = AnvilWindow.builder() .setTitle("Search…") .setUpperGui(Gui.empty(3, 1)) .setLowerGui(gui) .setViewer(player) .addRenameHandler(text -> System.out.println("Player typed: " + text)) .build(); anvilWindow.open(); ``` -------------------------------- ### Asynchronous Item Loading with Item.builder() Source: https://context7.com/nichtstudiocode/invui/llms.txt An item that displays a placeholder while its actual content is computed asynchronously in the background. This prevents the GUI from freezing during long computations. ```java Item asyncItem = Item.builder() .async( new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE).setName("Loading…"), () -> { Thread.sleep(2000); // simulate heavy computation return new ItemBuilder(Material.EMERALD).setName("Ready!"); }) .build(); ``` -------------------------------- ### Custom Clickable Item Source: https://github.com/nichtstudiocode/invui/wiki/InvUI-Basics Create a custom item by extending BaseItem. Implement getItemProvider for appearance and handleClick for interaction logic. Call notifyWindows() to update the displayed item. ```java public class CountItem extends BaseItem { private int count; @Override public ItemProvider getItemProvider() { return new ItemBuilder(Material.DIAMOND).setDisplayName("Count: " + count); } @Override public void handleClick(ClickType clickType, Player player, InventoryClickEvent event) { if (clickType.isLeftClick()) { count++; // increment if left click } else { count--; // else decrement } notifyWindows(); // this will update the ItemStack that is displayed to the player } } ``` -------------------------------- ### Maven Repository Configuration Source: https://github.com/nichtstudiocode/invui/blob/main/README.md Add this repository to your Maven project to access InvUI artifacts. ```xml xenondevs https://repo.xenondevs.xyz/releases ``` -------------------------------- ### Localization with Languages Source: https://context7.com/nichtstudiocode/invui/llms.txt Details the `Languages` singleton for server-side translation of item names and lore. It explains how to register translation maps for different locales and how `ItemBuilder` automatically resolves translatable keys based on the viewer's locale. ```APIDOC ## `Languages` — Built-in Localization `Languages` is a singleton that enables server-side translation of `ItemBuilder` names and lore. Register translation maps (key → MiniMessage string) per `Locale`. `ItemBuilder` then resolves translatable keys at build time using the viewer's locale. ```java import xyz.xenondevs.invui.i18n.Languages; import xyz.xenondevs.invui.item.ItemBuilder; import org.bukkit.Material; import java.util.Locale; import java.util.Map; // Register translations in onEnable Languages languages = Languages.getInstance(); languages.addLanguage(Locale.ENGLISH, Map.of( "menu.title", "Main Menu", "item.sword.name", "Firesword", "item.sword.lore", "Burns enemies on hit" )); languages.addLanguage(Locale.GERMAN, Map.of( "menu.title", "Hauptmenü", "item.sword.name", "Feuerschwert", "item.sword.lore", "Setzt Feinde beim Treffen in Brand" )); // ItemBuilder resolves keys automatically for the viewer's locale ItemBuilder swordBuilder = new ItemBuilder(Material.DIAMOND_SWORD) .setName("item.sword.name") // treated as a translation key (MiniMessage format) .addLoreLines("item.sword.lore"); // When the window is opened, InvUI calls getItemProvider(player) // which calls swordBuilder.get(player.locale()), resolving the correct translation ``` ``` -------------------------------- ### InvUI GUI Filling Methods Source: https://github.com/nichtstudiocode/invui/wiki/GUIs Utility methods for filling GUIs with items, other GUIs, or virtual inventories. The `replace` parameter determines if existing items are overwritten. ```java gui.fill(item, replace); // fills everything ``` ```java gui.fill(start, end, item, replace); // fills from the start index to the end index ``` ```java gui.fillColumn(column, item, replace); // fills a column ``` ```java gui.fillRow(row, item, replace); // fills a row ``` ```java gui.fillBorders(item, replace); // fill the borders ``` ```java gui.fillRectangle(x, y, width, height, item, replace); // fills a rectangle with the an Item ``` ```java gui.fillRectangle(x, y, gui, replace); // fills a rectangle with another GUI ``` ```java gui.fillRectangle(x, y, width, virtualInventory, replace); // fills a rectangle with a VirtualInventory ``` -------------------------------- ### Create a 'Forward' navigation item for PagedGUI Source: https://github.com/nichtstudiocode/invui/wiki/Paged-GUI Extends 'PageItem' to create a custom control for navigating to the next page. It uses a green stained glass pane and displays navigation information based on the current GUI state. ```java public class ForwardItem extends PageItem { public ForwardItem() { super(true); } @Override public ItemBuilder getItemProvider(PagedGUI gui) { ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); builder.setDisplayName("§7Next page") .addLoreLines(gui.hasNextPage() ? "§7Go to page §e" + (gui.getCurrentPageIndex() + 2) + "§7/§e" + gui.getPageAmount() : "§cThere are no more pages"); return builder; } } ``` -------------------------------- ### Create a 'Back' navigation item for PagedGUI Source: https://github.com/nichtstudiocode/invui/wiki/Paged-GUI Extends 'PageItem' to create a custom control for navigating to the previous page. It uses a red stained glass pane and displays navigation information based on the current GUI state. ```java public class BackItem extends PageItem { public BackItem() { super(false); } @Override public ItemBuilder getItemProvider(PagedGUI gui) { ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); builder.setDisplayName("§7Previous page") .addLoreLines(gui.hasPageBefore() ? "§7Go to page §e" + gui.getCurrentPageIndex() + "§7/§e" + gui.getPageAmount() : "§cYou can't go further back"); return builder; } } ``` -------------------------------- ### Register Global Ingredients Source: https://github.com/nichtstudiocode/invui/wiki/Structure Register ingredients globally to reuse them across multiple structures. This is useful for common elements like background panes or navigation items. ```java Structure.addGlobalIngredient('#', new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName("§r")); // These items need a supplier Structure.addGlobalIngredient('<', BackItem::new); Structure.addGlobalIngredient('>', ForwardItem::new); // adding the Marker.ITEM_LIST_SLOT as a global ingredient is also a good idea Structure.addGlobalIngredient('x', Marker.ITEM_LIST_SLOT); ``` -------------------------------- ### Add InvUI Gradle Dependency Source: https://github.com/nichtstudiocode/invui/wiki/Home Configure your Gradle project with the XenonDevs repository and InvUI dependency. ```gradle repositories { maven { url = uri("https://repo.xenondevs.xyz/releases") } } dependencies { implementation "de.studiocode.invui:InvUI:VERSION" } ``` -------------------------------- ### Gui.fillColumn Source: https://context7.com/nichtstudiocode/invui/llms.txt Fills a specific column of the GUI with a specified item. ```APIDOC ## `Gui.fillColumn` ### Description Fills an entire column of the GUI with the provided item. ### Method `void fillColumn(int column, Object content)` ### Parameters - **column** (int) - The index of the column to fill. - **content** (Object) - The item or VirtualInventory to fill the column with. ### Request Example ```java Gui gui = Gui.empty(9, 6); Item border = Item.simple(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setName(" ")); gui.fillColumn(0, border); ``` ``` -------------------------------- ### ItemBuilder with MiniMessage and Lore Source: https://context7.com/nichtstudiocode/invui/llms.txt Constructs an item using `ItemBuilder`, supporting MiniMessage formatting for names and lore, enchantment glints, and custom data. ```java import org.bukkit.Material; import xyz.xenondevs.invui.item.ItemBuilder; // Basic MiniMessage name + lore ItemBuilder builder = new ItemBuilder(Material.NETHER_STAR) .setName("Ultimate Sword") .addLoreLines( "Damage: +50", "Speed: +10", "", "Click to equip" ) .setGlint(true); ``` -------------------------------- ### Add InvUI Maven Dependency Source: https://github.com/nichtstudiocode/invui/wiki/Home Include this repository and dependency in your Maven project to use InvUI. ```xml xenondevs https://repo.xenondevs.xyz/releases de.studiocode.invui InvUI VERSION ``` -------------------------------- ### InvUI GUI Background Item Source: https://github.com/nichtstudiocode/invui/wiki/GUIs Sets a background ItemProvider for a GUI. This background is displayed in slots that are otherwise empty, useful for paged GUIs. ```java gui.setBackground(itemProvider); ``` -------------------------------- ### Auto-cycling Item with Item.builder() Source: https://context7.com/nichtstudiocode/invui/llms.txt An item that automatically cycles between two states every 20 ticks (1 second). ```java Item cyclingItem = Item.builder() .setCyclingItemProvider(20, new ItemBuilder(Material.RED_WOOL).setName("OFF"), new ItemBuilder(Material.LIME_WOOL).setName("ON")) .build(); ``` -------------------------------- ### Fill Row and Column Source: https://context7.com/nichtstudiocode/invui/llms.txt Populates an entire row or column of the GUI with a specified item. Useful for creating structural elements or separators. ```java gui.fillRow(0, border); gui.fillColumn(0, border); ``` -------------------------------- ### Implement ControlItem for PagedGUI Source: https://github.com/nichtstudiocode/invui/wiki/Items This ControlItem allows navigation through a PagedGUI. It handles left-clicks to go forward and right-clicks to go back. The displayed item updates automatically when the page changes. ```java public class ChangePageItem extends ControlItem { @Override public void handleClick(ClickType clickType, Player player, InventoryClickEvent event) { if (clickType == ClickType.LEFT) { getGui().goForward(); // go one page forward on left-click } else if (clickType == ClickType.RIGHT) { getGui().goBack(); // go one page back on right-click } } @Override public ItemProvider getItemProvider(PagedGUI gui) { return new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE) .setDisplayName("§7Current page: " + (gui.getCurrentPageIndex() + 1)) // + 1 because we don't want to have "Current page: 0" .addLoreLines("§8Left-click to go forward", "§8Right-click to go back"); } } ``` -------------------------------- ### Fill GUI Borders Source: https://context7.com/nichtstudiocode/invui/llms.txt Populates only the outer border slots of the GUI with a specified item. The `replaceExisting` parameter controls whether existing items in the border slots are overwritten. ```java Item border = Item.simple(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setName(" ")); gui.fillBorders(border, true); ``` -------------------------------- ### Gui.fillRectangle Source: https://context7.com/nichtstudiocode/invui/llms.txt Fills a specific rectangular region within the GUI. ```APIDOC ## `Gui.fillRectangle` ### Description Fills a specified rectangular region within the GUI with a given item or inventory. The `replaceExisting` parameter determines if existing items in the region should be overwritten. ### Method `void fillRectangle(int x, int y, int width, int height, Object content, boolean replaceExisting)` ### Parameters - **x** (int) - The starting x-coordinate of the rectangle. - **y** (int) - The starting y-coordinate of the rectangle. - **width** (int) - The width of the rectangle. - **height** (int) - The height of the rectangle. - **content** (Object) - The item, VirtualInventory, or nested Gui to fill the region with. - **replaceExisting** (boolean) - If true, existing items in the region will be replaced. If false, only empty slots will be filled. ### Request Example ```java Gui gui = Gui.empty(9, 6); Item highlight = Item.simple(new ItemBuilder(Material.YELLOW_STAINED_GLASS_PANE)); gui.fillRectangle(2, 1, 5, 4, highlight, false); // only fill empty slots VirtualInventory inv = new VirtualInventory(5 * 4); gui.fillRectangle(2, 1, 5, inv); Gui innerGui = Gui.empty(3, 3); gui.fillRectangle(3, 1, innerGui); ``` ``` -------------------------------- ### Gui.fillBorders Source: https://context7.com/nichtstudiocode/invui/llms.txt Fills the borders of the GUI with a specified item, optionally preserving inner slots. ```APIDOC ## `Gui.fillBorders` ### Description Fills the borders of the GUI with the provided item. The `replaceExisting` parameter controls whether existing items in the border slots are replaced. ### Method `void fillBorders(Item item, boolean replaceExisting)` ### Parameters - **item** (Item) - The item to fill the borders with. - **replaceExisting** (boolean) - If true, existing items in border slots will be replaced. If false, only empty slots will be filled. ### Request Example ```java Gui gui = Gui.empty(9, 6); Item border = Item.simple(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setName(" ")); gui.fillBorders(border, true); ``` ``` -------------------------------- ### Gui.fillRow Source: https://context7.com/nichtstudiocode/invui/llms.txt Fills a specific row of the GUI with a specified item. ```APIDOC ## `Gui.fillRow` ### Description Fills an entire row of the GUI with the provided item. ### Method `void fillRow(int row, Object content)` ### Parameters - **row** (int) - The index of the row to fill. - **content** (Object) - The item or VirtualInventory to fill the row with. ### Request Example ```java Gui gui = Gui.empty(9, 6); Item border = Item.simple(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setName(" ")); gui.fillRow(0, border); ``` ``` -------------------------------- ### InvUI Maven Dependency Source: https://github.com/nichtstudiocode/invui/blob/main/README.md Include this dependency in your project to use the InvUI library. Replace VERSION with the desired version. ```xml xyz.xenondevs.invui invui VERSION ``` -------------------------------- ### Embed Nested GUI Source: https://context7.com/nichtstudiocode/invui/llms.txt Places a nested GUI within a specified rectangular region of the parent GUI. This allows for complex, hierarchical menu structures. ```java Gui innerGui = Gui.empty(3, 3); gui.fillRectangle(3, 1, innerGui); ``` -------------------------------- ### Fill Rectangular Region Source: https://context7.com/nichtstudiocode/invui/llms.txt Fills a specified rectangular area within the GUI. The `replaceExisting` parameter determines if only empty slots are filled or if existing items are overwritten. This can be used with items or VirtualInventories. ```java Item highlight = Item.simple(new ItemBuilder(Material.YELLOW_STAINED_GLASS_PANE)); gui.fillRectangle(2, 1, 5, 4, highlight, false); // only fill empty slots ``` ```java VirtualInventory inv = new VirtualInventory(5 * 4); gui.fillRectangle(2, 1, 5, inv); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.