Items
In InvUI, the UI Elements are just called Items.
Every item has an ItemProvider
which returns ItemStacks
based on player UUIDs. This behavior allows for easy localization of UI Elements, as you just need to inherit from ItemProvider
and implement your localization code there.
Unlike other inventory libraries, InvUI does not redraw items every tick. To trigger an update, call item.notifyWindows();
. This will notify all Windows
that are currently displaying that Item
to call Item#getItemProvider
and ItemProvider#getFor
and display the updated item to their viewer.
Default ItemProviders
There are also two default ItemProviders
in InvUI: ItemWrapper
and ItemBuilder
.
Both implementations will ignore the provided UUID in ItemProvider#getFor
, but you can always inherit from ItemProvider
to change this behavior.
Default UI Items in InvUI
InvUI provides a few basic items, but you will probably have to create your own ones for more complicated behavior.
Item | Description |
---|---|
AsyncItem | Creates it's ItemProvider asynchronously and displays a placeholder ItemProvider until the task is done. |
AutoCycleItem | Automatically cycles between an array of ItemProviders. |
AutoUpdateItem | Automatically updates its ItemProvider on a timer. |
CommandItem | Makes the player execute a command or write a message in chat when clicked. |
CycleItem | Cycles through an array of ItemProviders when clicked. |
SimpleItem | Just displays an ItemProvider. |
SuppliedItem | Displays an ItemProvider from a Supplier |
If you don't need any behavior at all and just want to make your GUI
look pretty, you can use the SimpleItem
. It cannot update it's ItemProvider
later on and does not have any on-click functionality.
Creating your own Item
To create your own Item, you'll need to inherit from either BaseItem
(if you want to be able to change its appearance) or SimpleItem
(if you don't need to change its appearance).
In this example, I inherited from BaseItem
.
Every time a player clicks on the Item, a counter will be incremented and the number on the Item will change.
class CountItem : BaseItem() {
private var count = 0
override fun getItemProvider(): ItemProvider {
return ItemBuilder(Material.DIAMOND).setDisplayName("Count: $count")
}
override fun handleClick(clickType: ClickType, player: Player, event: InventoryClickEvent) {
if (clickType.isLeftClick) {
count++ // increment if left click
} else {
count-- // else decrement
}
notifyWindows() // this will update the ItemStack that is displayed to the player
}
}
public class CountItem extends BaseItem {
private int count;
@Override
public ItemProvider getItemProvider() {
return new ItemBuilder(Material.DIAMOND).setDisplayName("Count: " + count);
}
@Override
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull 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
}
}
After adding the Item to the GUI, it will look like this:
ControlItems
A ControlItem
is a special sort of Item
: When it is added to a GUI
, the GUI
will be saved inside the ControlItem
.
You can also manually assign a GUI to a ControlItem
by calling ControlItem#setGUI
.
So, what are ControlItems
used for? You guessed it, controlling GUIs
. Page switching buttons are one example, as they need to call PagedGUI#goForward
and PagedGUI#goBack
which would not be possible without having the instance of the GUI
to control saved somewhere.
This would be a simple implementation of ControlItem
for a paged GUI:
class ChangePageItem : ControlItem<PagedGUI>() {
override fun handleClick(clickType: ClickType, player: Player, event: InventoryClickEvent) {
if (clickType == ClickType.LEFT) {
gui.goForward() // go one page forward on left-click
} else if (clickType == ClickType.RIGHT) {
gui.goBack() // go one page back on right-click
}
}
override fun getItemProvider(gui: PagedGUI): ItemProvider {
return ItemBuilder(Material.BLACK_STAINED_GLASS_PANE)
.setDisplayName("§7Current page: " + (gui.currentPageIndex + 1)) // + 1 because we don't want to have "Current page: 0"
.addLoreLines("§8Left-click to go forward", "§8Right-click to go back")
}
}
public class ChangePageItem extends ControlItem<PagedGUI> {
@Override
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull 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");
}
}
The getItemProvider
method will get called when the page changes, as PagedGUI
internally calls Controllable#updateControlItems
, so the displayed page number in this example item will always be correct.