Resource GUIManager - Fast and easy way to create GUI

Discussion in 'Spigot Plugin Development' started by FrozenLegend, Oct 14, 2018.

  1. Hi everyone,

    I'm here for share some classes I've made for creating GUI using inventory.
    I'm still working on the project so change will probably be done to these files so if you have any suggestion do it.

    Why should i use it ?

    • Create GUI supporting multiple pages
    • Add action when clicking on different item
    • Design your GUI pages with a pattern (like craft recipes)
    • Built in tool for designing each page
    • Easy to use

    Example:

    Code (Java):
    public final class FrostCore extends JavaPlugin {

        private GUIManager manager;

        @Override
        public void onEnable() {
            manager = new GUIManager(this);
            Bukkit.getPluginCommand("teleports").setExecutor(this);

            final CommonGUI gui = manager.get("teleports");

            if (gui.isEmpty()) {

                final Page worldSelector = new Page("Worlds", Size.THREE_ROW);
                final Page teleports = new Page("Teleports", Size.THREE_ROW);

                // Create the pattern like this chaining everything
                final Pattern worldSelectorPattern = worldSelector.createPattern()
                        .setRow(Row.FIRST,  "RBRBWBRBR")
                        .setRow(Row.SECOND, "RB NOE BR")
                        .setRow(Row.THIRD,  "RBRBWBRBR")
                        .setKey('R', Item.create(Material.RED_STAINED_GLASS_PANE).name(ChatColor.RED + "Border"))
                        .setKey('B', Item.create(Material.BLACK_STAINED_GLASS_PANE).name(ChatColor.BLACK + "Border"))
                        .setKey('W', Item.create(Material.WHITE_STAINED_GLASS_PANE).name(ChatColor.WHITE + "Border"))
                        .setKey('N', ActionItem.create(Material.NETHER_BRICK)
                                .action((p, clickType) -> p.teleport(Bukkit.getWorlds().get(1).getSpawnLocation()))
                                .name(ChatColor.RED + "Teleport to NETHER"))
                        .setKey('O', ActionItem.create(Material.SUNFLOWER)
                                .action((p, clickType) -> p.teleport(Bukkit.getWorlds().get(0).getSpawnLocation()))
                                .name(ChatColor.BLUE + "Teleport to OVERWORLD"))
                        .setKey('E', ActionItem.create(Material.END_STONE)
                                .action((p, clickType) -> p.teleport(Bukkit.getWorlds().get(2).getSpawnLocation()))
                                .name(ChatColor.DARK_GREEN + "Teleport to END"));

                // Or like this
                final Pattern teleportsPattern = teleports.createPattern();

                teleportsPattern.setRow(Row.FIRST,  "GBGBWBGBG");
                teleportsPattern.setRow(Row.SECOND, "GB  X  BG");
                teleportsPattern.setRow(Row.THIRD,  "GBGBWBGBG");

                teleportsPattern.setKey('G', Item.create(Material.GREEN_STAINED_GLASS_PANE).name(ChatColor.RED + "Border"));
                teleportsPattern.setKey('B', Item.create(Material.BLUE_STAINED_GLASS_PANE).name(ChatColor.WHITE + "Border"));
                teleportsPattern.setKey('W', Item.create(Material.WHITE_STAINED_GLASS_PANE).name(ChatColor.WHITE + "Border"));
                teleportsPattern.setKey('X', ActionItem.create(Material.COMPASS)
                        .action((p, clickType) -> p.teleport(p.getWorld().getSpawnLocation()))
                        .name(ChatColor.BLUE + "Teleport to the spawn")
                );

                worldSelector.applyPattern(worldSelectorPattern);
                teleports.applyPattern(teleportsPattern);

                /*
                    You can also add items without pattern
                    All items add manually should be add after applying the pattern
                    Or the pattern will override all the item added manually
                 */

                worldSelector.addItem(Row.THIRD, Column.NINTH, ActionItem.create(Material.HOPPER)
                        .action(((p, clickType) -> gui.nextPage(p)))
                        .name(ChatColor.AQUA + "Next page")
                );

                teleports.addItem(Row.THIRD, Column.FIRST, ActionItem.create(Material.HOPPER)
                        .action(((p, clickType) -> gui.previousPage(p)))
                        .name(ChatColor.AQUA + "Previous page")
                );

                gui.addPages(worldSelector, teleports);
            }

        }

        @Override
        public boolean onCommand(CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
            if (sender instanceof Player) {
                final Player player = (Player) sender;
                if (args.length == 0) {
                    manager.get("teleports").open(player);
                }
            }
            return true;
        }

    }
    Output:

    First page created (worldSelection)
    upload_2018-10-14_3-37-6.png
    • Netherbrick: Teleport to nether
    • Sunflower: Teleport to normal world
    • End stone: Teleport to the end
    • Hopper: Show the next page (in our case Teleports page)
    Second page create (teleports)
    upload_2018-10-14_3-40-38.png
    • Bed: Teleport to world spawn
    • Hopper: Show the previous page (in our case Worlds page)

    If you want to use it you can get the everything here : GitHub
    You can also use the doc available here : Javadoc

    If you have any suggestion do it !
     
    #1 FrozenLegend, Oct 14, 2018
    Last edited: Oct 22, 2018 at 9:36 PM
    • Like Like x 5
    • Useful Useful x 2
    • Creative Creative x 1
  2. Good job! Seems useful
     
    • Agree Agree x 1
  3. some suggestions, not serious things:

    • maybe add an individual implementation for 'showing' another page?
    maybe like:

    Code (Java):
    gui.appendPage(page);
    gui.setNextPageItem(item);
    then listen for clicks on that item, and return the next page to show.

    • some kind of builder pattern for action item, have it self build through a static method
    Code (Java):

    ActionItem.create()
         .item(new ItemStack(Material.DIAMOND));
         .action((player, clickType) -> player.sendMessage("hello"))
         .switch(new ItemStack(Material.COAL)); //just something i came up with, maybe the new item it gets replaced with, when clicked :P
     

    • LAMBDAS LAMBDAS LAMBDAS!
     
    • Like Like x 2
  4. iShadey

    iShadey Previously TrollStar12345

    I never actually thought about using string patterns in GUI creation, I will definitely be using parts of this resource! :)
     
  5. Maybe add the "put" method to Pattern Object for not using aditional map objects
     
  6. Thanks for your suggestions !

    Method for adding page is already available GUI#addPage(Page)
    and for showing the next/previous page (if existing) these methods are available GUI#nextPage() and GUI#previousPage()
    and for your setNextPageItem i don't know if i understand what you tell me but you just give an item as parameter and this item when clicked will call gui#nextPage() ?

    Gonna make a builder for the items it's more readable and add the switch method good idea !

    That's exactly what i was thinking when reading my code xd

    EDIT :
    - Add builder for Item and ActionItem
    - You can set the action using lambda
    - Pattern can now be chained for creating the pattern
    - Remove the Map for assigning items to pattern (now use Pattern#setKey instead)
    - Fixed GUI#nextPage()
     
    #6 FrozenLegend, Oct 14, 2018
    Last edited: Oct 14, 2018
    • Friendly Friendly x 1
  7. I've modified some things for optimization purpose (before this update every GUI was linked to one player so if you was using the same GUI for every players, like a teleport GUI this gui was created and stored for each players) so now :
    • You can create personal GUI (GUI used by only one player -> ex: GUI with some personal stats)
    • You can create common GUI (GUI who can be used by everyone -> ex: Teleport GUI)
    everything is done using GUIManager

    GUIManager#get(String) -> Create or get the existing CommonGUI using the GUI name as parameter
    GUIManager#get(String, Player) -> Create or get the existing PersonalGUI using the GUI name and player instance as parameter

    If you have any suggestion or idea tell me !
     
  8. Interesting, I hadn't thought about using constant index definitions like that.
     
  9. its not working for me the github
    [​IMG]
     
  10. Firestar311

    Supporter

    GitHub is having issues as it stands
     

Share This Page