├── .github
└── FUNDING.yml
├── settings.gradle.kts
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── core
├── build.gradle.kts
└── src
│ └── main
│ └── java
│ └── net
│ └── j4c0b3y
│ └── api
│ └── menu
│ ├── utils
│ ├── TriFunction.java
│ └── Position.java
│ ├── annotation
│ ├── Async.java
│ └── AutoUpdate.java
│ ├── template
│ └── Template.java
│ ├── button
│ ├── Button.java
│ ├── impl
│ │ └── SimpleButton.java
│ └── ButtonClick.java
│ ├── task
│ └── AutoUpdateTask.java
│ ├── layer
│ ├── impl
│ │ ├── ForegroundLayer.java
│ │ └── BackgroundLayer.java
│ └── Layer.java
│ ├── MenuSize.java
│ ├── listener
│ └── InventoryListener.java
│ ├── pagination
│ ├── PaginationSlot.java
│ └── PaginatedMenu.java
│ ├── MenuHandler.java
│ └── Menu.java
├── .idea
├── vcs.xml
├── .gitignore
├── misc.xml
├── modules
│ └── MenuAPI.main.iml
└── runConfigurations
│ ├── Clean_MenuAPI.xml
│ ├── Publish_MenuAPI.xml
│ └── Build_MenuAPI.xml
├── .gitignore
├── extras
├── build.gradle.kts
└── src
│ └── main
│ └── java
│ └── net
│ └── j4c0b3y
│ └── api
│ └── menu
│ ├── MenuExtras.java
│ ├── button
│ └── impl
│ │ ├── pagination
│ │ ├── NextPageButton.java
│ │ ├── PreviousPageButton.java
│ │ └── SwitchPageButton.java
│ │ ├── PlaceholderButton.java
│ │ └── BackButton.java
│ ├── template
│ └── impl
│ │ ├── FillTemplate.java
│ │ ├── BorderTemplate.java
│ │ └── PaginationTemplate.java
│ ├── impl
│ └── selectpage
│ │ ├── button
│ │ └── SelectPageButton.java
│ │ └── SelectPageMenu.java
│ └── utils
│ └── Item.java
├── LICENSE.md
├── gradlew.bat
├── gradlew
└── README.md
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | custom: https://donate.j4c0b3y.net
2 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "MenuAPI"
2 | include("core", "extras")
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/J4C0B3Y/MenuAPI/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/core/build.gradle.kts:
--------------------------------------------------------------------------------
1 | repositories {
2 | maven("https://repo.codemc.io/repository/nms/")
3 | }
4 |
5 | dependencies {
6 | compileOnly("org.spigotmc:spigot:1.8.8-R0.1-SNAPSHOT")
7 | }
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 |
3 | !.gitignore
4 |
5 | !vcs.xml
6 | !encodings.xml
7 | !codeStyleSettings.xml
8 | !misc.xml
9 |
10 | !runConfigurations
11 | !runConfigurations/*
12 |
13 | !modules
14 | !modules/*
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | build/
3 | !gradle/wrapper/gradle-wrapper.jar
4 | !**/src/main/**/build/
5 | !**/src/test/**/build/
6 | gradle.properties
7 | jars/
8 |
9 | *.iws
10 | *.iml
11 | *.ipr
12 | out/
13 | !**/src/main/**/out/
14 | !**/src/test/**/out/
15 |
16 |
--------------------------------------------------------------------------------
/extras/build.gradle.kts:
--------------------------------------------------------------------------------
1 | repositories {
2 | maven("https://repo.codemc.io/repository/nms/")
3 | }
4 |
5 | dependencies {
6 | compileOnly(project(":core"))
7 | compileOnly("org.spigotmc:spigot:1.8.8-R0.1-SNAPSHOT")
8 | implementation("com.github.cryptomorin:XSeries:13.4.0")
9 | }
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat May 04 01:11:13 AEST 2024
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/menu/utils/TriFunction.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.utils;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version MenuAPI
6 | * @since 7/08/2025
7 | */
8 | @FunctionalInterface
9 | public interface TriFunction {
10 | R apply(F first, S second, T third);
11 | }
12 |
--------------------------------------------------------------------------------
/extras/src/main/java/net/j4c0b3y/api/menu/MenuExtras.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu;
2 |
3 | import org.bukkit.ChatColor;
4 |
5 | /**
6 | * @author J4C0B3Y
7 | * @version MenuAPI
8 | * @since 4/10/2025
9 | */
10 | public class MenuExtras {
11 | public static ChatColor THEME = ChatColor.LIGHT_PURPLE;
12 | public static boolean PAGE_SELECT = true;
13 | }
14 |
--------------------------------------------------------------------------------
/.idea/modules/MenuAPI.main.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | SPIGOT
8 |
9 | 1
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/extras/src/main/java/net/j4c0b3y/api/menu/button/impl/pagination/NextPageButton.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.button.impl.pagination;
2 |
3 | import net.j4c0b3y.api.menu.pagination.PaginatedMenu;
4 |
5 | /**
6 | * @author J4C0B3Y
7 | * @version MenuAPI
8 | * @since 4/10/2025
9 | */
10 | public class NextPageButton extends SwitchPageButton {
11 |
12 | public NextPageButton(PaginatedMenu menu) {
13 | super("Next", menu::hasNextPage, menu::nextPage, menu);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/extras/src/main/java/net/j4c0b3y/api/menu/button/impl/pagination/PreviousPageButton.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.button.impl.pagination;
2 |
3 | import net.j4c0b3y.api.menu.pagination.PaginatedMenu;
4 |
5 | /**
6 | * @author J4C0B3Y
7 | * @version MenuAPI
8 | * @since 4/10/2025
9 | */
10 | public class PreviousPageButton extends SwitchPageButton {
11 |
12 | public PreviousPageButton(PaginatedMenu menu) {
13 | super("Previous", menu::hasPreviousPage, menu::nextPage, menu);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/menu/annotation/Async.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Marks the menu as asynchronous.
10 | *
11 | * @author J4C0B3Y
12 | * @version MenuAPI
13 | * @since 22/05/2024
14 | */
15 | @Target(ElementType.TYPE)
16 | @Retention(RetentionPolicy.RUNTIME)
17 | public @interface Async {
18 | }
19 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/menu/utils/Position.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.utils;
2 |
3 | import lombok.Getter;
4 | import lombok.RequiredArgsConstructor;
5 |
6 | /**
7 | * Represents a 2d position with an x and y coordinate.
8 | *
9 | * @author J4C0B3Y
10 | * @version MenuAPI
11 | * @since 12/05/2024
12 | */
13 | @Getter
14 | @RequiredArgsConstructor
15 | public class Position {
16 | /**
17 | * The x coordinate.
18 | */
19 | private final int x;
20 |
21 | /**
22 | * The y coordinate.
23 | */
24 | private final int y;
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/menu/template/Template.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.template;
2 |
3 | import net.j4c0b3y.api.menu.layer.impl.BackgroundLayer;
4 | import net.j4c0b3y.api.menu.layer.impl.ForegroundLayer;
5 |
6 | /**
7 | * Used to apply a reusable design preset to a menus layers.
8 | *
9 | * @author J4C0B3Y
10 | * @version MenuAPI
11 | * @since 12/05/2024
12 | */
13 | public interface Template {
14 | /**
15 | * Applies a design to a menu.
16 | *
17 | * @param background The menu's background layer.
18 | * @param foreground The menu's foreground layer.
19 | */
20 | void apply(BackgroundLayer background, ForegroundLayer foreground);
21 | }
22 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/menu/annotation/AutoUpdate.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Marks the menu for auto updating
10 | * using the specified tick interval.
11 | *
12 | * @author J4C0B3Y
13 | * @version MenuAPI
14 | * @since 12/05/2024
15 | */
16 | @Target(ElementType.TYPE)
17 | @Retention(RetentionPolicy.RUNTIME)
18 | public @interface AutoUpdate {
19 | /**
20 | * The interval in ticks to auto update the menu.
21 | *
22 | * @return The auto update ticks.
23 | */
24 | int value();
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/menu/button/Button.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.button;
2 |
3 | import org.bukkit.inventory.ItemStack;
4 |
5 | /**
6 | * A menu button, used to display an icon
7 | * and a click handler for the inventory item.
8 | *
9 | * @author J4C0B3Y
10 | * @version MenuAPI
11 | * @since 12/05/2024
12 | */
13 | public abstract class Button {
14 | /**
15 | * Gets the button's display item stack, this can
16 | * be null if the button should not be displayed.
17 | *
18 | * @return The buttons icon.
19 | */
20 | public abstract ItemStack getIcon();
21 |
22 | /**
23 | * Called when the button is clicked,
24 | * this can be ignored by the onClick
25 | * handler in the button's menu.
26 | *
27 | * @param click The button click.
28 | */
29 | public void onClick(ButtonClick click) { }
30 | }
31 |
--------------------------------------------------------------------------------
/extras/src/main/java/net/j4c0b3y/api/menu/button/impl/PlaceholderButton.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.button.impl;
2 |
3 | import com.cryptomorin.xseries.XMaterial;
4 | import net.j4c0b3y.api.menu.button.Button;
5 | import net.j4c0b3y.api.menu.utils.Item;
6 | import org.bukkit.ChatColor;
7 | import org.bukkit.inventory.ItemStack;
8 |
9 | /**
10 | * @author J4C0B3Y
11 | * @version MenuAPI
12 | * @since 4/10/2025
13 | */
14 | public class PlaceholderButton extends Button {
15 | private final ItemStack icon;
16 |
17 | public PlaceholderButton(XMaterial material) {
18 | this.icon = new Item(material)
19 | .setName(ChatColor.RESET.toString())
20 | .build();
21 | }
22 |
23 | public PlaceholderButton() {
24 | this(XMaterial.GRAY_STAINED_GLASS_PANE);
25 | }
26 |
27 | @Override
28 | public ItemStack getIcon() {
29 | return icon;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/Clean_MenuAPI.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
16 |
17 |
18 | true
19 | true
20 | false
21 | false
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/Publish_MenuAPI.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | true
19 | true
20 | false
21 | false
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/Build_MenuAPI.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | true
20 | true
21 | false
22 | false
23 |
24 |
25 |
--------------------------------------------------------------------------------
/extras/src/main/java/net/j4c0b3y/api/menu/template/impl/FillTemplate.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.template.impl;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.RequiredArgsConstructor;
5 | import net.j4c0b3y.api.menu.Menu;
6 | import net.j4c0b3y.api.menu.button.Button;
7 | import net.j4c0b3y.api.menu.button.impl.BackButton;
8 | import net.j4c0b3y.api.menu.button.impl.PlaceholderButton;
9 | import net.j4c0b3y.api.menu.layer.impl.BackgroundLayer;
10 | import net.j4c0b3y.api.menu.layer.impl.ForegroundLayer;
11 | import net.j4c0b3y.api.menu.template.Template;
12 |
13 | /**
14 | * @author J4C0B3Y
15 | * @version MenuAPI
16 | * @since 4/10/2025
17 | */
18 | @AllArgsConstructor
19 | @RequiredArgsConstructor
20 | public class FillTemplate implements Template {
21 | private final Menu menu;
22 | private Button background;
23 |
24 | @Override
25 | public void apply(BackgroundLayer background, ForegroundLayer foreground) {
26 | background.fill(this.background != null ? this.background : new PlaceholderButton());
27 | foreground.set(0, new BackButton(this.menu));
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024-Present J4C0B3Y
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/extras/src/main/java/net/j4c0b3y/api/menu/template/impl/BorderTemplate.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.template.impl;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.RequiredArgsConstructor;
5 | import net.j4c0b3y.api.menu.Menu;
6 | import net.j4c0b3y.api.menu.button.Button;
7 | import net.j4c0b3y.api.menu.button.impl.BackButton;
8 | import net.j4c0b3y.api.menu.button.impl.PlaceholderButton;
9 | import net.j4c0b3y.api.menu.layer.impl.BackgroundLayer;
10 | import net.j4c0b3y.api.menu.layer.impl.ForegroundLayer;
11 | import net.j4c0b3y.api.menu.template.Template;
12 |
13 | /**
14 | * @author J4C0B3Y
15 | * @version MenuAPI
16 | * @since 4/10/2025
17 | */
18 | @AllArgsConstructor
19 | @RequiredArgsConstructor
20 | public class BorderTemplate implements Template {
21 | private final Menu menu;
22 | private Button background;
23 |
24 | @Override
25 | public void apply(BackgroundLayer background, ForegroundLayer foreground) {
26 | background.border(new PlaceholderButton());
27 |
28 | if (this.background != null) {
29 | background.center(this.background);
30 | }
31 |
32 | foreground.set(0, new BackButton(this.menu));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/extras/src/main/java/net/j4c0b3y/api/menu/button/impl/BackButton.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.button.impl;
2 |
3 | import com.cryptomorin.xseries.XMaterial;
4 | import lombok.RequiredArgsConstructor;
5 | import net.j4c0b3y.api.menu.Menu;
6 | import net.j4c0b3y.api.menu.MenuExtras;
7 | import net.j4c0b3y.api.menu.button.Button;
8 | import net.j4c0b3y.api.menu.button.ButtonClick;
9 | import net.j4c0b3y.api.menu.utils.Item;
10 | import org.bukkit.inventory.ItemStack;
11 |
12 | /**
13 | * @author J4C0B3Y
14 | * @version MenuAPI
15 | * @since 4/10/2025
16 | */
17 | @RequiredArgsConstructor
18 | public class BackButton extends Button {
19 | private final Menu menu;
20 |
21 | @Override
22 | public ItemStack getIcon() {
23 | if (!this.menu.hasPreviousMenu()) return null;
24 |
25 | return new Item(XMaterial.RED_BED)
26 | .setName(MenuExtras.THEME + "&lBack")
27 | .addLore(
28 | "",
29 | "&7Return to the previous menu",
30 | "",
31 | MenuExtras.THEME + "Go Back &7(Left Click)"
32 | ).build();
33 | }
34 |
35 | @Override
36 | public void onClick(ButtonClick click) {
37 | if (click.getType().isLeftClick()) {
38 | menu.back();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/menu/task/AutoUpdateTask.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.task;
2 |
3 | import lombok.Getter;
4 | import lombok.RequiredArgsConstructor;
5 | import net.j4c0b3y.api.menu.Menu;
6 | import net.j4c0b3y.api.menu.MenuHandler;
7 | import net.j4c0b3y.api.menu.annotation.AutoUpdate;
8 |
9 | /**
10 | * Used to automatically update menus annotated with @AutoUpdate
11 | *
12 | * @author J4C0B3Y
13 | * @version MenuAPI
14 | * @since 12/05/2024
15 | */
16 | @RequiredArgsConstructor
17 | public class AutoUpdateTask implements Runnable {
18 | /**
19 | * The menu handler.
20 | */
21 | private final MenuHandler handler;
22 |
23 | /**
24 | * The tick time since the task started.
25 | */
26 | @Getter private long ticks = 0;
27 |
28 | /**
29 | * Loops through all open menus that is annotated with
30 | * AutoUpdate and updates them if the ticks since the
31 | * last update matches the value of the annotation.
32 | */
33 | @Override
34 | public void run() {
35 | for (Menu menu : handler.getOpenMenus().values()) {
36 | AutoUpdate annotation = menu.getClass().getAnnotation(AutoUpdate.class);
37 |
38 | if (annotation != null && ticks - menu.getLastUpdate() >= annotation.value()) {
39 | menu.update();
40 | }
41 | }
42 |
43 | ticks++;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/menu/layer/impl/ForegroundLayer.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.layer.impl;
2 |
3 | import net.j4c0b3y.api.menu.Menu;
4 | import net.j4c0b3y.api.menu.button.Button;
5 | import net.j4c0b3y.api.menu.layer.Layer;
6 |
7 | import java.util.TreeMap;
8 |
9 | /**
10 | * Represents a foreground layer in a menu with
11 | * many methods to manipulate the layer's content.
12 | *
13 | * @author J4C0B3Y
14 | * @version MenuAPI
15 | * @since 12/05/2024
16 | */
17 | public class ForegroundLayer extends Layer {
18 |
19 | /**
20 | * Creates a new foreground layer.
21 | *
22 | * @param menu The menu the layer belongs to.
23 | */
24 | public ForegroundLayer(Menu menu) {
25 | super(menu, new TreeMap<>());
26 | }
27 |
28 | /**
29 | * Returns the name of the foreground layer.
30 | *
31 | * @return The foreground layer name.
32 | */
33 | @Override
34 | public String getName() {
35 | return "foreground";
36 | }
37 |
38 | /**
39 | * Adds a button to the next available slot,
40 | * checking slots in the background layer as well.
41 | *
42 | * @param button The button to add.
43 | * @param other If the background layer should be checked.
44 | */
45 | @Override
46 | public void add(Button button, boolean other) {
47 | add(button, other ? getMenu().getBackground() : null);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/menu/MenuSize.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu;
2 |
3 | import lombok.Getter;
4 | import lombok.RequiredArgsConstructor;
5 |
6 | /**
7 | * The possible sizes for a bukkit inventory.
8 | *
9 | * @author J4C0B3Y
10 | * @version MenuAPI
11 | * @since 12/05/2024
12 | */
13 | @Getter
14 | @RequiredArgsConstructor
15 | public enum MenuSize {
16 | /**
17 | * A menu with three rows.
18 | */
19 | THREE(3),
20 |
21 | /**
22 | * A menu with four rows.
23 | */
24 | FOUR(4),
25 |
26 | /**
27 | * A menu with five rows.
28 | */
29 | FIVE(5),
30 |
31 | /**
32 | * A menu with six rows.
33 | */
34 | SIX(6);
35 |
36 | /**
37 | * How many rows the menu has.
38 | */
39 | private final int rows;
40 |
41 | /**
42 | * Returns the menu size using the input number,
43 | * which can be either the amount of rows or slots.
44 | *
45 | * @param input The rows or slots.
46 | * @return The associated menu size.
47 | */
48 | public static MenuSize of(int input) {
49 | for (MenuSize size : MenuSize.values()) {
50 | int rows = size.getRows();
51 |
52 | if (rows == input || rows == input * Menu.COLUMNS) {
53 | return size;
54 | }
55 | }
56 |
57 | throw new IllegalArgumentException("There is no menu size with " + input + " rows or slots!");
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/extras/src/main/java/net/j4c0b3y/api/menu/template/impl/PaginationTemplate.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.template.impl;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.RequiredArgsConstructor;
5 | import net.j4c0b3y.api.menu.Menu;
6 | import net.j4c0b3y.api.menu.button.Button;
7 | import net.j4c0b3y.api.menu.button.impl.pagination.NextPageButton;
8 | import net.j4c0b3y.api.menu.button.impl.pagination.PreviousPageButton;
9 | import net.j4c0b3y.api.menu.layer.impl.BackgroundLayer;
10 | import net.j4c0b3y.api.menu.layer.impl.ForegroundLayer;
11 | import net.j4c0b3y.api.menu.pagination.PaginatedMenu;
12 | import net.j4c0b3y.api.menu.pagination.PaginationSlot;
13 | import net.j4c0b3y.api.menu.template.Template;
14 |
15 | /**
16 | * @author J4C0B3Y
17 | * @version MenuAPI
18 | * @since 4/10/2025
19 | */
20 | @AllArgsConstructor
21 | @RequiredArgsConstructor
22 | public class PaginationTemplate implements Template {
23 | private final PaginatedMenu menu;
24 | private Button background;
25 |
26 | @Override
27 | public void apply(BackgroundLayer background, ForegroundLayer foreground) {
28 | new BorderTemplate(this.menu, this.background).apply(background, foreground);
29 |
30 | foreground.center(new PaginationSlot(this.menu));
31 |
32 | foreground.set(0, this.menu.getRows() - 1, new PreviousPageButton(this.menu));
33 | foreground.set(Menu.COLUMNS, this.menu.getRows() - 1, new NextPageButton(this.menu));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/extras/src/main/java/net/j4c0b3y/api/menu/impl/selectpage/button/SelectPageButton.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.impl.selectpage.button;
2 |
3 | import com.cryptomorin.xseries.XMaterial;
4 | import lombok.RequiredArgsConstructor;
5 | import net.j4c0b3y.api.menu.MenuExtras;
6 | import net.j4c0b3y.api.menu.button.Button;
7 | import net.j4c0b3y.api.menu.button.ButtonClick;
8 | import net.j4c0b3y.api.menu.impl.selectpage.SelectPageMenu;
9 | import net.j4c0b3y.api.menu.utils.Item;
10 | import org.bukkit.event.inventory.ClickType;
11 | import org.bukkit.inventory.ItemStack;
12 |
13 | /**
14 | * @author J4C0B3Y
15 | * @version MenuAPI
16 | * @since 4/10/2025
17 | */
18 | @RequiredArgsConstructor
19 | public class SelectPageButton extends Button {
20 | private final int page;
21 | private final SelectPageMenu menu;
22 |
23 | @Override
24 | public ItemStack getIcon() {
25 | boolean current = this.page == this.menu.getPaginatedMenu().getPage();
26 |
27 | return new Item(current ? XMaterial.ENCHANTED_BOOK : XMaterial.BOOK)
28 | .setName(MenuExtras.THEME + "&lPage" + this.page + (current ? "&7(Selected)" : ""))
29 | .addLore("", MenuExtras.THEME + "Select Page " + this.page + " &7(Left Click)")
30 | .build();
31 | }
32 |
33 | @Override
34 | public void onClick(ButtonClick click) {
35 | if (click.getType() != ClickType.LEFT) return;
36 |
37 | this.menu.getPaginatedMenu().setPage(this.page);
38 | this.menu.back();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/extras/src/main/java/net/j4c0b3y/api/menu/impl/selectpage/SelectPageMenu.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.menu.impl.selectpage;
2 |
3 | import lombok.Getter;
4 | import net.j4c0b3y.api.menu.MenuSize;
5 | import net.j4c0b3y.api.menu.button.Button;
6 | import net.j4c0b3y.api.menu.impl.selectpage.button.SelectPageButton;
7 | import net.j4c0b3y.api.menu.layer.impl.BackgroundLayer;
8 | import net.j4c0b3y.api.menu.layer.impl.ForegroundLayer;
9 | import net.j4c0b3y.api.menu.pagination.PaginatedMenu;
10 | import net.j4c0b3y.api.menu.template.impl.PaginationTemplate;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | /**
16 | * @author J4C0B3Y
17 | * @version MenuAPI
18 | * @since 4/10/2025
19 | */
20 | @Getter
21 | public class SelectPageMenu extends PaginatedMenu {
22 | private final PaginatedMenu paginatedMenu;
23 |
24 | public SelectPageMenu(PaginatedMenu menu) {
25 | super("Select Page", MenuSize.FOUR, menu.getPlayer());
26 | this.paginatedMenu = menu;
27 |
28 | setPreviousMenu(menu);
29 | }
30 |
31 | @Override
32 | public void setup(BackgroundLayer background, ForegroundLayer foreground) {
33 | apply(new PaginationTemplate(this));
34 | }
35 |
36 | @Override
37 | public List