-
-
Save I-Al-Istannen/eba17ebda69b03443b175a4e20712359 to your computer and use it in GitHub Desktop.
A BadPagedPane without any dependencies
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package me.ialistannen.modularcoretest.doggy; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Iterator; | |
import java.util.List; | |
import java.util.Locale; | |
import java.util.Map.Entry; | |
import java.util.Objects; | |
import java.util.SortedMap; | |
import java.util.TreeMap; | |
import java.util.stream.Collectors; | |
import org.bukkit.Bukkit; | |
import org.bukkit.ChatColor; | |
import org.bukkit.Material; | |
import org.bukkit.entity.Player; | |
import org.bukkit.event.inventory.InventoryClickEvent; | |
import org.bukkit.inventory.Inventory; | |
import org.bukkit.inventory.InventoryHolder; | |
import org.bukkit.inventory.ItemStack; | |
import org.bukkit.inventory.meta.ItemMeta; | |
/** | |
* A bad paged pane | |
*/ | |
public class BadPagedPane implements InventoryHolder { | |
private Inventory inventory; | |
private SortedMap<Integer, Page> pages = new TreeMap<>(); | |
private int currentIndex; | |
private int pageSize; | |
@SuppressWarnings("WeakerAccess") | |
protected BadButton controlBack; | |
@SuppressWarnings("WeakerAccess") | |
protected BadButton controlNext; | |
/** | |
* @param pageSize The page size. inventory rows - 2 | |
*/ | |
public BadPagedPane(int pageSize, int rows, String title) { | |
Objects.requireNonNull(title, "title can not be null!"); | |
if (rows < 3) { | |
throw new IllegalArgumentException("Rows must be >= 3, got " + rows); | |
} | |
if (rows > 6) { | |
throw new IllegalArgumentException("Rows must be <= 6, got " + rows); | |
} | |
if (pageSize > 6) { | |
throw new IllegalArgumentException("Page size must be <= 6, got" + pageSize); | |
} | |
this.pageSize = pageSize; | |
inventory = Bukkit.createInventory(this, rows * 9, color(title)); | |
pages.put(0, new Page(pageSize)); | |
} | |
/** | |
* @param button The button to add | |
*/ | |
public void addButton(BadButton button) { | |
for (Entry<Integer, Page> entry : pages.entrySet()) { | |
if (entry.getValue().addButton(button)) { | |
if (entry.getKey() == currentIndex) { | |
reRender(); | |
} | |
return; | |
} | |
} | |
Page page = new Page(pageSize); | |
page.addButton(button); | |
pages.put(pages.lastKey() + 1, page); | |
reRender(); | |
} | |
/** | |
* @param button The Button to remove | |
*/ | |
@SuppressWarnings("unused") | |
public void removeButton(BadButton button) { | |
for (Iterator<Entry<Integer, Page>> iterator = pages.entrySet().iterator(); iterator.hasNext(); ) { | |
Entry<Integer, Page> entry = iterator.next(); | |
if (entry.getValue().removeButton(button)) { | |
// we may need to delete the page | |
if (entry.getValue().isEmpty()) { | |
// we have more than one page, so delete it | |
if (pages.size() > 1) { | |
iterator.remove(); | |
} | |
// the currentIndex now points to a page that does not exist. Correct it. | |
if (currentIndex >= pages.size()) { | |
currentIndex--; | |
} | |
} | |
// if we modified the current one, re-render | |
// if we deleted the current page, re-render too | |
if (entry.getKey() >= currentIndex) { | |
reRender(); | |
} | |
return; | |
} | |
} | |
} | |
/** | |
* @return The amount of pages | |
*/ | |
@SuppressWarnings("WeakerAccess") | |
public int getPageAmount() { | |
return pages.size(); | |
} | |
/** | |
* @return The number of the current page (1 based) | |
*/ | |
@SuppressWarnings("WeakerAccess") | |
public int getCurrentPage() { | |
return currentIndex + 1; | |
} | |
/** | |
* @param index The index of the new page | |
*/ | |
@SuppressWarnings("WeakerAccess") | |
public void selectPage(int index) { | |
if (index < 0 || index >= getPageAmount()) { | |
throw new IllegalArgumentException( | |
"Index out of bounds: " + index + " [" + 0 + " " + getPageAmount() + ")" | |
); | |
} | |
if (index == currentIndex) { | |
return; | |
} | |
currentIndex = index; | |
reRender(); | |
} | |
/** | |
* Renders the inventory again | |
*/ | |
@SuppressWarnings("WeakerAccess") | |
public void reRender() { | |
inventory.clear(); | |
pages.get(currentIndex).render(inventory); | |
controlBack = null; | |
controlNext = null; | |
createControls(inventory); | |
} | |
/** | |
* @param event The {@link InventoryClickEvent} | |
*/ | |
@SuppressWarnings("WeakerAccess") | |
public void onClick(InventoryClickEvent event) { | |
event.setCancelled(true); | |
// back item | |
if (event.getSlot() == inventory.getSize() - 8) { | |
if (controlBack != null) { | |
controlBack.onClick(event); | |
} | |
return; | |
} | |
// next item | |
else if (event.getSlot() == inventory.getSize() - 2) { | |
if (controlNext != null) { | |
controlNext.onClick(event); | |
} | |
return; | |
} | |
pages.get(currentIndex).handleClick(event); | |
} | |
/** | |
* Get the object's inventory. | |
* | |
* @return The inventory. | |
*/ | |
@Override | |
public Inventory getInventory() { | |
return inventory; | |
} | |
/** | |
* Creates the controls | |
* | |
* @param inventory The inventory | |
*/ | |
@SuppressWarnings("WeakerAccess") | |
protected void createControls(Inventory inventory) { | |
// create separator | |
fillRow( | |
inventory.getSize() / 9 - 2, | |
getItemStack(Material.STAINED_GLASS_PANE, 15, ""), | |
inventory | |
); | |
if (getCurrentPage() > 1) { | |
String name = String.format( | |
Locale.ROOT, | |
"&3&lPage &a&l%d &7/ &c&l%d", | |
getCurrentPage() - 1, getPageAmount() | |
); | |
String lore = String.format( | |
Locale.ROOT, | |
"&7Brings you back to the page &c%d", | |
getCurrentPage() - 1 | |
); | |
ItemStack itemStack = getItemStack(Material.COAL_BLOCK, 0, name, lore); | |
controlBack = new BadButton(itemStack, event -> selectPage(currentIndex - 1)); | |
inventory.setItem(inventory.getSize() - 8, itemStack); | |
} | |
if (getCurrentPage() < getPageAmount()) { | |
String name = String.format( | |
Locale.ROOT, | |
"&3&lPage &a&l%d &7/ &c&l%d", | |
getCurrentPage() + 1, getPageAmount() | |
); | |
String lore = String.format( | |
Locale.ROOT, | |
"&7Brings you to the page &c%d", | |
getCurrentPage() + 1 | |
); | |
ItemStack itemStack = getItemStack(Material.IRON_BLOCK, 0, name, lore); | |
controlNext = new BadButton(itemStack, event -> selectPage(getCurrentPage())); | |
inventory.setItem(inventory.getSize() - 2, itemStack); | |
} | |
{ | |
String name = String.format( | |
Locale.ROOT, | |
"&3&lPage &a&l%d &7/ &c&l%d", | |
getCurrentPage(), getPageAmount() | |
); | |
String lore = String.format( | |
Locale.ROOT, | |
"&7You are on page &a%d &7/ &c%d", | |
getCurrentPage(), getPageAmount() | |
); | |
ItemStack itemStack = getItemStack(Material.BOOK, 0, name, lore); | |
inventory.setItem(inventory.getSize() - 5, itemStack); | |
} | |
} | |
private void fillRow(int rowIndex, ItemStack itemStack, Inventory inventory) { | |
int yMod = rowIndex * 9; | |
for (int i = 0; i < 9; i++) { | |
int slot = yMod + i; | |
inventory.setItem(slot, itemStack); | |
} | |
} | |
/** | |
* @param type The {@link Material} of the {@link ItemStack} | |
* @param durability The durability | |
* @param name The name. May be null. | |
* @param lore The lore. May be null. | |
* | |
* @return The item | |
*/ | |
@SuppressWarnings("WeakerAccess") | |
protected ItemStack getItemStack(Material type, int durability, String name, String... lore) { | |
ItemStack itemStack = new ItemStack(type, 1, (short) durability); | |
ItemMeta itemMeta = itemStack.getItemMeta(); | |
if (name != null) { | |
itemMeta.setDisplayName(color(name)); | |
} | |
if (lore != null && lore.length != 0) { | |
itemMeta.setLore(Arrays.stream(lore).map(this::color).collect(Collectors.toList())); | |
} | |
itemStack.setItemMeta(itemMeta); | |
return itemStack; | |
} | |
@SuppressWarnings("WeakerAccess") | |
protected String color(String input) { | |
return ChatColor.translateAlternateColorCodes('&', input); | |
} | |
/** | |
* @param player The {@link Player} to open it for | |
*/ | |
public void open(Player player) { | |
reRender(); | |
player.openInventory(getInventory()); | |
} | |
private static class Page { | |
private List<BadButton> buttons = new ArrayList<>(); | |
private int maxSize; | |
Page(int maxSize) { | |
this.maxSize = maxSize; | |
} | |
/** | |
* @param event The click event | |
*/ | |
void handleClick(InventoryClickEvent event) { | |
// user clicked in his own inventory. Silently drop it | |
if (event.getRawSlot() > event.getInventory().getSize()) { | |
return; | |
} | |
if (event.getSlot() >= buttons.size()) { | |
return; | |
} | |
BadButton button = buttons.get(event.getSlot()); | |
button.onClick(event); | |
} | |
/** | |
* @return True if there is space left | |
*/ | |
boolean hasSpace() { | |
return buttons.size() < maxSize * 9; | |
} | |
/** | |
* @param button The {@link BadButton} to add | |
* | |
* @return True if the button was added, false if there was no space | |
*/ | |
boolean addButton(BadButton button) { | |
if (!hasSpace()) { | |
return false; | |
} | |
buttons.add(button); | |
return true; | |
} | |
/** | |
* @param button The {@link BadButton} to remove | |
* | |
* @return True if the button was removed | |
*/ | |
boolean removeButton(BadButton button) { | |
return buttons.remove(button); | |
} | |
/** | |
* @param inventory The inventory to render in | |
*/ | |
void render(Inventory inventory) { | |
for (int i = 0; i < buttons.size(); i++) { | |
BadButton button = buttons.get(i); | |
inventory.setItem(i, button.getItemStack()); | |
} | |
} | |
/** | |
* @return True if this page is empty | |
*/ | |
boolean isEmpty() { | |
return buttons.isEmpty(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package me.ialistannen.modularcoretest.doggy; | |
import org.bukkit.event.EventHandler; | |
import org.bukkit.event.Listener; | |
import org.bukkit.event.inventory.InventoryClickEvent; | |
import org.bukkit.inventory.InventoryHolder; | |
/** | |
* Listens for click events for the {@link BadPagedPane} | |
*/ | |
public class BadPagedPaneListener implements Listener { | |
@EventHandler | |
public void onClick(InventoryClickEvent event) { | |
InventoryHolder holder = event.getInventory().getHolder(); | |
if (holder instanceof BadPagedPane) { | |
((BadPagedPane) holder).onClick(event); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package me.ialistannen.modularcoretest.doggy; | |
import org.bukkit.Material; | |
import org.bukkit.entity.Player; | |
import org.bukkit.scheduler.BukkitRunnable; | |
import com.perceivedev.perceivecore.utilities.item.ItemFactory; | |
import me.ialistannen.modularcoretest.ModularCoreTest; | |
public class Usage { | |
public static void main(String[] args, Player player) { | |
// set items to 36 to see how the pane handles dynamically creating and removing pages when opened | |
// This is because the two Runnables will then add a Button (==> overflow ==> new page) and then remove it again | |
int rows = 6, items = 100; | |
BadPagedPane pagedPane = new BadPagedPane(rows - 2, rows, "&3&lTest"); | |
for (int i = 1; i <= items; i++) { | |
int finalI = i; | |
pagedPane.addButton(new BadButton( | |
ItemFactory.builder(Material.STONE).setName("&6Hey: &a" + i).build(), | |
event -> player.sendMessage("Hey: " + finalI) | |
)); | |
} | |
pagedPane.open(player); | |
String hey = "Cool!"; | |
BadButton button = new BadButton( | |
ItemFactory.builder(Material.OBSIDIAN).setName("&6Hey: &a" + hey).build(), | |
event -> player.sendMessage("Hey: " + hey) | |
); | |
new BukkitRunnable() { | |
@Override | |
public void run() { | |
pagedPane.addButton(button); | |
} | |
}.runTaskLater(ModularCoreTest.getInstance(), 20 * 5); | |
new BukkitRunnable() { | |
@Override | |
public void run() { | |
pagedPane.removeButton(button); | |
} | |
}.runTaskLater(ModularCoreTest.getInstance(), 20 * 10); | |
// YOU NEED TO REGISTER THE BadPagedPaneListener. You can do so at startup, it will call the right methods | |
// at the right time, no matter when you register it. It can be registered the whole time without any problems. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Omg. I just found this on random spigot forums 0.o, thanks for making it!