{"id":16960995,"url":"https://github.com/cubbossa/menuframework","last_synced_at":"2025-08-26T23:36:24.917Z","repository":{"id":41066021,"uuid":"474394522","full_name":"CubBossa/MenuFramework","owner":"CubBossa","description":"A library to simply create Scoreboards, GUIs with inventorys and Hotbars","archived":false,"fork":false,"pushed_at":"2023-11-20T18:37:57.000Z","size":362,"stargazers_count":14,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-11T22:11:29.902Z","etag":null,"topics":["anvil","api","bukkit","gui","hotbar","inventory","java","menu","minecraft","paper","scoreboard","spigot","trader","villager"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CubBossa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-26T15:54:01.000Z","updated_at":"2024-06-08T19:05:02.000Z","dependencies_parsed_at":"2025-02-20T06:32:30.222Z","dependency_job_id":"bee4e845-9761-4af8-be5f-ab890046bd9f","html_url":"https://github.com/CubBossa/MenuFramework","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/CubBossa/MenuFramework","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CubBossa%2FMenuFramework","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CubBossa%2FMenuFramework/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CubBossa%2FMenuFramework/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CubBossa%2FMenuFramework/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CubBossa","download_url":"https://codeload.github.com/CubBossa/MenuFramework/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CubBossa%2FMenuFramework/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272267460,"owners_count":24903694,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-26T02:00:07.904Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anvil","api","bukkit","gui","hotbar","inventory","java","menu","minecraft","paper","scoreboard","spigot","trader","villager"],"created_at":"2024-10-13T22:50:44.643Z","updated_at":"2025-08-26T23:36:24.868Z","avatar_url":"https://github.com/CubBossa.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MenuFramework\n\n## Content\n\n- Usage\n  - Maven\n  - Setup\n- Skip Reading\n- Inventory Menus\n- Scoreboards\n- Chat Menus\n\n## Usage\n\n### Maven\n\nInstall the framework by adding jitpack as repository and the dependency below\nto your pom.xml.\n\n```XML\n\u003crepositories\u003e\n    \u003crepository\u003e\n        \u003cid\u003ejitpack.io\u003c/id\u003e\n        \u003curl\u003ehttps://jitpack.io\u003c/url\u003e\n    \u003c/repository\u003e\n\u003c/repositories\u003e\n\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.github.CubBossa.MenuFramework\u003c/groupId\u003e\n        \u003cartifactId\u003eMenuFramework\u003c/artifactId\u003e\n        \u003cversion\u003e[VERSION]\u003c/version\u003e\n    \u003c/dependency\u003e\n\n    \u003c!-- optional for anvil gui. Requires ProtocolLib on your server! --\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.github.CubBossa.MenuFramework\u003c/groupId\u003e\n        \u003cartifactId\u003eMenuFramework-Protocol-Extension\u003c/artifactId\u003e\n      \u003cversion\u003e[VERSION]\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\nThe Kyori Adventure API is required to use Minecraft-GUI-Framework.\nYou can shade both this library and adventure like so:\n\n```xml\n\u003cplugin\u003e\n    \u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n    \u003cartifactId\u003emaven-shade-plugin\u003c/artifactId\u003e\n    \u003cversion\u003e3.3.0-SNAPSHOT\u003c/version\u003e\n    \u003cexecutions\u003e\n        \u003cexecution\u003e\n            \u003cphase\u003epackage\u003c/phase\u003e\n            \u003cgoals\u003e\n                \u003cgoal\u003eshade\u003c/goal\u003e\n            \u003c/goals\u003e\n            \u003cconfiguration\u003e\n                \u003cartifactSet\u003e\n                    \u003cincludes\u003e\n                        \u003cinclude\u003enet.kyori:**\u003c/include\u003e\n                        \u003cinclude\u003ecom.github.CubBossa.MenuFramework:MenuFramework\u003c/include\u003e\n                        \u003cinclude\u003ecom.github.CubBossa.MenuFramework:MenuFramework-Protocol-Extension\u003c/include\u003e\n                        \u003cinclude\u003enet.wesjd:anvilgui\u003c/include\u003e\n                    \u003c/includes\u003e\n                \u003c/artifactSet\u003e\n                \u003crelocations\u003e\n                    \u003crelocation\u003e\n                        \u003cpattern\u003enet.kyori\u003c/pattern\u003e\n                        \u003cshadedPattern\u003e[YOUR_PLUGIN_PATH].kyori\u003c/shadedPattern\u003e\n                    \u003c/relocation\u003e\n                    \u003crelocation\u003e\n                        \u003cpattern\u003ede.cubbossa.menuframework\u003c/pattern\u003e\n                        \u003cshadedPattern\u003e[YOUR_PLUGIN_PATH].menuframework\u003c/shadedPattern\u003e\n                    \u003c/relocation\u003e\n                    \u003crelocation\u003e\n                        \u003cpattern\u003enet.wesjd.anvilgui\u003c/pattern\u003e\n                        \u003cshadedPattern\u003e[YOUR_PLUGIN_PATH].anvilgui\u003c/shadedPattern\u003e\n                    \u003c/relocation\u003e\n                \u003c/relocations\u003e\n            \u003c/configuration\u003e\n        \u003c/execution\u003e\n    \u003c/executions\u003e\n\u003c/plugin\u003e\n```\n\n### Setup\n\nTo get started, you have to initialize the GUIHandler class in your plugin onEnable method and \ndisable it in the onDisable method:\n\n```java\n    @Override\n    public void onEnable() {\n        GUIHandler guiHandler = new GUIHandler(this);\n        guiHandler.enable();\n        \n        // optional if used with protocol extension and ProtocolLib:\n        new ProtocolLibListener();\n    }\n\n    @Override\n    public void onDisable() {\n        GUIHandler.getInstance().disable();\n        \n        // optional if used with protocol extension and ProtocolLib:\n        ProtocolLibListener.getInstance().removePacketListener();\n    }\n```\n\n\n## Skip Reading\n\nIf you don't want to read the whole documentation but want to get started,\ncheck out the classes:\n- [Menu.java](https://github.com/CubBossa/MenuFramework/blob/master/MenuFramework/src/main/java/de/cubbossa/menuframework/inventory/Menu.java) for a method overview\n- [InventoryMenu.java](https://github.com/CubBossa/MenuFramework/blob/master/MenuFramework/src/main/java/de/cubbossa/menuframework/inventory/implementations/InventoryMenu.java) as basic menu implementation\n- [MenuPresets.java](https://github.com/CubBossa/MenuFramework/blob/master/MenuFramework/src/main/java/de/cubbossa/menuframework/inventory/MenuPresets.java) for predefined inventories and presets\n\n## Inventory Menus\n\n### Overview\n\nTo prevent programmers from creating every single GUI from scratch and dealing with endless Inventory Listeners, MCGUI Framework\nautomatically handles listening to bukkit events and calling your code.\n\nInventory Menus are defined by InventoryMenu objects. One InventoryMenu displays one paginated inventory, that can be shared by multiple players.\nKeep in mind, that every player sees the same changes in the inventory, so if you want to show items based on the user, create one InventoryMenu per player.\n\nInventory menus are divided into TopInventoryMenus and LayeredMenus.\nTopInventoryMenus are, as the name says, all menus that open on top of the player inventory (chest, merchant, hopper, furnace, anvil, ...).\nLayeredMenus are all menus, that are displayed in the players actual inventory.\n\nThere is one important difference between there types:\nThere can only ever be one TopInventoryMenu per player, while every player can have as much LayeredMenus opened as the admins want them to.\nTopInventoryMenus automatically close, when a new menu is opened, which is not the case for LayeredMenus.\n\nThis adds a special behaviour for closing TopInventoryMenus: If you provide a previous menu or open a menu as a sub menu, the parent menu will open\nautomatically, once the child menu has been closed. This allows programmers to create a hierarchy of menus that always leads back to the main menu.\nIf this behaviour is not required, simply open the new menu with its open method. If the \"previous\" parameter is set to null, all parent menus are cleared\nand no inventory will open when the menu is closed.\n\nLayeredMenus instead don't close if players close their inventories. LayeredMenus can cover any slots of the player inventory (first row, every second\nslot, etc...). If multiple LayeredMenus contain the same slot, the most recent added menu will be rendered and executed then clicked.\nHence, you always have to close LayeredMenus if you open them to restore the players original inventories and prevent item duping.\nLayeredMenus only close automatically if the player disconnects.\n\nExample for a TopInventoryMenu with multiple presets:\n```Java\npublic class Example {\n\n    public void openExampleMenu(Player player) {\n\n        // Creates a chest menu with 2 rows and the title Lobby Selector\n        ListMenu menu = MenuPresets.newListMenu(Component.text(\"Lobby Selector\"), 3,\n                    // LobbyHandler derives from ListMenuSupplier and can be displayed as list\n                    ServerHandler.getInstance(),\n                    // Action that triggers the call of the click handler\n                    Action.LEFT,\n                    // Will be called when a lobby icon is clicked. The targetContext contains the lobby as target\n                    targetContext -\u003e {\n                        ServerHandler.getInstance().connect(clickContext.getPlayer(), targetContext.getTarget());\n                    }  );\n\n        // Open the GUI for the given player\n        menu.open(player);\n    }\n}\n```\n\n### Pagination\n\nWhen inserting items and clickhandlers into the menu (e.g. `Menu#setItem(int, ItemStack)`), you can input\nevery slot you like. Since every inventory has a limited amount of slots, only items on those slots are being added\nto the menu inventory.\nButtons at higher or negative slots can be displayed by changing the current page.\nThe first index of each page can be calculated like so: `slots_per_page x current_page`\nTo change the rendered page, call `Menu#openPage(Player, int)`. This does not open the inventory, it only changes the\nitems in the menu inventory to the items for the provided page.\n\nThe MenuPresets class contains pagination presets that can be added with `Menu#addPreset(...)` and allow the menu users\nto turn pages via buttons.\n\nThe maximum page is the page that contains the item or click handler with the highest slot,\nthe minimum page is the page that contains the lowest slot.\n\n### Menu Presets\n\nSome inventory buttons are required many times, but always do the same thing. They also don't need to be static buttons\nthat have to be removed manually if not wanted anymore.\nTherefore, you can add MenuPresets to your menu. MenuPresets add items and click handlers are always added to the currently opened\npage if the slot is not already taken by a static button.\n\nThe MenuPresets class contains presets for filling inventory backgrounds, adding rows, adding pagination items and back items.\nYou can create own MenuPresets by implementing the MenuPreset interface. Use the provided functions of the interface to add\nitems and click handlers dynamically. If you call `Menu#setItem(int, ItemStack)` in the MenuPreset, you would add a static\nitem, which is not what MenuPresets are expected to do.\nStill, the interface method holds a reference to the menu, so that you can refresh the menu or change pages if necessary.\n\nExample MenuPreset that dynamically fills the background of the menu with the provided ItemStack.\n```Java\n    public static MenuPreset\u003c? extends TargetContext\u003c?\u003e\u003e fill(ItemStack stack) {\n        return (menu, addItem, addClickHandler) -\u003e {\n            Arrays.stream(menu.getSlots()).forEach(value -\u003e addItem.accept(value, stack));\n        };\n    }\n```\n\n### Default ClickHandler\n\n### Default Cancelling\n\n### CloseHandler\n\n\n### Animations\n\n## Scoreboards\n\n### Overview\n\nCustomScoreboards provide simplified methods to display sidebars in Minecraft.\nCustomScoreboards are structured in a stack, so hiding a scoreboard will reveal the CustomScoreboard that was visible before.\nThis only accounts for CustomScoreboard from this framework and if the scoreboard hasn't been hidden from the player before.\n\n```Java\npublic class Example {\n    public void showScoreboard(Player player) {\n    // New Scoreboard with lobby as key, the name of the lobby as name and 5 lines. Store this instance to toggle and update the scoreboard lateron.\n\tCustomScoreboard scoreboard = new CustomScoreboard(\"lobby\", ServerHandler.getInstance().getCurrentServer().getDisplayName(), 5);\n\n    // Static entry in line 2 -\u003e won't update\n\tscoreboard.setLine(2, Component.text(\"Jump'n'Run Score:\"));\n\t// Dynamic entry in line 3 -\u003e can be updated, e.g. in a JumpNRun Listener to refresh the high score\n\tscoreboard.setLine(3, () -\u003e Component.text(JumpNRunHandler.getInstance().getFormattedHighScore(player)));\n\n    // Show the scoreboard instance to the player\n\tscoreboard.show(player);\n    }\n}\n```\n\n## Chat Menus\n\n### Overview\n\nChat menus provide a simple way to display many information in chat, scoreboards and item lores.\nThey are basically lists with indents. Therefore, they use a parent child structure, so that you can add multiple child menus to each chat menu object.\nEvery ChatMenu object can be rendered and will use all child menus to create the Component List to use in Chat.\n\nCode:\n```Java\n        TextMenu online = new TextMenu(\"Spieler online:\");\n        Bukkit.getOnlinePlayers().forEach(p -\u003e online.addSub(new ComponentMenu(p.displayName())));\n        online.send(player);\n```\nResult:\n```\n        Spieler online:\n         \u003e  CubBossa\n         \u003e  Steve\n         \u003e  Alex\n```\n\n### Types\n\nThere are three predefined ChatMenu types: TextMenu, ComponentMenu and ItemMenu.\n- TextMenu simply renders a string, that can contain legacy formatting.\n- ComponentMenu can be instantiated with a Component like the players display name.\n- ItemMenu uses the display name or translation key of an item stack and adds the item meta as lore.\n\nTo implement own ChatMenu types, simply derive from ChatMenu and use the class as generic type that is supposed to be\nconverted to a menu entry.\n\nTo change the way menus are rendered, you can change the static INDENT_COMPONENT component in the ChatMenu class.\nIt will be added before each indented sub menu.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcubbossa%2Fmenuframework","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcubbossa%2Fmenuframework","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcubbossa%2Fmenuframework/lists"}