Skip to content

CustomGUI

Dark Litss edited this page Sep 15, 2020 · 4 revisions

A custom GUI is a GUI that you can specify it's layout by using a yaml configuration.

Getting started

First of all, let's create a new class called TestCustomGUI, and makes it extends CustomGui.

public class ConfirmDialogGUI extends CustomGui{
    public ConfirmDialogGUI(Player player) {
        super(TestPlugin.getInstance(), player, GuiLayout.from(TestPlugin.getInstance().getConfig().getConfigurationSection("ui.confirm")));
    }

    @Override
    protected void onClosed() {
        player.sendMessage("Smart move, boy.");
    }
}

The constructor of the CustomGui class takes 3 arguments, Plugin, Player, and GuiLayout.

GuiLayout

A GuiLayout holds all the information that is needed to create a Inventory. To get an GuiLayout you need an ConfigurationSection that has following options:

  1. title - The title of the Inventory
  2. layout - A List of String, each String have at most 9 characters, every character will be an ItemStack showing on the Inventory.
  3. callbacks - The callbacks related to the layout, we will need them later in the GUI class.
  4. widgets - Declare the ItemStack of each characters.

Open your config.yml and write following:

ui:
  confirm:
    title: "§6Confirmation"
    layout:
     - '####@####'
     - ' y     n '
     - '#########'
    callbacks:
      'y': yes
      'n': no
    widgets:
      'y':
        ==: org.bukkit.inventory.ItemStack
        type: GRASS
        meta:
          ==: ItemMeta
          meta-type: UNSPECIFIC
          display-name: "§cYes"
          lore:
            - "§c This will kill {player}."
      'n':
        ==: org.bukkit.inventory.ItemStack
        type: BARRIER
        meta:
          ==: ItemMeta
          meta-type: UNSPECIFIC
          display-name: "§cNo"
          lore:
            - "§c Get out of here, "
            - "§c and pretends nothing ever happen."
      '#':
        ==: org.bukkit.inventory.ItemStack
        type: STAINED_GLASS_PANE
        meta:
          ==: ItemMeta
          meta-type: UNSPECIFIC
          display-name: "§c"
          lore:
            - "§7 Just some decorations. "

Applying variables

The items on the layout supports variables and PlaceholderAPIs.
To activate the placeholders, you need to call applyPlaceholders(player) method.
To apply your own variables, you can use applyVariables(Map<String, Object>) method.

An example
    public ConfirmDialogGUI(Player player) {
        super(TestPlugin.getInstance(), player,
                GuiLayout.from(TestPlugin.getInstance().getConfig().getConfigurationSection("ui"))
                        .applyVariables(Collections.singletonMap("player", "Lss233"))
                        .applyPlaceholders(player)
        );
    }

Dealing with the callbacks

We use on(String, BiComsumer<Player, ClickType>) to perform actions when the player interact with our GUI.

        on("yes", (user, clickType) -> {
            user.kickPlayer("You shouldn't really do that.");
        }).on("no", (user, clickType) -> {
            user.closeInventory();
        });

You can use ClickType to perform different action in various situation.

Changing the layout Dynamically

There are times we can't just define all the components inside the ConfigurationSection.

But, it is ok. All we need is to modify the GuiLayout before our GUI is being present to the players.

Add a widget

getLayout().addWidget(identifier, itemstack);

This method adds an widget just like ConfigurationSection we the previous written.

There is one thing to keep in mind that the identifier must be a one char String, otherwise it might likely not to work.

Update variables

If you have the same variable name but with different values on various widgets.

You can just using getLayout().updateWidget(identifier, variables) to update them.

Update ItemMeta

getLayout().updateWidget(identifer, (item, meta) -> {
    meta.setDisplayName("How about this?");
    meta.setLore(Arrays.asList("What", "about", "now?"));
});

A completed example

Let's make the @ to be our dynamically added widget.

getLayout().addWidget("@", new ItemStack(Material.PAPER))
    .updateWidget("@", (item, meta) -> {
        meta.setDisplayName(ChatColor.RED + "Curse");
        meta.setLore(Collections.singletonList(ChatColor.GREY + "Hey, {me}. What's your choice?"));
    })
    .updateWidget("@", Collections.singletonMap("me", player.getName()));