Fix SpellShop item manager to not crash and support filtering

This commit is contained in:
drdev
2013-12-17 21:21:35 +00:00
parent 1c122b99e9
commit 117501c511
25 changed files with 224 additions and 124 deletions

2
.gitattributes vendored
View File

@@ -15464,13 +15464,13 @@ forge-gui/src/main/java/forge/gui/toolbox/imaging/FImagePanel.java -text
forge-gui/src/main/java/forge/gui/toolbox/imaging/FImageUtil.java -text forge-gui/src/main/java/forge/gui/toolbox/imaging/FImageUtil.java -text
forge-gui/src/main/java/forge/gui/toolbox/imaging/ImageUtil.java -text forge-gui/src/main/java/forge/gui/toolbox/imaging/ImageUtil.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/CardManager.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/CardManager.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/InventoryItemManager.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/ItemManager.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/ItemManager.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/ItemManagerContainer.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/ItemManagerContainer.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/ItemManagerModel.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/ItemManagerModel.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/SFilterUtil.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/SFilterUtil.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/SItemManagerIO.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/SItemManagerIO.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/SItemManagerUtil.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/SItemManagerUtil.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/SpellShopManager.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/CardCMCFilter.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/CardCMCFilter.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/CardColorFilter.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/CardColorFilter.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/CardFormatFilter.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/CardFormatFilter.java -text

View File

@@ -437,7 +437,7 @@ public enum CDeckEditorUI implements ICDoc, IMenuProvider {
deckTable.setWantElasticColumns(wantElastic); deckTable.setWantElasticColumns(wantElastic);
catView.setWantUnique(wantUnique); catView.setWantUnique(wantUnique);
deckView.setWantUnique(wantUnique); deckView.setWantUnique(wantUnique);
catView.buildFilterPredicate(); catView.applyFilters();
} }
private class _FindAsYouType extends KeyAdapter { private class _FindAsYouType extends KeyAdapter {

View File

@@ -257,7 +257,7 @@ public class CEditorDraftingProcess extends ACEditorBase<PaperCard, DeckGroup> {
if (this.getDeckManager().getPool() == null) { //avoid showing next choice or resetting pool if just switching back to Draft screen if (this.getDeckManager().getPool() == null) { //avoid showing next choice or resetting pool if just switching back to Draft screen
this.showChoices(this.boosterDraft.nextChoice()); this.showChoices(this.boosterDraft.nextChoice());
this.getDeckManager().setPool((Iterable<InventoryItem>) null); this.getDeckManager().setPool((Iterable<PaperCard>) null);
} }
else { else {
this.showChoices(this.getCatalogManager().getPool()); this.showChoices(this.getCatalogManager().getPool());

View File

@@ -48,7 +48,7 @@ import forge.gui.framework.FScreen;
import forge.gui.home.quest.CSubmenuQuestDecks; import forge.gui.home.quest.CSubmenuQuestDecks;
import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.itemmanager.InventoryItemManager; import forge.gui.toolbox.itemmanager.SpellShopManager;
import forge.gui.toolbox.itemmanager.SItemManagerUtil; import forge.gui.toolbox.itemmanager.SItemManagerUtil;
import forge.gui.toolbox.itemmanager.table.TableColumnInfo; import forge.gui.toolbox.itemmanager.table.TableColumnInfo;
import forge.gui.toolbox.itemmanager.table.SColumnUtil; import forge.gui.toolbox.itemmanager.table.SColumnUtil;
@@ -129,8 +129,8 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
this.questData = qd; this.questData = qd;
final InventoryItemManager catalogManager = new InventoryItemManager(false); final SpellShopManager catalogManager = new SpellShopManager(false);
final InventoryItemManager deckManager = new InventoryItemManager(false); final SpellShopManager deckManager = new SpellShopManager(false);
catalogManager.setAlwaysNonUnique(true); catalogManager.setAlwaysNonUnique(true);
deckManager.setAlwaysNonUnique(true); deckManager.setAlwaysNonUnique(true);

View File

@@ -30,36 +30,50 @@ import forge.quest.QuestWorld;
public final class CardManager extends ItemManager<PaperCard> { public final class CardManager extends ItemManager<PaperCard> {
public CardManager(boolean wantUnique0) { public CardManager(boolean wantUnique0) {
super(PaperCard.class, wantUnique0); super(PaperCard.class, wantUnique0);
}
this.lockFiltering = true; //temporary lock filtering for improved performance @Override
this.addFilter(new CardColorFilter(this)); protected void addDefaultFilters() {
this.addFilter(new CardTypeFilter(this)); addDefaultFilters(this);
this.lockFiltering = false;
buildFilterPredicate();
} }
@Override @Override
protected ItemFilter<PaperCard> createSearchFilter() { protected ItemFilter<PaperCard> createSearchFilter() {
return new CardSearchFilter(this); return createSearchFilter(this);
} }
@Override @Override
protected void buildFilterMenu(JPopupMenu menu) { protected void buildFilterMenu(JPopupMenu menu) {
buildFilterMenu(menu, this);
}
/* Static overrides shared with SpellShopManager*/
public static void addDefaultFilters(final ItemManager<? super PaperCard> itemManager) {
itemManager.addFilter(new CardColorFilter(itemManager));
itemManager.addFilter(new CardTypeFilter(itemManager));
}
public static ItemFilter<PaperCard> createSearchFilter(final ItemManager<? super PaperCard> itemManager) {
return new CardSearchFilter(itemManager);
}
public static void buildFilterMenu(JPopupMenu menu, final ItemManager<? super PaperCard> itemManager) {
JMenu fmt = new JMenu("Format"); JMenu fmt = new JMenu("Format");
for (final GameFormat f : Singletons.getModel().getFormats()) { for (final GameFormat f : Singletons.getModel().getFormats()) {
GuiUtils.addMenuItem(fmt, f.getName(), null, new Runnable() { GuiUtils.addMenuItem(fmt, f.getName(), null, new Runnable() {
@Override @Override
public void run() { public void run() {
addFilter(new CardFormatFilter(CardManager.this, f)); itemManager.addFilter(new CardFormatFilter(itemManager, f));
} }
}, CardFormatFilter.canAddFormat(f, getFilter(CardFormatFilter.class))); }, CardFormatFilter.canAddFormat(f, itemManager.getFilter(CardFormatFilter.class)));
} }
menu.add(fmt); menu.add(fmt);
GuiUtils.addMenuItem(menu, "Sets...", null, new Runnable() { GuiUtils.addMenuItem(menu, "Sets...", null, new Runnable() {
@Override @Override
public void run() { public void run() {
CardSetFilter existingFilter = getFilter(CardSetFilter.class); CardSetFilter existingFilter = itemManager.getFilter(CardSetFilter.class);
if (existingFilter != null) { if (existingFilter != null) {
existingFilter.edit(); existingFilter.edit();
} }
@@ -70,43 +84,43 @@ public final class CardManager extends ItemManager<PaperCard> {
public void run() { public void run() {
List<String> sets = dialog.getSelectedSets(); List<String> sets = dialog.getSelectedSets();
if (!sets.isEmpty()) { if (!sets.isEmpty()) {
addFilter(new CardSetFilter(CardManager.this, sets, dialog.getWantReprints())); itemManager.addFilter(new CardSetFilter(itemManager, sets, dialog.getWantReprints()));
} }
} }
}); });
} }
} }
}); });
JMenu range = new JMenu("Value range"); JMenu range = new JMenu("Value range");
GuiUtils.addMenuItem(range, "CMC", null, new Runnable() { GuiUtils.addMenuItem(range, "CMC", null, new Runnable() {
@Override @Override
public void run() { public void run() {
addFilter(new CardCMCFilter(CardManager.this)); itemManager.addFilter(new CardCMCFilter(itemManager));
} }
}, getFilter(CardCMCFilter.class) == null); }, itemManager.getFilter(CardCMCFilter.class) == null);
GuiUtils.addMenuItem(range, "Power", null, new Runnable() { GuiUtils.addMenuItem(range, "Power", null, new Runnable() {
@Override @Override
public void run() { public void run() {
addFilter(new CardPowerFilter(CardManager.this)); itemManager.addFilter(new CardPowerFilter(itemManager));
} }
}, getFilter(CardPowerFilter.class) == null); }, itemManager.getFilter(CardPowerFilter.class) == null);
GuiUtils.addMenuItem(range, "Toughness", null, new Runnable() { GuiUtils.addMenuItem(range, "Toughness", null, new Runnable() {
@Override @Override
public void run() { public void run() {
addFilter(new CardToughnessFilter(CardManager.this)); itemManager.addFilter(new CardToughnessFilter(itemManager));
} }
}, getFilter(CardToughnessFilter.class) == null); }, itemManager.getFilter(CardToughnessFilter.class) == null);
menu.add(range); menu.add(range);
JMenu world = new JMenu("Quest world"); JMenu world = new JMenu("Quest world");
for (final QuestWorld w : Singletons.getModel().getWorlds()) { for (final QuestWorld w : Singletons.getModel().getWorlds()) {
GuiUtils.addMenuItem(world, w.getName(), null, new Runnable() { GuiUtils.addMenuItem(world, w.getName(), null, new Runnable() {
@Override @Override
public void run() { public void run() {
addFilter(new CardQuestWorldFilter(CardManager.this, w)); itemManager.addFilter(new CardQuestWorldFilter(itemManager, w));
} }
}, CardQuestWorldFilter.canAddQuestWorld(w, getFilter(CardQuestWorldFilter.class))); }, CardQuestWorldFilter.canAddQuestWorld(w, itemManager.getFilter(CardQuestWorldFilter.class)));
} }
menu.add(world); menu.add(world);
} }

View File

@@ -1,27 +0,0 @@
package forge.gui.toolbox.itemmanager;
import javax.swing.JPopupMenu;
import forge.gui.toolbox.itemmanager.filters.ItemFilter;
import forge.item.InventoryItem;
/**
* TODO: Write javadoc for this type.
*
*/
@SuppressWarnings("serial")
public final class InventoryItemManager extends ItemManager<InventoryItem> {
public InventoryItemManager(boolean wantUnique0) {
super(InventoryItem.class, wantUnique0);
}
@Override
protected ItemFilter<InventoryItem> createSearchFilter() {
return null;
}
@Override
protected void buildFilterMenu(JPopupMenu menu) {
}
}

View File

@@ -72,10 +72,10 @@ import forge.util.ReflectionUtil;
public abstract class ItemManager<T extends InventoryItem> extends JPanel { public abstract class ItemManager<T extends InventoryItem> extends JPanel {
private ItemPool<T> pool; private ItemPool<T> pool;
private final ItemManagerModel<T> model; private final ItemManagerModel<T> model;
private Predicate<T> filterPredicate = null; private Predicate<? super T> filterPredicate = null;
private final Map<Class<? extends ItemFilter<T>>, List<ItemFilter<T>>> filters = private final Map<Class<? extends ItemFilter<? extends T>>, List<ItemFilter<? extends T>>> filters =
new HashMap<Class<? extends ItemFilter<T>>, List<ItemFilter<T>>>(); new HashMap<Class<? extends ItemFilter<? extends T>>, List<ItemFilter<? extends T>>>();
private final List<ItemFilter<T>> orderedFilters = new ArrayList<ItemFilter<T>>(); private final List<ItemFilter<? extends T>> orderedFilters = new ArrayList<ItemFilter<? extends T>>();
private boolean wantUnique = false; private boolean wantUnique = false;
private boolean alwaysNonUnique = false; private boolean alwaysNonUnique = false;
private boolean allowMultipleSelections = false; private boolean allowMultipleSelections = false;
@@ -89,7 +89,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
.readonly() //TODO: Support editing filter logic .readonly() //TODO: Support editing filter logic
.build(); .build();
private ItemFilter<T> mainSearchFilter; private ItemFilter<? extends T> mainSearchFilter;
private final JPanel pnlButtons = new JPanel(new MigLayout("insets 0, gap 0, ax center, hidemode 3")); private final JPanel pnlButtons = new JPanel(new MigLayout("insets 0, gap 0, ax center, hidemode 3"));
private final FLabel btnFilters = new FLabel.ButtonBuilder() private final FLabel btnFilters = new FLabel.ButtonBuilder()
@@ -111,6 +111,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
private final ItemTable<T> table; private final ItemTable<T> table;
private final JScrollPane tableScroller; private final JScrollPane tableScroller;
private boolean initialized;
protected boolean lockFiltering; protected boolean lockFiltering;
/** /**
@@ -124,11 +125,18 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
this.genericType = genericType0; this.genericType = genericType0;
this.wantUnique = wantUnique0; this.wantUnique = wantUnique0;
this.model = new ItemManagerModel<T>(this, genericType0); this.model = new ItemManagerModel<T>(this, genericType0);
this.table = new ItemTable<T>(this, this.model);
this.tableScroller = new JScrollPane(this.table);
}
/**
* Initialize item manager if needed
*/
public void initialize() {
if (this.initialized) { return; } //avoid initializing more than once
//build table view //build table view
this.table = new ItemTable<T>(this, this.model);
this.table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); this.table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.tableScroller = new JScrollPane(this.table);
this.tableScroller.setOpaque(false); this.tableScroller.setOpaque(false);
this.tableScroller.getViewport().setOpaque(false); this.tableScroller.getViewport().setOpaque(false);
this.tableScroller.setBorder(null); this.tableScroller.setBorder(null);
@@ -144,7 +152,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
public void itemStateChanged(ItemEvent arg0) { public void itemStateChanged(ItemEvent arg0) {
lockFiltering = true; lockFiltering = true;
boolean enabled = chkEnableFilters.isSelected(); boolean enabled = chkEnableFilters.isSelected();
for (ItemFilter<T> filter : orderedFilters) { for (ItemFilter<? extends T> filter : orderedFilters) {
filter.setEnabled(enabled); filter.setEnabled(enabled);
} }
txtFilterLogic.setEnabled(enabled); txtFilterLogic.setEnabled(enabled);
@@ -152,7 +160,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
mainSearchFilter.setEnabled(enabled); mainSearchFilter.setEnabled(enabled);
mainSearchFilter.updateEnabled(); //need to call updateEnabled since no listener for filter checkbox mainSearchFilter.updateEnabled(); //need to call updateEnabled since no listener for filter checkbox
lockFiltering = false; lockFiltering = false;
buildFilterPredicate(); applyFilters();
} }
}); });
@@ -174,7 +182,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
final Runnable cmdAddCurrentSearch = new Runnable() { final Runnable cmdAddCurrentSearch = new Runnable() {
@Override @Override
public void run() { public void run() {
ItemFilter<T> searchFilter = mainSearchFilter.createCopy(); ItemFilter<? extends T> searchFilter = mainSearchFilter.createCopy();
if (searchFilter != null) { if (searchFilter != null) {
lockFiltering = true; //prevent updating filtering from this change lockFiltering = true; //prevent updating filtering from this change
addFilter(searchFilter); addFilter(searchFilter);
@@ -209,6 +217,12 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
}; };
this.btnFilters.setCommand(addFilterCommand); this.btnFilters.setCommand(addFilterCommand);
this.btnFilters.setRightClickCommand(addFilterCommand); //show menu on right-click too this.btnFilters.setRightClickCommand(addFilterCommand); //show menu on right-click too
//setup initial filters
addDefaultFilters();
this.initialized = true; //must set flag just before applying filters
applyFilters();
} }
@Override @Override
@@ -216,7 +230,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
int number = 0; int number = 0;
StringBuilder logicBuilder = new StringBuilder(); StringBuilder logicBuilder = new StringBuilder();
LayoutHelper helper = new LayoutHelper(this); LayoutHelper helper = new LayoutHelper(this);
for (ItemFilter<T> filter : this.orderedFilters) { for (ItemFilter<? extends T> filter : this.orderedFilters) {
filter.setNumber(++number); filter.setNumber(++number);
logicBuilder.append(number + "&"); logicBuilder.append(number + "&");
helper.fillLine(filter.getPanel(), ItemFilter.PANEL_HEIGHT); helper.fillLine(filter.getPanel(), ItemFilter.PANEL_HEIGHT);
@@ -271,7 +285,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
* *
* @param items * @param items
*/ */
public void setPool(final Iterable<InventoryItem> items) { public void setPool(final Iterable<T> items) {
this.setPool(ItemPool.createFrom(items, this.genericType), false); this.setPool(ItemPool.createFrom(items, this.genericType), false);
} }
@@ -346,7 +360,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
* *
* getSelectedItem. * getSelectedItem.
* *
* @return InventoryItem * @return T
*/ */
public T getSelectedItem() { public T getSelectedItem() {
return this.table.getSelectedItem(); return this.table.getSelectedItem();
@@ -356,7 +370,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
* *
* getSelectedItems. * getSelectedItems.
* *
* @return List<InventoryItem> * @return List<T>
*/ */
public List<T> getSelectedItems() { public List<T> getSelectedItems() {
return this.table.getSelectedItems(); return this.table.getSelectedItems();
@@ -459,32 +473,33 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
return this.model.getItems(); return this.model.getItems();
} }
protected abstract ItemFilter<T> createSearchFilter(); protected abstract void addDefaultFilters();
protected abstract ItemFilter<? extends T> createSearchFilter();
protected abstract void buildFilterMenu(JPopupMenu menu); protected abstract void buildFilterMenu(JPopupMenu menu);
protected <F extends ItemFilter<T>> F getFilter(Class<F> filterClass) { protected <F extends ItemFilter<? extends T>> F getFilter(Class<F> filterClass) {
return ReflectionUtil.safeCast(this.filters.get(filterClass), filterClass); return ReflectionUtil.safeCast(this.filters.get(filterClass), filterClass);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void addFilter(final ItemFilter<T> filter) { public void addFilter(final ItemFilter<? extends T> filter) {
final Class<? extends ItemFilter<T>> filterClass = (Class<? extends ItemFilter<T>>) filter.getClass(); final Class<? extends ItemFilter<? extends T>> filterClass = (Class<? extends ItemFilter<? extends T>>) filter.getClass();
List<ItemFilter<T>> classFilters = this.filters.get(filterClass); List<ItemFilter<? extends T>> classFilters = this.filters.get(filterClass);
if (classFilters == null) { if (classFilters == null) {
classFilters = new ArrayList<ItemFilter<T>>(); classFilters = new ArrayList<ItemFilter<? extends T>>();
this.filters.put(filterClass, classFilters); this.filters.put(filterClass, classFilters);
} }
if (classFilters.size() > 0) { if (classFilters.size() > 0) {
//if filter with the same class already exists, try to merge if allowed //if filter with the same class already exists, try to merge if allowed
//NOTE: can always use first filter for these checks since if //NOTE: can always use first filter for these checks since if
//merge is supported, only one will ever exist //merge is supported, only one will ever exist
final ItemFilter<T> existingFilter = classFilters.get(0); final ItemFilter<? extends T> existingFilter = classFilters.get(0);
if (existingFilter.merge(filter)) { if (existingFilter.merge(filter)) {
//if new filter merged with existing filter, just refresh the widget //if new filter merged with existing filter, just refresh the widget
existingFilter.refreshWidget(); existingFilter.refreshWidget();
if (!this.lockFiltering) { //apply filters and focus existing filter's main component if filtering not locked if (!this.lockFiltering) { //apply filters and focus existing filter's main component if filtering not locked
buildFilterPredicate(); applyFilters();
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
@@ -501,7 +516,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
this.revalidate(); this.revalidate();
if (!this.lockFiltering) { //apply filters and focus filter's main component if filtering not locked if (!this.lockFiltering) { //apply filters and focus filter's main component if filtering not locked
buildFilterPredicate(); applyFilters();
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
@@ -512,9 +527,9 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void removeFilter(ItemFilter<T> filter) { public void removeFilter(ItemFilter<? extends T> filter) {
final Class<? extends ItemFilter<T>> filterClass = (Class<? extends ItemFilter<T>>) filter.getClass(); final Class<? extends ItemFilter<? extends T>> filterClass = (Class<? extends ItemFilter<? extends T>>) filter.getClass();
final List<ItemFilter<T>> classFilters = this.filters.get(filterClass); final List<ItemFilter<? extends T>> classFilters = this.filters.get(filterClass);
if (classFilters != null && classFilters.remove(filter)) { if (classFilters != null && classFilters.remove(filter)) {
if (classFilters.size() == 0) { if (classFilters.size() == 0) {
this.filters.remove(filterClass); this.filters.remove(filterClass);
@@ -522,23 +537,23 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
orderedFilters.remove(filter); orderedFilters.remove(filter);
this.remove(filter.getPanel()); this.remove(filter.getPanel());
this.revalidate(); this.revalidate();
buildFilterPredicate(); applyFilters();
} }
} }
public void buildFilterPredicate() { public void applyFilters() {
if (this.lockFiltering) { return; } if (this.lockFiltering || !this.initialized) { return; }
List<Predicate<? super T>> predicates = new ArrayList<Predicate<? super T>>(); List<Predicate<? super T>> predicates = new ArrayList<Predicate<? super T>>();
predicates.add(Predicates.instanceOf(this.genericType)); predicates.add(Predicates.instanceOf(this.genericType));
for (ItemFilter<T> filter : this.orderedFilters) { //TODO: Support custom filter logic for (ItemFilter<? extends T> filter : this.orderedFilters) { //TODO: Support custom filter logic
if (filter.isEnabled() && !filter.isEmpty()) { if (filter.isEnabled() && !filter.isEmpty()) {
predicates.add(filter.buildPredicate()); predicates.add(filter.buildPredicate(this.genericType));
} }
} }
if (!this.mainSearchFilter.isEmpty()) { if (!this.mainSearchFilter.isEmpty()) {
predicates.add(mainSearchFilter.buildPredicate()); predicates.add(mainSearchFilter.buildPredicate(this.genericType));
} }
this.filterPredicate = predicates.size() == 0 ? null : Predicates.and(predicates); this.filterPredicate = predicates.size() == 0 ? null : Predicates.and(predicates);
if (this.pool != null) { if (this.pool != null) {
@@ -587,7 +602,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
this.table.getTableModel().refreshSort(); this.table.getTableModel().refreshSort();
for (ItemFilter<T> filter : this.orderedFilters) { for (ItemFilter<? extends T> filter : this.orderedFilters) {
filter.afterFiltersApplied(); filter.afterFiltersApplied();
} }

View File

@@ -19,8 +19,6 @@ package forge.gui.toolbox.itemmanager;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import forge.item.InventoryItem;
/** /**
* Simple container pane meant to contain item managers. * Simple container pane meant to contain item managers.
@@ -32,12 +30,13 @@ public final class ItemManagerContainer extends JScrollPane {
this(null); this(null);
} }
public ItemManagerContainer(ItemManager<? extends InventoryItem> itemManager) { public ItemManagerContainer(ItemManager<?> itemManager) {
super(itemManager, JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); super(null, JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
setBorder(null); setBorder(null);
setOpaque(false); setOpaque(false);
getViewport().setOpaque(false); getViewport().setOpaque(false);
setItemManager(itemManager);
} }
/** /**
@@ -46,7 +45,10 @@ public final class ItemManagerContainer extends JScrollPane {
* *
* @return ItemPoolView * @return ItemPoolView
*/ */
public void setItemManager(ItemManager<? extends InventoryItem> itemManager) { public void setItemManager(ItemManager<?> itemManager) {
if (itemManager != null) {
itemManager.initialize(); //ensure item manager is initialized
}
this.getViewport().setView(itemManager); this.getViewport().setView(itemManager);
} }
} }

View File

@@ -12,6 +12,7 @@ import forge.card.CardRulesPredicates;
import forge.card.CardRulesPredicates.Presets; import forge.card.CardRulesPredicates.Presets;
import forge.card.MagicColor; import forge.card.MagicColor;
import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FLabel;
import forge.item.InventoryItem;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.util.PredicateString.StringOp; import forge.util.PredicateString.StringOp;
@@ -132,6 +133,33 @@ public class SFilterUtil {
return Predicates.compose(textFilter, PaperCard.FN_GET_RULES); return Predicates.compose(textFilter, PaperCard.FN_GET_RULES);
} }
public static <T extends InventoryItem> Predicate<T> buildItemTextFilter(String text) {
if (text.trim().isEmpty()) {
return Predicates.alwaysTrue();
}
return new ItemTextPredicate<T>(text);
}
private static class ItemTextPredicate<T extends InventoryItem> implements Predicate<T> {
private final String[] splitText;
private ItemTextPredicate(String text) {
splitText = text.toLowerCase().replaceAll(",", "").replaceAll(" ", " ").split(" ");
}
@Override
public boolean apply(T input) {
String name = input.getName().toLowerCase();
for (String s : splitText) {
if (name.contains(s)) {
return true;
}
}
return false;
}
};
public static <T> Predicate<T> optimizedAnd(Predicate<T> p1, Predicate<T> p2) { public static <T> Predicate<T> optimizedAnd(Predicate<T> p1, Predicate<T> p2) {
return p1 == null ? p2 : (p2 == null ? p1 : Predicates.and(p1, p2)); return p1 == null ? p2 : (p2 == null ? p1 : Predicates.and(p1, p2));

View File

@@ -0,0 +1,32 @@
package forge.gui.toolbox.itemmanager;
import javax.swing.JPopupMenu;
import forge.gui.toolbox.itemmanager.filters.ItemFilter;
import forge.item.InventoryItem;
/**
* TODO: Write javadoc for this type.
*
*/
@SuppressWarnings("serial")
public final class SpellShopManager extends ItemManager<InventoryItem> {
public SpellShopManager(boolean wantUnique0) {
super(InventoryItem.class, wantUnique0);
}
@Override
protected void addDefaultFilters() {
CardManager.addDefaultFilters(this);
}
@Override
protected ItemFilter<? extends InventoryItem> createSearchFilter() {
return CardManager.createSearchFilter(this);
}
@Override
protected void buildFilterMenu(JPopupMenu menu) {
CardManager.buildFilterMenu(menu, this);
}
}

View File

@@ -13,7 +13,7 @@ import forge.item.PaperCard;
* *
*/ */
public class CardCMCFilter extends ValueRangeFilter<PaperCard> { public class CardCMCFilter extends ValueRangeFilter<PaperCard> {
public CardCMCFilter(ItemManager<PaperCard> itemManager0) { public CardCMCFilter(ItemManager<? super PaperCard> itemManager0) {
super(itemManager0); super(itemManager0);
} }
@@ -28,7 +28,7 @@ public class CardCMCFilter extends ValueRangeFilter<PaperCard> {
} }
@Override @Override
public Predicate<PaperCard> buildPredicate() { protected Predicate<PaperCard> buildPredicate() {
Predicate<CardRules> predicate = getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField.CMC); Predicate<CardRules> predicate = getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField.CMC);
if (predicate == null) { if (predicate == null) {
return Predicates.alwaysTrue(); return Predicates.alwaysTrue();

View File

@@ -19,7 +19,7 @@ import forge.item.PaperCard;
* *
*/ */
public class CardColorFilter extends StatTypeFilter<PaperCard> { public class CardColorFilter extends StatTypeFilter<PaperCard> {
public CardColorFilter(ItemManager<PaperCard> itemManager0) { public CardColorFilter(ItemManager<? super PaperCard> itemManager0) {
super(itemManager0); super(itemManager0);
} }
@@ -40,7 +40,7 @@ public class CardColorFilter extends StatTypeFilter<PaperCard> {
} }
@Override @Override
public final Predicate<PaperCard> buildPredicate() { protected final Predicate<PaperCard> buildPredicate() {
byte colors = 0; byte colors = 0;
if (buttonMap.get(StatTypes.WHITE).getSelected()) { if (buttonMap.get(StatTypes.WHITE).getSelected()) {

View File

@@ -22,10 +22,10 @@ public class CardFormatFilter extends ListLabelFilter<PaperCard> {
protected boolean allowReprints = true; protected boolean allowReprints = true;
protected final Set<GameFormat> formats = new HashSet<GameFormat>(); protected final Set<GameFormat> formats = new HashSet<GameFormat>();
public CardFormatFilter(ItemManager<PaperCard> itemManager0) { public CardFormatFilter(ItemManager<? super PaperCard> itemManager0) {
super(itemManager0); super(itemManager0);
} }
public CardFormatFilter(ItemManager<PaperCard> itemManager0, GameFormat format0) { public CardFormatFilter(ItemManager<? super PaperCard> itemManager0, GameFormat format0) {
super(itemManager0); super(itemManager0);
this.formats.add(format0); this.formats.add(format0);
} }
@@ -151,7 +151,7 @@ public class CardFormatFilter extends ListLabelFilter<PaperCard> {
} }
@Override @Override
public final Predicate<PaperCard> buildPredicate() { protected final Predicate<PaperCard> buildPredicate() {
List<Predicate<PaperCard>> predicates = new ArrayList<Predicate<PaperCard>>(); List<Predicate<PaperCard>> predicates = new ArrayList<Predicate<PaperCard>>();
for (GameFormat f : this.formats) { for (GameFormat f : this.formats) {
predicates.add(allowReprints ? f.getFilterRules() : f.getFilterPrinted()); predicates.add(allowReprints ? f.getFilterRules() : f.getFilterPrinted());

View File

@@ -13,7 +13,7 @@ import forge.item.PaperCard;
* *
*/ */
public class CardPowerFilter extends ValueRangeFilter<PaperCard> { public class CardPowerFilter extends ValueRangeFilter<PaperCard> {
public CardPowerFilter(ItemManager<PaperCard> itemManager0) { public CardPowerFilter(ItemManager<? super PaperCard> itemManager0) {
super(itemManager0); super(itemManager0);
} }
@@ -28,7 +28,7 @@ public class CardPowerFilter extends ValueRangeFilter<PaperCard> {
} }
@Override @Override
public Predicate<PaperCard> buildPredicate() { protected Predicate<PaperCard> buildPredicate() {
Predicate<CardRules> predicate = getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField.POWER); Predicate<CardRules> predicate = getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField.POWER);
if (predicate == null) { if (predicate == null) {
return Predicates.alwaysTrue(); return Predicates.alwaysTrue();

View File

@@ -16,10 +16,10 @@ import forge.quest.QuestWorld;
public class CardQuestWorldFilter extends CardFormatFilter { public class CardQuestWorldFilter extends CardFormatFilter {
private final Set<QuestWorld> questWorlds = new HashSet<QuestWorld>(); private final Set<QuestWorld> questWorlds = new HashSet<QuestWorld>();
public CardQuestWorldFilter(ItemManager<PaperCard> itemManager0) { public CardQuestWorldFilter(ItemManager<? super PaperCard> itemManager0) {
super(itemManager0); super(itemManager0);
} }
public CardQuestWorldFilter(ItemManager<PaperCard> itemManager0, QuestWorld questWorld0) { public CardQuestWorldFilter(ItemManager<? super PaperCard> itemManager0, QuestWorld questWorld0) {
super(itemManager0); super(itemManager0);
this.questWorlds.add(questWorld0); this.questWorlds.add(questWorld0);
this.formats.add(getQuestWorldFormat(questWorld0)); this.formats.add(getQuestWorldFormat(questWorld0));

View File

@@ -24,7 +24,7 @@ public class CardSearchFilter extends TextSearchFilter<PaperCard> {
private FComboBoxWrapper<String> cbSearchMode; private FComboBoxWrapper<String> cbSearchMode;
private FLabel btnName, btnType, btnText; private FLabel btnName, btnType, btnText;
public CardSearchFilter(ItemManager<PaperCard> itemManager0) { public CardSearchFilter(ItemManager<? super PaperCard> itemManager0) {
super(itemManager0); super(itemManager0);
} }
@@ -110,7 +110,7 @@ public class CardSearchFilter extends TextSearchFilter<PaperCard> {
} }
@Override @Override
public Predicate<PaperCard> buildPredicate() { protected Predicate<PaperCard> buildPredicate() {
return SFilterUtil.buildTextFilter( return SFilterUtil.buildTextFilter(
txtSearch.getText(), txtSearch.getText(),
cbSearchMode.getSelectedIndex() != 0, cbSearchMode.getSelectedIndex() != 0,

View File

@@ -16,7 +16,7 @@ import forge.item.PaperCard;
public class CardSetFilter extends CardFormatFilter { public class CardSetFilter extends CardFormatFilter {
private final Set<String> sets = new HashSet<String>(); private final Set<String> sets = new HashSet<String>();
public CardSetFilter(ItemManager<PaperCard> itemManager0, Collection<String> sets0, boolean allowReprints0) { public CardSetFilter(ItemManager<? super PaperCard> itemManager0, Collection<String> sets0, boolean allowReprints0) {
super(itemManager0); super(itemManager0);
this.sets.addAll(sets0); this.sets.addAll(sets0);
this.formats.add(new GameFormat(null, this.sets, null)); this.formats.add(new GameFormat(null, this.sets, null));

View File

@@ -13,7 +13,7 @@ import forge.item.PaperCard;
* *
*/ */
public class CardToughnessFilter extends ValueRangeFilter<PaperCard> { public class CardToughnessFilter extends ValueRangeFilter<PaperCard> {
public CardToughnessFilter(ItemManager<PaperCard> itemManager0) { public CardToughnessFilter(ItemManager<? super PaperCard> itemManager0) {
super(itemManager0); super(itemManager0);
} }
@@ -28,7 +28,7 @@ public class CardToughnessFilter extends ValueRangeFilter<PaperCard> {
} }
@Override @Override
public Predicate<PaperCard> buildPredicate() { protected Predicate<PaperCard> buildPredicate() {
Predicate<CardRules> predicate = getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField.TOUGHNESS); Predicate<CardRules> predicate = getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField.TOUGHNESS);
if (predicate == null) { if (predicate == null) {
return Predicates.alwaysTrue(); return Predicates.alwaysTrue();

View File

@@ -19,7 +19,7 @@ import forge.item.PaperCard;
* *
*/ */
public class CardTypeFilter extends StatTypeFilter<PaperCard> { public class CardTypeFilter extends StatTypeFilter<PaperCard> {
public CardTypeFilter(ItemManager<PaperCard> itemManager0) { public CardTypeFilter(ItemManager<? super PaperCard> itemManager0) {
super(itemManager0); super(itemManager0);
} }
@@ -40,7 +40,7 @@ public class CardTypeFilter extends StatTypeFilter<PaperCard> {
} }
@Override @Override
public final Predicate<PaperCard> buildPredicate() { protected final Predicate<PaperCard> buildPredicate() {
final List<Predicate<CardRules>> types = new ArrayList<Predicate<CardRules>>(); final List<Predicate<CardRules>> types = new ArrayList<Predicate<CardRules>>();
for (SItemManagerUtil.StatTypes s : buttonMap.keySet()) { for (SItemManagerUtil.StatTypes s : buttonMap.keySet()) {

View File

@@ -44,13 +44,13 @@ public abstract class ItemFilter<T extends InventoryItem> {
cb.setFocusable(false); cb.setFocusable(false);
} }
protected final ItemManager<T> itemManager; protected final ItemManager<? super T> itemManager;
private FilterPanel panel; private FilterPanel panel;
private Widget widget; private Widget widget;
private final JCheckBox chkEnable = new JCheckBox(); private final JCheckBox chkEnable = new JCheckBox();
private RemoveButton btnRemove; private RemoveButton btnRemove;
protected ItemFilter(ItemManager<T> itemManager0) { protected ItemFilter(ItemManager<? super T> itemManager0) {
this.itemManager = itemManager0; this.itemManager = itemManager0;
this.chkEnable.setSelected(true); //enable by default this.chkEnable.setSelected(true); //enable by default
} }
@@ -119,13 +119,28 @@ public abstract class ItemFilter<T extends InventoryItem> {
} }
protected void applyChange() { protected void applyChange() {
this.itemManager.buildFilterPredicate(); this.itemManager.applyFilters();
}
public <U extends InventoryItem> Predicate<U> buildPredicate(Class<U> genericType) {
final Predicate<T> predicate = this.buildPredicate();
return new Predicate<U>() {
@SuppressWarnings("unchecked")
@Override
public boolean apply(U item) {
try {
return predicate.apply((T)item);
}
catch (Exception ex) {
return false; //if can't cast U to T, filter item out
}
}
};
} }
public abstract ItemFilter<T> createCopy(); public abstract ItemFilter<T> createCopy();
public abstract boolean isEmpty(); public abstract boolean isEmpty();
public abstract void reset(); public abstract void reset();
public abstract Predicate<T> buildPredicate();
public void afterFiltersApplied() { public void afterFiltersApplied() {
} }
@@ -139,6 +154,7 @@ public abstract class ItemFilter<T extends InventoryItem> {
protected abstract void buildWidget(JPanel widget); protected abstract void buildWidget(JPanel widget);
protected abstract void doWidgetLayout(LayoutHelper helper); protected abstract void doWidgetLayout(LayoutHelper helper);
protected abstract Predicate<T> buildPredicate();
@SuppressWarnings("serial") @SuppressWarnings("serial")
private class FilterPanel extends JPanel { private class FilterPanel extends JPanel {

View File

@@ -17,7 +17,7 @@ import forge.util.TextUtil;
public abstract class ListLabelFilter<T extends InventoryItem> extends ItemFilter<T> { public abstract class ListLabelFilter<T extends InventoryItem> extends ItemFilter<T> {
private FLabel label; private FLabel label;
protected ListLabelFilter(ItemManager<T> itemManager0) { protected ListLabelFilter(ItemManager<? super T> itemManager0) {
super(itemManager0); super(itemManager0);
} }

View File

@@ -18,7 +18,7 @@ import forge.util.ItemPoolView;
public abstract class StatTypeFilter<T extends InventoryItem> extends ToggleButtonsFilter<T> { public abstract class StatTypeFilter<T extends InventoryItem> extends ToggleButtonsFilter<T> {
protected final Map<SItemManagerUtil.StatTypes, FLabel> buttonMap; protected final Map<SItemManagerUtil.StatTypes, FLabel> buttonMap;
public StatTypeFilter(ItemManager<T> itemManager0) { public StatTypeFilter(ItemManager<? super T> itemManager0) {
super(itemManager0); super(itemManager0);
buttonMap = new HashMap<SItemManagerUtil.StatTypes, FLabel>(); buttonMap = new HashMap<SItemManagerUtil.StatTypes, FLabel>();
} }
@@ -79,7 +79,7 @@ public abstract class StatTypeFilter<T extends InventoryItem> extends ToggleButt
@Override @Override
public void afterFiltersApplied() { public void afterFiltersApplied() {
final ItemPoolView<T> items = itemManager.getFilteredItems(); final ItemPoolView<? super T> items = itemManager.getFilteredItems();
for (Map.Entry<SItemManagerUtil.StatTypes, FLabel> btn : buttonMap.entrySet()) { for (Map.Entry<SItemManagerUtil.StatTypes, FLabel> btn : buttonMap.entrySet()) {
int count = items.countAll(Predicates.compose(btn.getKey().predicate, PaperCard.FN_GET_RULES), PaperCard.class); int count = items.countAll(Predicates.compose(btn.getKey().predicate, PaperCard.FN_GET_RULES), PaperCard.class);
btn.getValue().setText(String.valueOf(count)); btn.getValue().setText(String.valueOf(count));

View File

@@ -5,26 +5,37 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter; import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.Timer; import javax.swing.Timer;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import forge.gui.toolbox.FTextField; import forge.gui.toolbox.FTextField;
import forge.gui.toolbox.LayoutHelper; import forge.gui.toolbox.LayoutHelper;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.gui.toolbox.itemmanager.SFilterUtil;
import forge.item.InventoryItem; import forge.item.InventoryItem;
/** /**
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
*/ */
public abstract class TextSearchFilter<T extends InventoryItem> extends ItemFilter<T> { public class TextSearchFilter<T extends InventoryItem> extends ItemFilter<T> {
protected FTextField txtSearch; protected FTextField txtSearch;
protected TextSearchFilter(ItemManager<T> itemManager0) { public TextSearchFilter(ItemManager<? super T> itemManager0) {
super(itemManager0); super(itemManager0);
} }
@Override
public ItemFilter<T> createCopy() {
TextSearchFilter<T> copy = new TextSearchFilter<T>(itemManager);
copy.getWidget(); //initialize widget
copy.txtSearch.setText(this.txtSearch.getText());
return copy;
}
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return txtSearch.isEmpty(); return txtSearch.isEmpty();
@@ -108,4 +119,13 @@ public abstract class TextSearchFilter<T extends InventoryItem> extends ItemFilt
applyChange(); applyChange();
} }
}); });
@Override
protected Predicate<T> buildPredicate() {
String text = txtSearch.getText();
if (text.trim().isEmpty()) {
return Predicates.alwaysTrue();
}
return SFilterUtil.buildItemTextFilter(text);
}
} }

View File

@@ -24,7 +24,7 @@ public abstract class ToggleButtonsFilter<T extends InventoryItem> extends ItemF
protected boolean lockFiltering; protected boolean lockFiltering;
private final ArrayList<FLabel> buttons = new ArrayList<FLabel>(); private final ArrayList<FLabel> buttons = new ArrayList<FLabel>();
protected ToggleButtonsFilter(ItemManager<T> itemManager0) { protected ToggleButtonsFilter(ItemManager<? super T> itemManager0) {
super(itemManager0); super(itemManager0);
} }

View File

@@ -27,7 +27,7 @@ public abstract class ValueRangeFilter<T extends InventoryItem> extends ItemFilt
private FLabel label; private FLabel label;
private FSpinner lowerBound, upperBound; private FSpinner lowerBound, upperBound;
protected ValueRangeFilter(ItemManager<T> itemManager0) { protected ValueRangeFilter(ItemManager<? super T> itemManager0) {
super(itemManager0); super(itemManager0);
} }