Closed thelipe7 closed 2 years ago
E ai meu amigão, beleza? Provavelmente durante o setSource
, a instância de Main.getInstance()
pode estar retornando nullo. Você já tentou debuggar o code?
Aliás, sugiro que você veja o tópico de paginação da wiki aqui. Haverá alguns métodos mais simples que pode o auxiliar na hora de criar um menu paginado!
Este erro acontece apenas quando tento usar o hasNextPage
ou hasPreviousPage
, isso em qualquer parte do código que já tentei o utilizar, quando removo o mesmo o menu funciona normalmente, mas o problema é os itens de navegação que quero esconder, afinal não tem sentido eles aparecerem se não existem outras páginas.
O menu fica da seguinte forma:
Utilizando o mesmo código em tudo apenas removendo o hasNextPage
e hasPreviousPage
:
Main.getInstance().getViewFrame().setDefaultNextPageItem((context) -> { ViewItem viewItem = new ViewItem(); viewItem.withItem(BukkitUtils.loadItemStack("262:0 : 1 : nome>&aPágina {page} : esconder>tudo" .replace("{page}", String.valueOf(context.getPage() + 2)))); viewItem.onClick(event -> { if (event.isLeftClick()) { event.paginated().switchToNextPage(); BukkitUtils.playSound(event.getPlayer(), Sound.CLICK); } }); return viewItem; }); Main.getInstance().getViewFrame().setDefaultPreviousPageItem((context) -> { ViewItem viewItem = new ViewItem(); viewItem.withItem(BukkitUtils.loadItemStack("262:0 : 1 : nome>&aPágina {page} : esconder>tudo" .replace("{page}", String.valueOf(context.getPage())))); viewItem.onClick(event -> { if (event.isLeftClick()) { event.paginated().switchToPreviousPage(); BukkitUtils.playSound(event.getPlayer(), Sound.CLICK); } }); return viewItem; });
Aparentemente, o método setDefaultPreviousPageItem
não possui efeitos nenhum. Você já tentou usar os métodos setNavigateNextItemFactory
e setNavigateBackItemFactory
?
Aparentemente, o método
setDefaultPreviousPageItem
não possui efeitos nenhum. Você já tentou usar os métodossetNavigateNextItemFactory
esetNavigateBackItemFactory
?
O principio é o mesmo, entretanto, você não precisa aplicar nenhum item ao ViewItem caso não haja nenhuma pagina disponivel.
@luiz-otavio Testei a sua sugestão e o erro continou, então fui testando e testando diversas formas e possíveis motivos para acontecer este problema. Por fim cheguei a seguinte conclusão:
Procurando por formas de fazer o que foi discutido acima, eu encontrei este exemplo deixado em https://github.com/DevNatan/inventory-framework/blob/main/examples/src/main/java/me/saiintbrisson/minecraft/examples/PersistentLayeredNavigablePaginatedView.java onde dentro do mesmo tem uma forma de definir os itens de navegação, modifiquei o mesmo e finalmente consegui o resultado esperado, chegando no seguinte código final:
public final class TopLossesView extends PaginatedView<Integer> {
public TopLossesView() {
super(6, "Paginated view");
setSource(IntStream.rangeClosed(0, 100).boxed().collect(Collectors.toList()));
setLayout("XXXXXXXXX", "XOOOOOOOX", "XOOOOOOOX", "XOOOOOOOX", "XOOOOOOOX", "XXX<X>XXX");
}
@Override
protected ViewItem getPreviousPageItem(@NotNull PaginatedViewContext<Integer> context) {
ViewItem viewItem = new ViewItem();
if (!context.isFirstPage()) {
viewItem
.withItem(BukkitUtils.loadItemStack("262:0 : 1 : nome>&aPágina {page} : esconder>tudo"
.replace("{page}", String.valueOf(context.getPage()))))
.onClick(event -> {
if (event.isLeftClick()) {
context.switchToPreviousPage();
BukkitUtils.playSound(event.getPlayer(), Sound.CLICK);
}
});
} else {
viewItem.withItem(new ItemStack(Material.AIR));
}
return viewItem;
}
@Override
protected ViewItem getNextPageItem(@NotNull PaginatedViewContext<Integer> context) {
ViewItem viewItem = new ViewItem();
if (context.getPage() + 1 != context.getPagesCount()) {
viewItem
.withItem(BukkitUtils.loadItemStack("262:0 : 1 : nome>&aPágina {page} : esconder>tudo"
.replace("{page}", String.valueOf(context.getPage() + 2))))
.onClick(event -> {
if (event.isLeftClick()) {
context.switchToNextPage();
BukkitUtils.playSound(event.getPlayer(), Sound.CLICK);
}
});
} else {
viewItem.withItem(new ItemStack(Material.AIR));
}
return viewItem;
}
@Override
protected void onItemRender(PaginatedViewSlotContext<Integer> render, ViewItem item, Integer value) {
item.withItem(createPaginationItemStack(value));
}
private ItemStack createPaginationItemStack(int value) {
ItemStack stack = new ItemStack(Material.PAPER);
ItemMeta meta = requireNonNull(stack.getItemMeta());
meta.setDisplayName("Item " + value);
stack.setItemMeta(meta);
return stack;
}
}
Porém quando passei a parte de navegação para meus menus, o mesmo erro de antes voltou a aparecer, então eu pensei que poderia ser erro meu em fazer os menus ou algo parecido, mas resolvi testar uma coisa, ao alterar o set source do código acima de: setSource(IntStream.rangeClosed(0, 100).boxed().collect(Collectors.toList()));
para:
setSource(context -> {
return IntStream.rangeClosed(0, 100).boxed().collect(Collectors.toList());
});
O erro começou a aparecer e o menu parou de funcionar. Por fim resumindo ao tornar o setSource
como dinâmico algumas funções ficam retornando o erro acima. Minha explicação é bem bagunçada mas espero ter conseguido explicar de uma forma boa.
Excelente! Por fim, isso resolve a issue?
Na verdade não. Eu preciso usar o setSource dinâmico mas por causa dele da o erro aí ,-,
Você tem certeza que precisa disso dinamicamente? O que acha de tentar:
public TopWinsView() {
super(3, "Top Views"); // Example
List<User> user = Main.getInstance().getMainDataManager().USERS.getCached()
.clone();
user.sort(Comparing.comparing(User::getWins).reversed()); // Coloca para atualizar isso a cada 5m, pois o cache é variavel;
setSource(user); // Pronto, clonou a lista de usuários e ordenou por vitórias.
setNextPageItem((context, item) -> {
if (!context.hasNextPage()) {
return;
}
ItemStack arrow = new ItemBuilder(Material.ARROW)
.name(
translate("&aNext page")
).build();
item.withItem(arrow).onClick(handler -> context.switchToNextPage());
});
setPreviousPageItem((context, item) -> {
if (!context.hasPreviousPage()) {
return;
}
ItemStack arrow = new ItemBuilder(Material.ARROW)
.name(
translate("&aPrevious page")
).build();
item.withItem(arrow).onClick(handler -> context.switchToPreviousPage());
});
}
@Override
protected void onItemRender(@NotNull PaginatedViewSlotContext<Match> context, @NotNull ViewItem viewItem, @NotNull User value) {
String name = value.getName(); // Salva o nome do user, porque o método Bukkit#getOfflinePlayer é lento.
ItemStack icon = BukkitUtils.loadItemStack("397:3 : 1 : nome>&e{pos}° - {player} : lore>&fVitórias: &7{wins} : donc
.replace(target:"{player}", name)
.replace(target:"{pos}", String.valueOf(context.getIndex() + 1))
.replace(target:"{wins}", String.valueOf(value.getWins())));
return viewItem.withItem(icon);
}
@Override
protected void onRender(@NotNull ViewContext context) {
if (context.paginated().getSource().isEmpty()) {
// Fico vazio? então bota um item para falar que ta vazio.
ItemStack empty = new ItemBuilder(Material.BARRIER)
.name(
translate("&cSem vencedores.")
).build();
context.slot(
13,
empty
);
}
}
Ai fica igualzinho o exemplo, e é claro, o melhor seria tornar essa lista global e usar métodos como scheduleUpdate
para atualizar frequentemente a lista.
Adaptei um pouco e apliquei em todos os meus menus e finalmente funcionou da forma esperada :). Agora apenas uma dúvida, 3 menus onde são listados alguns elementos, vou usar de exemplo um que é uma lista de itens, dentro do menu eu coloquei para ao clicar com o botão direito ele remove o item da lista. Porém eu quero que ele atualize na hora isso no menu e não que eu delete e tenha que reabrir o menu para atualizar, se for possívela atualizar para todos que estão vendo o menu também seria bem top.
Você pode invocar o método ViewContext#update
, na qual, vai atualizar o layout atual da pagina conforme a source!
Is there an existing issue for this?
🐛 Describe the bug
Mesmo sem outras páginas para exibir ele continua aparecendo os itens de navegação
✔️ Expected behavior
O item de navegação aparecer apenas quando necessário.
👣 Steps to Reproduce
Ao me deparar com este problema fui em busca de uma solução, o que resultou no seguinte código:
Porém quando tento abrir o menu resulta no seguinte erro:
💻 Platform
⭐ Versions
MC 1.8.8, IF 2.5.2
✍️ Additional context
Meu setSource está da seguinte forma:
Dentro de: