Add search button to the CommonPagedPanel.

Search button will allow to search elements if there are more than displayed elements.
This commit is contained in:
BONNe 2021-09-20 15:14:42 +03:00
parent 8c9ddb189d
commit 09d5bfc8cf
8 changed files with 303 additions and 47 deletions

View File

@ -14,7 +14,7 @@ import org.eclipse.jdt.annotation.NonNull;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Consumer;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
@ -27,7 +27,7 @@ import world.bentobox.challenges.utils.Constants;
/**
* This panel implements common things for Paged pages.
*/
public abstract class CommonPagedPanel extends CommonPanel
public abstract class CommonPagedPanel<T> extends CommonPanel
{
/**
* Instantiates a new Common paged panel.
@ -57,16 +57,28 @@ public abstract class CommonPagedPanel extends CommonPanel
}
/**
* This method is called when filter value is updated.
*/
protected abstract void updateFilters();
/**
* Create element button panel item.
*
* @param object the object
* @return the panel item
*/
protected abstract PanelItem createElementButton(T object);
/**
* Populate elements.
*
* @param panelBuilder the panel builder
* @param objectList the object list
* @param buttonBuilder the button builder
*/
protected void populateElements(PanelBuilder panelBuilder,
List<?> objectList,
Function<Object, PanelItem> buttonBuilder)
protected void populateElements(PanelBuilder panelBuilder, List<T> objectList)
{
final int MAX_ELEMENTS = 21;
final int size = objectList.size();
@ -91,7 +103,7 @@ public abstract class CommonPagedPanel extends CommonPanel
{
if (!panelBuilder.slotOccupied(index))
{
panelBuilder.item(index, buttonBuilder.apply(objectList.get(objectIndex++)));
panelBuilder.item(index, this.createElementButton(objectList.get(objectIndex++)));
}
index++;
@ -107,6 +119,13 @@ public abstract class CommonPagedPanel extends CommonPanel
{
panelBuilder.item(18, this.getButton(CommonButtons.PREVIOUS));
}
// Add search button only if there is more than MAX_ELEMENTS objects or searchString
// is not blank.
if (!this.searchString.isBlank() || objectList.size() > MAX_ELEMENTS)
{
panelBuilder.item(40, this.getButton(CommonButtons.SEARCH));
}
}
@ -157,6 +176,59 @@ public abstract class CommonPagedPanel extends CommonPanel
return true;
};
}
else if (button == CommonButtons.SEARCH)
{
description.add(this.user.getTranslation(reference + "description"));
if (this.searchString != null && !this.searchString.isEmpty())
{
description.add(this.user.getTranslation(reference + "search",
Constants.PARAMETER_VALUE, this.searchString));
}
description.add("");
description.add(this.user.getTranslation(Constants.TIPS + "left-click-to-edit"));
if (!this.searchString.isEmpty())
{
description.add(this.user.getTranslation(Constants.TIPS + "right-click-to-clear"));
}
icon = new ItemStack(Material.ANVIL);
clickHandler = (panel, user, clickType, slot) -> {
if (clickType.isRightClick())
{
// Clear string.
this.searchString = "";
this.updateFilters();
// Rebuild gui.
this.build();
}
else
{
// Create consumer that process description change
Consumer<String> consumer = value ->
{
if (value != null)
{
this.searchString = value;
this.updateFilters();
}
this.build();
};
// start conversation
ConversationUtils.createStringInput(consumer,
user,
user.getTranslation(Constants.CONVERSATIONS + "write-search"),
user.getTranslation(Constants.CONVERSATIONS + "search-updated"));
}
return true;
};
}
else
{
icon = new ItemStack(Material.PAPER);
@ -178,7 +250,8 @@ public abstract class CommonPagedPanel extends CommonPanel
private enum CommonButtons
{
NEXT,
PREVIOUS
PREVIOUS,
SEARCH
}
@ -186,4 +259,9 @@ public abstract class CommonPagedPanel extends CommonPanel
* Current page index.
*/
private int pageIndex;
/**
* Text that contains filter string.
*/
protected String searchString = "";
}

View File

@ -34,7 +34,7 @@ import world.bentobox.challenges.utils.Utils;
/**
* This class contains all necessary elements to create Levels Edit GUI.
*/
public class EditLevelPanel extends CommonPagedPanel
public class EditLevelPanel extends CommonPagedPanel<Challenge>
{
// ---------------------------------------------------------------------
// Section: Constructors
@ -111,6 +111,16 @@ public class EditLevelPanel extends CommonPagedPanel
// ---------------------------------------------------------------------
/**
* This method is called when filter value is updated.
*/
@Override
protected void updateFilters()
{
// Do nothing here.
}
/**
* This method builds all necessary elements in GUI panel.
*/
@ -190,11 +200,15 @@ public class EditLevelPanel extends CommonPagedPanel
*/
private void buildChallengesPanel(PanelBuilder panelBuilder)
{
List<Challenge> challengeList = this.addon.getChallengesManager().getLevelChallenges(this.challengeLevel);
List<Challenge> challengeList = this.addon.getChallengesManager().
getLevelChallenges(this.challengeLevel).stream().
filter(challenge -> this.searchString.isBlank() ||
challenge.getFriendlyName().toLowerCase().contains(this.searchString.toLowerCase()) ||
challenge.getUniqueId().toLowerCase().contains(this.searchString.toLowerCase()) ||
challenge.getChallengeType().name().toLowerCase().contains(this.searchString)).
collect(Collectors.toList());
this.populateElements(panelBuilder,
challengeList,
o -> this.createChallengeIcon((Challenge) o));
this.populateElements(panelBuilder, challengeList);
panelBuilder.item(39, this.createButton(Button.ADD_CHALLENGES));
panelBuilder.item(41, this.createButton(Button.REMOVE_CHALLENGES));
@ -279,7 +293,8 @@ public class EditLevelPanel extends CommonPagedPanel
* @param challenge Challenge which icon must be created.
* @return PanelItem that represents given challenge.
*/
private PanelItem createChallengeIcon(Challenge challenge)
@Override
protected PanelItem createElementButton(Challenge challenge)
{
return new PanelItemBuilder().
name(Util.translateColorCodes(challenge.getFriendlyName())).

View File

@ -33,7 +33,7 @@ import world.bentobox.challenges.web.object.LibraryEntry;
* This class contains all necessary elements to create GUI that lists all challenges.
* It allows to edit them or remove, depending on given input mode.
*/
public class LibraryPanel extends CommonPagedPanel
public class LibraryPanel extends CommonPagedPanel<LibraryEntry>
{
// ---------------------------------------------------------------------
// Section: Constructor
@ -54,6 +54,8 @@ public class LibraryPanel extends CommonPagedPanel
case DATABASE -> this.generateDatabaseEntries();
case TEMPLATE -> this.generateTemplateEntries();
};
this.filterElements = this.libraryEntries;
}
@ -130,6 +132,32 @@ public class LibraryPanel extends CommonPagedPanel
// ---------------------------------------------------------------------
/**
* This method is called when filter value is updated.
*/
@Override
protected void updateFilters()
{
if (this.searchString == null || this.searchString.isBlank())
{
this.filterElements = this.libraryEntries;
}
else
{
this.filterElements = this.libraryEntries.stream().
filter(element -> {
// If element name is set and name contains search field, then do not filter out.
return element.name().toLowerCase().contains(this.searchString.toLowerCase()) ||
element.author().toLowerCase().contains(this.searchString.toLowerCase()) ||
element.gameMode().toLowerCase().contains(this.searchString.toLowerCase()) ||
element.language().toLowerCase().contains(this.searchString.toLowerCase());
}).
distinct().
collect(Collectors.toList());
}
}
/**
* {@inheritDoc}
*/
@ -156,9 +184,7 @@ public class LibraryPanel extends CommonPagedPanel
GuiUtils.fillBorder(panelBuilder);
this.populateElements(panelBuilder,
this.libraryEntries,
o -> this.createEntryIcon((LibraryEntry) o));
this.populateElements(panelBuilder, this.filterElements);
if (this.mode == Library.WEB)
{
@ -232,7 +258,8 @@ public class LibraryPanel extends CommonPagedPanel
* @param libraryEntry LibraryEntry which button must be created.
* @return Entry button.
*/
private PanelItem createEntryIcon(LibraryEntry libraryEntry)
@Override
protected PanelItem createElementButton(LibraryEntry libraryEntry)
{
PanelItemBuilder itemBuilder = new PanelItemBuilder().
name(ChatColor.translateAlternateColorCodes('&', libraryEntry.name())).
@ -436,4 +463,9 @@ public class LibraryPanel extends CommonPagedPanel
* List of library elements.
*/
private final List<LibraryEntry> libraryEntries;
/**
* Stores filtered items.
*/
private List<LibraryEntry> filterElements;
}

View File

@ -1,7 +1,9 @@
package world.bentobox.challenges.panel.admin;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.bukkit.Material;
import org.bukkit.World;
@ -25,7 +27,7 @@ import world.bentobox.challenges.utils.Utils;
* This class contains all necessary elements to create GUI that lists all challenges.
* It allows to edit them or remove, depending on given input mode.
*/
public class ListChallengesPanel extends CommonPagedPanel
public class ListChallengesPanel extends CommonPagedPanel<Challenge>
{
// ---------------------------------------------------------------------
// Section: Constructor
@ -96,6 +98,16 @@ public class ListChallengesPanel extends CommonPagedPanel
// ---------------------------------------------------------------------
/**
* This method is called when filter value is updated.
*/
@Override
protected void updateFilters()
{
// Do nothing here.
}
/**
* {@inheritDoc}
*/
@ -114,9 +126,15 @@ public class ListChallengesPanel extends CommonPagedPanel
GuiUtils.fillBorder(panelBuilder);
}
this.populateElements(panelBuilder,
this.addon.getChallengesManager().getAllChallenges(this.world),
o -> this.createChallengeIcon((Challenge) o));
List<Challenge> challengeList = this.addon.getChallengesManager().getAllChallenges(this.world).
stream().
filter(challenge -> this.searchString.isBlank() ||
challenge.getFriendlyName().toLowerCase().contains(this.searchString.toLowerCase()) ||
challenge.getUniqueId().toLowerCase().contains(this.searchString.toLowerCase()) ||
challenge.getChallengeType().name().toLowerCase().contains(this.searchString)).
collect(Collectors.toList());
this.populateElements(panelBuilder, challengeList);
panelBuilder.item(44, this.returnButton);
@ -129,7 +147,8 @@ public class ListChallengesPanel extends CommonPagedPanel
* @param challenge Challenge which button must be created.
* @return Challenge button.
*/
private PanelItem createChallengeIcon(Challenge challenge)
@Override
protected PanelItem createElementButton(Challenge challenge)
{
PanelItemBuilder itemBuilder = new PanelItemBuilder().
name(Util.translateColorCodes(challenge.getFriendlyName())).

View File

@ -4,7 +4,9 @@ package world.bentobox.challenges.panel.admin;
import org.bukkit.Material;
import org.bukkit.World;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
@ -12,6 +14,7 @@ import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.util.Util;
import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.database.object.ChallengeLevel;
import world.bentobox.challenges.panel.CommonPagedPanel;
import world.bentobox.challenges.panel.CommonPanel;
@ -25,7 +28,7 @@ import world.bentobox.challenges.utils.Utils;
* This class creates GUI that lists all Levels. Clicking on Level icon will be processed
* by input mode.
*/
public class ListLevelsPanel extends CommonPagedPanel
public class ListLevelsPanel extends CommonPagedPanel<ChallengeLevel>
{
// ---------------------------------------------------------------------
// Section: Constructor
@ -96,6 +99,16 @@ public class ListLevelsPanel extends CommonPagedPanel
// ---------------------------------------------------------------------
/**
* This method is called when filter value is updated.
*/
@Override
protected void updateFilters()
{
// Do nothing here.
}
/**
* {@inheritDoc}
*/
@ -114,9 +127,14 @@ public class ListLevelsPanel extends CommonPagedPanel
GuiUtils.fillBorder(panelBuilder);
}
this.populateElements(panelBuilder,
this.addon.getChallengesManager().getLevels(this.world),
o -> this.createLevelIcon((ChallengeLevel) o));
List<ChallengeLevel> levelList = this.addon.getChallengesManager().getLevels(this.world).
stream().
filter(challenge -> this.searchString.isBlank() ||
challenge.getFriendlyName().toLowerCase().contains(this.searchString.toLowerCase()) ||
challenge.getUniqueId().toLowerCase().contains(this.searchString.toLowerCase())).
collect(Collectors.toList());
this.populateElements(panelBuilder, levelList);
panelBuilder.item(44, this.returnButton);
@ -129,7 +147,8 @@ public class ListLevelsPanel extends CommonPagedPanel
* @param challengeLevel Level which button must be created.
* @return Level button.
*/
private PanelItem createLevelIcon(ChallengeLevel challengeLevel)
@Override
protected PanelItem createElementButton(ChallengeLevel challengeLevel)
{
PanelItemBuilder itemBuilder = new PanelItemBuilder().
name(Util.translateColorCodes(challengeLevel.getFriendlyName())).

View File

@ -31,7 +31,7 @@ import world.bentobox.challenges.utils.Utils;
/**
* This class contains methods that allows to select specific user.
*/
public class ListUsersPanel extends CommonPagedPanel
public class ListUsersPanel extends CommonPagedPanel<Player>
{
// ---------------------------------------------------------------------
// Section: Constructors
@ -56,6 +56,7 @@ public class ListUsersPanel extends CommonPagedPanel
super(addon, user, world, topLabel, permissionPrefix);
this.onlineUsers = this.collectUsers(ViewMode.IN_WORLD);
this.operationMode = operationMode;
this.filterElements = this.onlineUsers;
}
@ -67,6 +68,7 @@ public class ListUsersPanel extends CommonPagedPanel
super(panel);
this.onlineUsers = this.collectUsers(ViewMode.IN_WORLD);
this.operationMode = operationMode;
this.filterElements = this.onlineUsers;
}
@ -104,6 +106,29 @@ public class ListUsersPanel extends CommonPagedPanel
// ---------------------------------------------------------------------
/**
* This method is called when filter value is updated.
*/
@Override
protected void updateFilters()
{
if (this.searchString == null || this.searchString.isBlank())
{
this.filterElements = this.onlineUsers;
}
else
{
this.filterElements = this.onlineUsers.stream().
filter(element -> {
// If element name is set and name contains search field, then do not filter out.
return element.getDisplayName().toLowerCase().contains(this.searchString.toLowerCase());
}).
distinct().
collect(Collectors.toList());
}
}
@Override
protected void build()
{
@ -112,9 +137,7 @@ public class ListUsersPanel extends CommonPagedPanel
GuiUtils.fillBorder(panelBuilder);
this.populateElements(panelBuilder,
this.onlineUsers,
o -> this.createPlayerIcon((Player) o));
this.populateElements(panelBuilder, this.filterElements);
// Add button that allows to toggle different player lists.
panelBuilder.item( 4, this.createToggleButton());
@ -129,7 +152,8 @@ public class ListUsersPanel extends CommonPagedPanel
* @param player Player which button must be created.
* @return Player button.
*/
private PanelItem createPlayerIcon(Player player)
@Override
protected PanelItem createElementButton(Player player)
{
final String reference = Constants.BUTTON + "player.";
@ -318,6 +342,10 @@ public class ListUsersPanel extends CommonPagedPanel
this.onlineUsers = this.collectUsers(this.mode);
}
// Reset search
this.searchString = "";
this.updateFilters();
this.build();
return true;
}).build();
@ -359,6 +387,11 @@ public class ListUsersPanel extends CommonPagedPanel
*/
private List<Player> onlineUsers;
/**
* List with players that should be in GUI.
*/
private List<Player> filterElements;
/**
* Current operation mode.
*/

View File

@ -8,6 +8,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
@ -27,7 +28,7 @@ import world.bentobox.challenges.utils.Utils;
/**
* This class allows to edit material that are in required material map.
*/
public class ManageBlocksPanel extends CommonPagedPanel
public class ManageBlocksPanel extends CommonPagedPanel<Material>
{
private ManageBlocksPanel(CommonPanel parentGUI, Map<Material, Integer> materialMap)
{
@ -36,9 +37,12 @@ public class ManageBlocksPanel extends CommonPagedPanel
this.materialList = new ArrayList<>(this.materialMap.keySet());
// Sort materials by their ordinal value.
this.materialList.sort(Comparator.comparing(Enum::ordinal));
this.materialList.sort(Comparator.comparing(Enum::name));
this.selectedMaterials = new HashSet<>();
// Init without filters applied.
this.filterElements = this.materialList;
}
@ -56,11 +60,34 @@ public class ManageBlocksPanel extends CommonPagedPanel
// ---------------------------------------------------------------------
/**
* This method is called when filter value is updated.
*/
@Override
protected void updateFilters()
{
if (this.searchString == null || this.searchString.isBlank())
{
this.filterElements = this.materialList;
}
else
{
this.filterElements = this.materialList.stream().
filter(element -> {
// If element name is set and name contains search field, then do not filter out.
return element.name().toLowerCase().contains(this.searchString.toLowerCase());
}).
distinct().
collect(Collectors.toList());
}
}
/**
* This method builds all necessary elements in GUI panel.
*/
@Override
public void build()
protected void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).
name(this.user.getTranslation(Constants.TITLE + "manage-blocks"));
@ -71,9 +98,7 @@ public class ManageBlocksPanel extends CommonPagedPanel
panelBuilder.item(3, this.createButton(Button.ADD_BLOCK));
panelBuilder.item(5, this.createButton(Button.REMOVE_BLOCK));
this.populateElements(panelBuilder,
this.materialList,
o -> this.createElementButton((Material) o));
this.populateElements(panelBuilder, this.filterElements);
// Add return button.
panelBuilder.item(44, this.returnButton);
@ -181,7 +206,8 @@ public class ManageBlocksPanel extends CommonPagedPanel
* @param material material which button must be created.
* @return new Button for material.
*/
private PanelItem createElementButton(Material material)
@Override
protected PanelItem createElementButton(Material material)
{
final String reference = Constants.BUTTON + "material.";
@ -279,4 +305,9 @@ public class ManageBlocksPanel extends CommonPagedPanel
* List of required materials.
*/
private final Map<Material, Integer> materialMap;
/**
* Stores filtered items.
*/
private List<Material> filterElements;
}

View File

@ -8,6 +8,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
@ -28,7 +29,7 @@ import world.bentobox.challenges.utils.Utils;
/**
* This class allows to edit entities that are in required entities map.
*/
public class ManageEntitiesPanel extends CommonPagedPanel
public class ManageEntitiesPanel extends CommonPagedPanel<EntityType>
{
private ManageEntitiesPanel(CommonPanel parentGUI, Map<EntityType, Integer> requiredEntities)
{
@ -39,6 +40,7 @@ public class ManageEntitiesPanel extends CommonPagedPanel
this.entityList.sort(Comparator.comparing(Enum::name));
this.selectedEntities = new HashSet<>(EntityType.values().length);
this.filterElements = this.entityList;
}
@ -56,11 +58,34 @@ public class ManageEntitiesPanel extends CommonPagedPanel
// ---------------------------------------------------------------------
/**
* This method is called when filter value is updated.
*/
@Override
protected void updateFilters()
{
if (this.searchString == null || this.searchString.isBlank())
{
this.filterElements = this.entityList;
}
else
{
this.filterElements = this.entityList.stream().
filter(element -> {
// If element name is set and name contains search field, then do not filter out.
return element.name().toLowerCase().contains(this.searchString.toLowerCase());
}).
distinct().
collect(Collectors.toList());
}
}
/**
* This method builds all necessary elements in GUI panel.
*/
@Override
public void build()
protected void build()
{
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).
name(this.user.getTranslation(Constants.TITLE + "manage-entities"));
@ -72,9 +97,7 @@ public class ManageEntitiesPanel extends CommonPagedPanel
panelBuilder.item(5, this.createButton(Button.REMOVE_ENTITY));
panelBuilder.item(8, this.createButton(Button.SWITCH_ENTITY));
this.populateElements(panelBuilder,
this.entityList,
o -> this.createEntityButton((EntityType) o));
this.populateElements(panelBuilder, this.filterElements);
// Add return button.
panelBuilder.item(44, this.returnButton);
@ -193,7 +216,8 @@ public class ManageEntitiesPanel extends CommonPagedPanel
* @param entity Entity which button must be created.
* @return new Button for entity.
*/
private PanelItem createEntityButton(EntityType entity)
@Override
protected PanelItem createElementButton(EntityType entity)
{
final String reference = Constants.BUTTON + "entity.";
@ -299,4 +323,9 @@ public class ManageEntitiesPanel extends CommonPagedPanel
* Boolean indicate if entities should be displayed as eggs or mob heads.
*/
private boolean asEggs;
/**
* Stores filtered items.
*/
private List<EntityType> filterElements;
}