Bukkit Gui
Bukkit Gui Module is a new replacement of the old Bukkit Menu Module. With the power feature of pane, mapping, and more independent components, you can create a GUI with ease.
First Release: 0.7.1b1-SNAPSHOT
Adding the gui module
In your module build.gradle, please add the following dependency:
- Groovy
- Kotlin DSL
dependencies {
api 'io.fairyproject:bukkit-gui'
// Other dependencies
}
dependencies {
api("io.fairyproject:bukkit-gui")
// Other dependencies
}
Creating a Gui
To create a Gui, you'll first need to inject the GuiFactory
class into your component, and include a title in the create function.
@InjectableComponent
public class MyComponent {
private final GuiFactory guiFactory;
public MyComponent(GuiFactory guiFactory) {
this.guiFactory = guiFactory;
}
public void open(Player player) {
Gui gui = guiFactory.create(Component.text("My Gui"));
// configure
gui.open(player);
}
}
Done! you created a Gui with a title of My Gui
, easy right? but what if you want to add a pane to the Gui?
Pane System
Here it comes, the main difference between the old Menu Module and the new Gui Module, the Pane System.
A Pane is a container that holds gui items, and it can be added to the Gui to display the components. A Gui can hold multiple panes, and each pane will have their specific position and region.
Creating a Pane
Creating a pane is simple, you can use the Pane
class to create a new pane, and add it to the Gui. Let's start with a normal pane.
NormalPane pane = Pane.normal(9, 3); // 9 slots, 3 rows
gui.addPane(pane);
A normal pane is a pane that holds a fixed amount of slots, there is also other types of panes such as PaginatedPane for paginated slots.
Adding Slots
To add slots to the pane, you can use the setSlot
method to add an item to the pane.
pane.setSlot(0, GuiSlot.of(XMaterial.APPLE));
pane.fillEmptySlots(GuiSlot.of(XMaterial.GRAY_STAINED_GLASS_PANE)); // fill empty slots with a specific gui slot
You have a Gui with an apple in the first slot, and the rest of the slots are filled with gray stained-glass pane! Easy so far?
Gui Slot
With the previous example, you know how to create a GuiSlot with plain material. But actually, you can do more with GuiSlot. Not only accepting XMaterial, but also ItemStack, ItemBuilder, and regular Bukkit Material etc.
GuiSlot withItemBuilder = GuiSlot.of(ItemBuilder
.of(XMaterial.APPLE)
.name("&bApple")
.build());
GuiSlot withItemStack = GuiSlot.of(new ItemStack(Material.APPLE));
GuiSlot withMaterial = GuiSlot.of(Material.APPLE);
Behavior
GuiSlot also supports behavior, you can add a click event to the slot, and it will be triggered when the player clicks on the slot.
GuiSlot onClick = GuiSlot.of(XMaterial.APPLE, clickedPlayer -> {
clickedPlayer.sendMessage("You clicked the apple!");
});
GuiSlot onRightClick = GuiSlot.of(XMaterial.APPLE, (clickedPlayer, clickType) -> {
if (clickType != ClickType.RIGHT)
return;
clickedPlayer.sendMessage("You right-clicked the apple!");
});
Item Selector
Item Selector is a special type of GuiSlot that allows the player to select an item from their inventory.
import java.util.concurrent.atomic.AtomicReference;
AtomicReference<ItemStack> item = new AtomicReference<>(new ItemStack(Material.APPLE));
// Create an item selector in the first slot of the pane.
// Make sure when you setSlot to the pane, you set the slot to 0 too.
GuiSlot itemSelectorSlot = GuiSlot.itemSelector(pane, 0)
.emptyItem(new ItemStack(Material.BARRIER)) // The item to display when there is no item in the item selector.
.currentItem(new ItemStack(Material.APPLE)) // The default item available in the item selector.
.canPlacePredicate(itemStack ->itemStack.getType() == Material.APPLE) // The predicate to check if the player can place the item.
.updateCallback(itemStack -> {
// The callback to update the item in the item selector.
// This will be called when the player places an item in the item selector.
item.set(itemStack);
})
.build();
pane.setSlot(0, itemSelectorSlot);
Paginated
PaginatedPane is a special type of pane that holds a paginated list of slots, and it allows the player to navigate through the pages.
PaginatedPane paginatedPane = Pane.paginated(9, 3); // 9 slots, 3 rows
// Add slots to the paginated pane
for (int i = 0; i < 100; i++) {
int index = i;
paginatedPane.addSlot(GuiSlot.of(XMaterial.APPLE, clickedPlayer -> {
clickedPlayer.sendMessage("You clicked the apple number " + index);
});
}
NormalPane navigationPane = Pane.normal(0, 4, 9, 1); // 9 slots, 1 row, starting from the 4th row
navigationPane.setSlot(0, GuiSlot.previousPage(paginatedPane)); // The previous page button
navigationPane.setSlot(8, GuiSlot.nextPage(paginatedPane)); // The next page button
gui.addPane(paginatedPane);
gui.addPane(navigationPane);