Skip to content
LeeGod edited this page Dec 2, 2021 · 2 revisions

Fairy has a built-in Menu system to let you build menu in very simple way

Menu

All you need to do is create a class that extends Menu and override several methods

Example:

import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import io.fairyproject.bukkit.menu.Button;
import io.fairyproject.bukkit.menu.ButtonBuilder;
import io.fairyproject.bukkit.menu.Menu;
import io.fairyproject.bukkit.menu.buttons.DisplayButton;
import io.fairyproject.bukkit.util.Chat;
import io.fairyproject.bukkit.util.items.ItemBuilder;

public class ExampleMenu extends Menu {

    // The draw function, where you set buttons
    @Override
    public void draw(boolean firstInitial) {
        // First initial, you can do things while it's on open instead of updates
        if (firstInitial) {
            player.sendMessage("&eYOU OPENED THE MENU"); // the player field is accessible anywhere in this class

            // set display button at slot 0
            this.set(0, new DisplayButton(new ItemStack(Material.EMERALD), true)); // new DisplayButton(ItemStack displayItem, boolean shouldCancel)

            // add an interactable button with button builder at slot 1
            this.set(1, new ButtonBuilder()
                    .item(new ItemBuilder(Material.WOOL).name("&eThe Wool")) // Using ItemBuilder to quickly build an item
                    .shouldCancel((ignored, slot, clickType) -> player.getName().equals("LeeGod")) // Cancel the inventory click event if the player's name is LeeGod
                    .callback((ignored, slot, clickType, hotbarButton) -> { // (Player, int, ClickType, int)
                        Chat.sendRaw(player, "&aHOLY POG YOU CLICKED THe WOOL"); // Chat.sendRaw automatically translate color codes

                        this.render(); // re-draw the menu
                    })
                    .build()
            );

            // add a button on menu x 1, y 0, translates to slot 9
            this.set(1, 0, new ExampleButton());

            // add a button on the first empty slot
            this.set(this.findFirstEmpty(), new ExampleButton());
        } else {
            // clear it if it's not first initial, you'll see items on open, but on update it will gone in this case
            this.clear();
        }
    }

    @Override
    public int getSize() {
        return 18; // Return the size of this menu, return -1 the menu will automatically find the size of the menu based on the maximum slot button
    }

    // The get Title Function, where you set the title of the menu
    @Override
    public String getTitle() {
        return "The Cool Menu";
    }

    // If you don't like the builder pattern, you can extends the Button instead
    private class ExampleButton extends Button {

        // return the display item
        @Override
        public ItemStack getButtonItem(Player player) {
            return new ItemBuilder(Material.CARPET)
                    .name("Hello")
                    .build();
        }

        // on click
        @Override
        public void clicked(Player player, int slot, ClickType clickType, int hotbarButton) {
            player.sendMessage("You've clicked hello");
        }

        // should cancel inventory click event, default is true
        @Override
        public boolean shouldCancel(Player player, int slot, ClickType clickType) {
            return true;
        }
    }

}

PaginatedMenu

You can also create a menu with multiple pages with Imanity Framework! simply extends PaginatedMenu

and here's the Example;

import org.bukkit.Material;
import io.fairyproject.bukkit.menu.buttons.DisplayButton;
import io.fairyproject.bukkit.menu.pagination.PaginatedMenu;
import io.fairyproject.bukkit.util.items.ItemBuilder;

public class ExamplePaginatedMenu extends PaginatedMenu {

    @Override
    public int getMaxPages() {
        return 3; // How many page you want in this menu
    }

    // Draw Buttons based on the page player is in
    @Override
    protected void drawPage(boolean firstInitial, int page) {
        switch (page) {
            case 1:
                this.set(0, new DisplayButton(new ItemBuilder(Material.SIGN).name("I'm the first page Item!").build(), true));
                break;
            case 2:
                this.set(0, new DisplayButton(new ItemBuilder(Material.SIGN).name("I'm the second page Item!").build(), true));
                break;
            default:
            case 3:
                this.set(0, new DisplayButton(new ItemBuilder(Material.SIGN).name("I'm the third page Item!").build(), true));
                break;
        }
    }

    // Draw Global items that will be in the top of every page
    // By default there will be a page down and page up button on slot 0 and 8
    // If you don't want it you can remove the super call in this method and new PageButton for your own
    @Override
    protected void drawGlobal(boolean firstInitial) {
        super.drawGlobal(firstInitial);
        this.set(1, new DisplayButton(new ItemBuilder(Material.EMERALD).name("I'm the Global Item!").build(), true));
    }

    @Override
    public int getGlobalSize() {
        return 9; // The size of global items, default is 9
    }

    // get title
    @Override
    public String getPrePaginatedTitle() {
        return "Paginated Menu";
    }
}

PaginatedListMenu

In some case you might want to display a list of soemthing in to menu then you can use PaginatedListMenu to display it

For example:

import org.bukkit.Bukkit;
import org.bukkit.Material;
import io.fairyproject.bukkit.menu.Button;
import io.fairyproject.bukkit.menu.buttons.DisplayButton;
import io.fairyproject.bukkit.menu.pagination.PaginatedListMenu;
import io.fairyproject.bukkit.util.items.ItemBuilder;

import java.util.List;

public class ExamplePaginatedListMenu extends PaginatedListMenu {
    
    // Return list of buttons, in this case we want to display every player in this menu with pages
    // So we can use transformToButtons function, to transform a list of players to buttons for menu to display
    @Override
    public List<Button> getButtons() {
        return this.transformToButtons(Bukkit.getOnlinePlayers(), player -> new DisplayButton(new ItemBuilder(Material.SKULL_ITEM)
                .data(3)
                .skull(player.getName())
        .build(), true));
    }

    @Override
    public String getPrePaginatedTitle() {
        return "&eServer Player List";
    }
}

Menu Function

To open the menu new ExampleMenu().open(Player);

To get all menu by type Menu.getMenusByType(ExampleMenu.class)

That's all, simple, easy but powerful!

Clone this wiki locally