Skip to content

Commit

Permalink
Significantly changed the menu creation mechanism.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rubix327 committed May 29, 2022
1 parent 5fd1334 commit 7700a04
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 66 deletions.
112 changes: 74 additions & 38 deletions src/main/java/org/mineacademy/fo/menu/AdvancedMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,14 @@
* Basic advanced menu.
* Supports adding items, buttons and filling locked slots with wrapper item.
* Also contains some ready buttons (Menu, ReturnBack, Refresh, etc.).<br><br>
* DO NOT FORGET to add {@link #init()} method in the end of the constructor
* if you make any changes in your menu (like setting the locked slots or adding new buttons).
* To get started, override {@link #setup} method and customize your menu inside it.
*/
public abstract class AdvancedMenu extends Menu {

/**
* The player watching the menu.
*/
private final Player player;
/**
* The menu which is opened from {@link #getReturnBackButton}.
*/
@Getter
private final Class<? extends AdvancedMenu> parentMenu;
/**
* Contains buttons and their slots.
*/
Expand All @@ -61,6 +55,10 @@ public abstract class AdvancedMenu extends Menu {
*/
@Getter
protected List<Integer> lockedSlots = new ArrayList<>();
/**
* The menu which is opened from {@link #getReturnBackButton}.
*/
private Class<? extends AdvancedMenu> parentMenu = getClass();
/**
* The material of the wrapper item.
* See {@link #wrapperItem} for more info.
Expand All @@ -78,16 +76,12 @@ public abstract class AdvancedMenu extends Menu {
private ItemStack wrapperItem = ItemCreator.of(wrapperMaterial, "").build().make();

public AdvancedMenu(Player player){
this(player, null);
}

public AdvancedMenu(Player player, Class<? extends AdvancedMenu> parent){
this.player = player;
this.parentMenu = (parent == null ? getClass() : parent);
}

/**
* Add button to the menu.
* Add button to the menu.<br>
* <b>Use it only inside {@link #setup} method to avoid errors!</b><br>
* @param slot the slot the button should be displayed on
* @param btn the button
*/
Expand All @@ -96,7 +90,8 @@ protected void addButton(Integer slot, Button btn){
}

/**
* Add custom item with no behavior to the menu.
* Add custom item with no behavior to the menu.<br>
* <b>Use it only inside {@link #setup} method to avoid errors!</b><br>
* If you want item to have behavior use {@link #addButton}.
* @param slot the slot the item should be placed on
* @param item the item
Expand All @@ -105,18 +100,10 @@ protected void addItem(Integer slot, ItemStack item){
items.put(slot, item);
}

/**
* Actions to be taken when opening or updating the menu.<br>
* It automatically runs when the menu opens. But if you make some changes after calling super()
* in your child class you must call init() manually in the constructor after all changes.
*/
protected void init(){}

/**
* Redraw the menu without moving the cursor to the center.
*/
protected void refreshMenu(){
init();
redraw();
}

Expand All @@ -127,10 +114,25 @@ public final Player getPlayer(){
return this.player;
}

/**
* Get the {@link #parentMenu}.
*/
protected final Class<? extends AdvancedMenu> getParentMenu(){
return this.parentMenu;
}

/**
* Set the {@link #parentMenu}.
*/
protected final void setParent(Class<? extends AdvancedMenu> parent){
this.parentMenu = parent;
}

/**
* Display this menu to the player given in the constructor.
*/
public final void display(){
public void display(){
setup();
displayTo(getPlayer());
}

Expand All @@ -145,7 +147,9 @@ protected Button getReturnBackButton(){
/**
* Get the button that returns player to the parent menu given in the constructor.
* If the parent is not given it will return player to the same menu.
* If item is not given, it will get its item from {@link MenuUtil#defaultReturnBackItem}.<br>
* If item is not given, it will get its item from {@link MenuUtil#defaultReturnBackItem}.<br><br>
* <b>NOTE</b> that this button returns player to the non-personalized menu.
* To use personalized menus, use {@link #getMenuButton}.<br><br>
* You can override this button and add some your logic.
* @return the return button
*/
Expand Down Expand Up @@ -194,15 +198,49 @@ public ItemStack getItem() {
}

/**
* Does the same as {@link #getMenuButton(ItemStack, Class)}.
* <b>Attention! Please use {@link #getMenuButton(Class)} if possible because it is much more efficient!
* Use this method only if your menu constructor is custom or the menu must be created by instance
* (and not by class).</b><br><br>
* Does the same as {@link #getMenuButton(ItemStack, AdvancedMenu)}.
* Uses the default button from {@link MenuUtil#defaultMenuItem}.
*/
protected Button getMenuButton(AdvancedMenu to){
return getMenuButton(MenuUtil.defaultMenuItem, to);
}

/**
* <b>Attention! Please use {@link #getMenuButton(ItemStack, Class)} if possible because it is much more efficient!
* Use this method only if your menu constructor is custom or the menu must be created by instance
* (and not by class).</b><br><br>
* Create a new button which opens a given menu instance.
* @param item how the button should look like
* @param to what menu the player should be sent to
* @return the button
*/
protected Button getMenuButton(ItemStack item, AdvancedMenu to){
return new Button() {
@Override
public void onClickedInMenu(Player player, AdvancedMenu menu, ClickType click) {
to.display();
}

@Override
public ItemStack getItem() {
return item;
}
};
}

/**
* Does the same as {@link #getMenuButton(ItemStack, Class)}.
* Uses default item from {@link MenuUtil#defaultMenuItem}.
*/
protected Button getMenuButton(Class<? extends AdvancedMenu> to){
return getMenuButton(MenuUtil.defaultMenuItem, to);
}

/**
* Get the button that displays new menu to the player.
* Create a new button which opens a new menu instance created from a given class.
* @param item how the button should look like
* @param to what menu the player should be sent to
* @return the button
Expand All @@ -226,15 +264,12 @@ public ItemStack getItem() {
*/
private AdvancedMenu newInstanceOf(Player player, Class<? extends AdvancedMenu> menu){
try{
return menu.getDeclaredConstructor(Player.class).newInstance(player);
AdvancedMenu am = menu.getDeclaredConstructor(Player.class).newInstance(player);
am.setParent(menu);
return am;
}
catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e){
try{
return menu.getDeclaredConstructor(Player.class, Class.class).newInstance(player, null);
}
catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e1){
e1.printStackTrace();
}
e.printStackTrace();
}
throw new NullPointerException("Could not create a new instance of " + menu.getName() + " class. " +
"Please create a constructor with only Player argument.");
Expand Down Expand Up @@ -382,18 +417,19 @@ protected final void setLockedSlots(String figure){
}
}

@Override
protected void onButtonClick(Player player, int slot, InventoryAction action, ClickType click, Button button) {
super.onButtonClick(player, slot, action, click, button);
}

@Override
protected void onMenuClick(Player player, int slot, InventoryAction action, ClickType click, ItemStack cursor, ItemStack clicked, boolean cancelled) {
if (getButtons().containsKey(slot)){
getButtons().get(slot).onClickedInMenu(player, this, click);
}
}

/**
* Override this method and customize your menu here.
* This method is automatically started just before displaying a menu to a player.
*/
protected void setup(){}

@Override
public ItemStack getItemAt(int slot) {
if (getItems().containsKey(slot)){
Expand Down
45 changes: 25 additions & 20 deletions src/main/java/org/mineacademy/fo/menu/AdvancedMenuPagged.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,9 @@
/**
* Menu with pages.<br>
* Supports previous and next buttons.<br><br>
* DO NOT FORGET to add {@link #init()} method in the end of the constructor
* if you make any changes in your menu (like setting the locked slots or adding new buttons).
* To get started, override {@link #setup} method and customize your menu inside it.
*/
public abstract class AdvancedMenuPagged<T> extends AdvancedMenu {
/**
* Shows if the constructor of MenuPaginated was initialized at least once.
*/
private final boolean isInitialized;

/**
* Slots and their raw {@link #elements}.
*/
Expand Down Expand Up @@ -76,27 +70,19 @@ public abstract class AdvancedMenuPagged<T> extends AdvancedMenu {
private ItemStack nextButtonItem = ItemCreator.of(CompMaterial.TIPPED_ARROW, "&7Next page").build().make();

public AdvancedMenuPagged(Player player){
this(player, null);
}

public AdvancedMenuPagged(Player player, Class<? extends AdvancedMenu> parent){
super(player, parent);
init();
isInitialized = true;
super(player);
}

/**
* Actions to be taken when opening or updating the menu.<br>
* It automatically runs when the menu opens. But if you make some changes after calling super()
* in your child class you must call init() manually in the constructor after all changes.
* Updating paged menu elements.<br>
* It automatically runs when the menu opens.
*/
@Override
protected void init(){
private void updateElements(){
resetCursorAt();
setElements();
setElementsItems();
setElementsSlots();
if (isInitialized) addPrevNextButtons(getPreviousButtonSlot(), getNextButtonSlot());
addPrevNextButtons(getPreviousButtonSlot(), getNextButtonSlot());
}

/**
Expand Down Expand Up @@ -244,6 +230,25 @@ private void resetCursorAt() {
this.cursorAt = (currentPage - 1) * getAvailableSlotsSize();
}

/**
* Redraw the menu without moving the cursor to the center.
*/
@Override
protected void refreshMenu(){
updateElements();
redraw();
}

/**
* Display this menu to the player given in the constructor.
*/
@Override
public void display(){
updateElements();
setup();
displayTo(getPlayer());
}

/**
* Display items on their slots.
* This method already has a good working implementation, so try not to override it.
Expand Down
10 changes: 2 additions & 8 deletions src/main/java/org/mineacademy/fo/menu/AdvancedMenuTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,12 @@
/**
* The semi-ready implementation of paged menu with all tools.
* You only have to set the size, title and locked slots.<br><br>
* DO NOT FORGET to add {@link #init()} method in the end of the constructor
* if you make any changes in your menu (like setting the locked slots or adding new buttons).
* To get started, override {@link #setup} method and customize your menu inside it.
*/
public abstract class AdvancedMenuTools extends AdvancedMenuPagged<Tool> {

public AdvancedMenuTools(Player player) {
this(player, null);
}

public AdvancedMenuTools(Player player, Class<? extends AdvancedMenu> parent){
super(player, parent);
init();
super(player);
}

@Override
Expand Down

0 comments on commit 7700a04

Please sign in to comment.