This documentation guides you through creating a SpecialButton for use in your plugin, utilizing the SpecialButton.java class to implement custom click actions. This example is the typical case of a very simple button.
Overview
SpecialButton extends ZButton from the fr.maxlego08.menu API to customize the button's behavior on click events. It's designed to close the player's inventory interface, send a custom message, and apply a "jump" or "boost" effect to the player's velocity.
Prerequisites
Ensure you have the fr.maxlego08.menu API included in your project to use ZButton and other required classes.
Implementation Steps
Step 1: Define the SpecialButton Class
Create a class named SpecialButton that extends ZButton. This class will override the onClick method to define the button's behavior.
In the SpecialButton class, override the onClick method to specify the actions that occur when the button is clicked. This includes closing the player's inventory, sending a custom message, and applying a velocity change to simulate a jump.
Within the onClick method, add the logic for the custom actions:
Close the Inventory Interface: Use player.closeInventory() to close the inventory interface.
Send a Custom Message to the Player: Use player.sendMessage("§fWhoosshh") to send a custom message.
Modify the Player's Velocity:
Retrieve the current velocity: Vector vector = player.getVelocity().
Modify the velocity to add an upward motion: vector.add(new Vector(0, 2, 0)).
Apply the new velocity: player.setVelocity(vector).
@Overridepublic void onClick(Player player, InventoryClickEvent event, InventoryDefault inventory, int slot, Placeholders placeholders) {
player.closeInventory(); // Close the player's current inventoryplayer.sendMessage("§fWhoosshh"); // Send a custom message to the playerVector vector =player.getVelocity(); // Get the current velocity of the playervector.add(newVector(0,2,0)); // Modify the Y-axis to make the player "jump"player.setVelocity(vector); // Apply the new velocity to the player}
Step 4: Regitser the SpecialButton
To register the SpecialButton in your plugin, instantiate it and add it to your inventory layout where needed. Ensure that the inventory system you're using supports custom button actions.
publicclassMyPluginextendsJavaPlugin { @OverridepublicvoidonEnable() {// Plugin startup logic// Assume buttonManager is your instance of a class managing buttonsbuttonManager.register(newNoneLoader(this,SpecialButton.class,"zmenuexample_special")); }}
This method allows to save a button very quickly without having to create a new loader. You must specify the plugin from where the plugin comes from, the button class and the name. For the name of the button it is advisable to prefix the name of your plugin.
Result
packagefr.maxlego08.example;importfr.maxlego08.menu.api.utils.Placeholders;importfr.maxlego08.menu.button.ZButton;importfr.maxlego08.menu.inventory.inventories.InventoryDefault;importorg.bukkit.entity.Player;importorg.bukkit.event.inventory.InventoryClickEvent;importorg.bukkit.util.Vector;importorg.bukkit.entity.Player;importorg.bukkit.event.inventory.InventoryClickEvent;importorg.bukkit.util.Vector;importfr.maxlego08.menu.button.ZButton;importfr.maxlego08.menu.inventory.inventories.InventoryDefault;/** * SpecialButton extends ZButton to implement a custom click action. */publicclassSpecialButtonextendsZButton { /** * Handles the click event on this special button. * * @param player The player who clicked the button. * @param event The inventory click event details. * @param inventory The inventory where the click occurred. * @param slot The slot number where the click happened. * @param placeholders Placeholders for dynamic text replacement, not used in this method. */ @Override public void onClick(Player player, InventoryClickEvent event, InventoryDefault inventory, int slot, Placeholders placeholders) {
// Close the inventory interface for the player. player.closeInventory();// Send a message to the player. player.sendMessage("§fWhoosshh");// Get the current velocity of the player.Vector vector =player.getVelocity();// Add to the player's current velocity to make them move upwards.// Here, 'new Vector(0, 2, 0)' adds no motion on the X and Z axes, but adds upward motion on the Y axis. vector.add(newVector(0,2,0));// Apply the new velocity to the player, effectively causing a "jump" or "boost" effect. player.setVelocity(vector); // Call the superclass method if necessary. This call might be redundant if the superclass does not implement further action.
super.onClick(player, event, inventory, slot, placeholders); }}
Paginate Button
This documentation outlines how to implement a ExamplePaginateButton for creating a paginated inventory interface in your plugin, using the provided ExamplePaginateButton.java class as a basis.
Overview
ExamplePaginateButton leverages the PaginateButton interface from the fr.maxlego08.menu.api to offer pagination functionality, allowing items to be displayed across multiple inventory pages.
Prerequisites
Include the fr.maxlego08.menu API in your project.
Understand basic concepts of inventory manipulation in Bukkit/Spigot plugins.
Implementation Steps
Step 1: Extend ZButton and Implement PaginateButton
Your ExamplePaginateButton should extend ZButton and implement PaginateButton, enabling special render behavior and pagination:
We use Plugin instead of ExamplePlugin because the NoneLoader class, which is responsible for button registration, requires a constructor parameter of the plugin. Since NoneLoader is designed to work with the general Plugin interface from Spigot, it ensures compatibility with any Spigot plugin. Casting to the specific ExamplePlugin class is then performed to access its unique functionalities. This approach maintains flexibility and adherence to Spigot's plugin architecture.
Step 2: Override hasSpecialRender
Indicate that your button uses custom rendering logic for pagination:
Override the onRender method to define how items are displayed based on the current page:
@OverridepublicvoidonRender(Player player,InventoryDefault inventory) {Pagination<ItemStack> pagination =newPagination<>(); List<ItemStack> itemStacks = pagination.paginate(this.plugin.getItemStacks(), this.slots.size(), inventory.getPage());
// Loop and add items to the inventory}
Step 4: Define Pagination Size
Implement getPaginationSize to specify the total number of items for pagination. This directly influences the number of pages within the inventory, allowing for dynamic list management. Changes in the list size will automatically adjust the pagination, making this method a key component in handling variable amounts of data efficiently in the inventory UI.
To register the ExamplePaginateButton in your plugin, instantiate it and add it to your inventory layout where needed. Ensure that the inventory system you're using supports custom button actions.
publicclassMyPluginextendsJavaPlugin { @OverridepublicvoidonEnable() {// Plugin startup logic// Assume buttonManager is your instance of a class managing buttonsbuttonManager.register(newNoneLoader(plugin,ExamplePaginateButton.class,"zmenuexample_pagination")); }}
This method allows to save a button very quickly without having to create a new loader. You must specify the plugin from where the plugin comes from, the button class and the name. For the name of the button it is advisable to prefix the name of your plugin.
Result
packagefr.maxlego08.example;importfr.maxlego08.menu.api.button.PaginateButton;importfr.maxlego08.menu.button.ZButton;importfr.maxlego08.menu.inventory.inventories.InventoryDefault;importfr.maxlego08.menu.zcore.utils.inventory.Pagination;importorg.bukkit.entity.Player;importorg.bukkit.inventory.ItemStack;importorg.bukkit.plugin.Plugin;importjava.util.List;/** * ExamplePaginateButton extends ZButton and implements PaginateButton to provide * pagination functionality for a custom inventory within a zMenu. */publicclassExamplePaginateButtonextendsZButtonimplementsPaginateButton {// Reference to the main plugin instance for accessing its functionalities.privatefinalExamplePlugin plugin; /** * Constructor that casts the generic Plugin type to the specific ExamplePlugin type. * @param plugin The plugin instance, passed in as a generic Plugin type. */publicExamplePaginateButton(Plugin plugin) {this.plugin= (ExamplePlugin) plugin; } /** * Indicates that this button has a special render behavior, enabling pagination. * @return true to signify that custom rendering logic is used. */ @OverridepublicbooleanhasSpecialRender() {returntrue; } /** * Custom rendering method for paginated items. It populates the inventory with items * based on the current page and available slots. * @param player The player viewing the inventory. * @param inventory The inventory being rendered. */ @OverridepublicvoidonRender(Player player,InventoryDefault inventory) {// Utilize Pagination utility to split itemStacks into pages.Pagination<ItemStack> pagination =newPagination<>();// Get paginated list of ItemStacks for the current page. List<ItemStack> itemStacks = pagination.paginate(this.plugin.getItemStacks(), this.slots.size(), inventory.getPage());
// Loop through the paginated items and add them to the inventory.for (int i =0; i !=Math.min(itemStacks.size(),this.slots.size()); i++) {int slot =slots.get(i); // Get the slot number.ItemStack itemStack =itemStacks.get(i); // Get the ItemStack.// Add the item to the inventory at the specified slot and set a click listener.inventory.addItem(slot, itemStack).setClick(event ->player.sendMessage("§fClick !")); } } /** * Determines the total size of pagination based on the total number of items. * @param player The player for whom the pagination size is calculated. * @return The total number of items to paginate. */ @OverridepublicintgetPaginationSize(Player player) {// Return the total size of itemStacks to determine how many pages are needed.returnthis.plugin.getItemStacks().size(); }}
Custom Button Loader
You can create your own button loader if your button needs more settings. Just create a class that will implement ButtonLoader. All you have to do is implement the methods, here is an example from zShop.