diff --git a/forge-core/src/main/java/forge/util/storage/StorageBase.java b/forge-core/src/main/java/forge/util/storage/StorageBase.java index 03e5afa3347..9b5bfb40578 100644 --- a/forge-core/src/main/java/forge/util/storage/StorageBase.java +++ b/forge-core/src/main/java/forge/util/storage/StorageBase.java @@ -19,7 +19,6 @@ package forge.util.storage; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -39,9 +38,7 @@ import forge.util.IItemReader; */ public class StorageBase implements IStorage { protected final Map map; - - public final static StorageBase emptyMap = new StorageBase("Empty", new HashMap()); - public final String name; + private final String name; public StorageBase(final String name, final IItemReader io) { this.name = name; @@ -64,8 +61,20 @@ public class StorageBase implements IStorage { } @Override - public Iterator iterator() { - return this.map.values().iterator(); + public final Iterator iterator() { + final IStorage> folders = getFolders(); + if (folders == null) { //if no folders, just return map iterator + return this.map.values().iterator(); + } + //otherwise return iterator for list containing folder items followed by map's items + ArrayList items = new ArrayList(); + for (IStorage folder : folders) { + for (T item : folder) { + items.add(item); + } + } + items.addAll(this.map.values()); + return items.iterator(); } @Override @@ -75,12 +84,16 @@ public class StorageBase implements IStorage { @Override public int size() { - return this.map.size(); + int size = this.map.size(); + if (this.getFolders() != null) { + size += this.getFolders().size(); + } + return size; } @Override public T find(Predicate condition) { - return Iterables.tryFind(map.values(), condition).orNull(); + return Iterables.tryFind(this, condition).orNull(); } @Override @@ -93,11 +106,9 @@ public class StorageBase implements IStorage { throw new UnsupportedOperationException("This is a read-only storage"); } - // we don't have nested folders unless that's overridden in a derived class - @SuppressWarnings("unchecked") @Override public IStorage> getFolders() { - return (IStorage>) emptyMap; + return null; //no nested folders unless getFolders() overridden in a derived class } /* (non-Javadoc) @@ -105,7 +116,6 @@ public class StorageBase implements IStorage { */ @Override public String getName() { - // TODO Auto-generated method stub return name; } } diff --git a/forge-core/src/main/java/forge/util/storage/StorageImmediatelySerialized.java b/forge-core/src/main/java/forge/util/storage/StorageImmediatelySerialized.java index ca3ab2a6d7a..154ddf15d95 100644 --- a/forge-core/src/main/java/forge/util/storage/StorageImmediatelySerialized.java +++ b/forge-core/src/main/java/forge/util/storage/StorageImmediatelySerialized.java @@ -87,6 +87,6 @@ public class StorageImmediatelySerialized extends StorageBase { */ @Override public IStorage> getFolders() { - return subfolders == null ? super.getFolders() : subfolders; + return subfolders; } } diff --git a/forge-gui/src/main/java/forge/gui/deckchooser/DeckgenUtil.java b/forge-gui/src/main/java/forge/gui/deckchooser/DeckgenUtil.java index 67e2b363e08..cf5d0e68e03 100644 --- a/forge-gui/src/main/java/forge/gui/deckchooser/DeckgenUtil.java +++ b/forge-gui/src/main/java/forge/gui/deckchooser/DeckgenUtil.java @@ -6,9 +6,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map.Entry; -import java.util.Random; - -import javax.swing.JList; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; @@ -23,6 +20,7 @@ import forge.deck.generation.DeckGenerator5Color; import forge.deck.generation.DeckGeneratorBase; import forge.deck.generation.DeckGeneratorMonoColor; import forge.gui.toolbox.FOptionPane; +import forge.gui.toolbox.itemmanager.DeckManager; import forge.item.PaperCard; import forge.properties.ForgePreferences.FPref; import forge.quest.QuestController; @@ -105,32 +103,6 @@ public class DeckgenUtil { return deck; } - /** - * Gets a user deck. - * - * @param selection {java.lang.String} - * @return {@link forge.deck.Deck} - */ - public static Deck getConstructedDeck(final String selection) { - IStorage path = Singletons.getModel().getDecks().getConstructed(); - String name = selection; - int idxSlash = name.indexOf('/'); - while (idxSlash > 0 && path != null) { - String sf = name.substring(0, idxSlash).trim(); - path = path.getFolders().get(sf); - name = name.substring(idxSlash+1).trim(); - idxSlash = name.indexOf('/'); - }; - if (path == null) { - throw new IllegalArgumentException("Path not found - " + selection); - } - return path.get(name); - } - - public static Deck getPreconDeck(String selection) { - return QuestController.getPrecons().get(selection).getDeck(); - } - public static QuestEvent getQuestEvent(final String name) { QuestController qCtrl = Singletons.getModel().getQuest(); for (QuestEventChallenge challenge : qCtrl.getChallenges()) { @@ -190,40 +162,37 @@ public class DeckgenUtil { return allQuestDecks.get(rand); } - public static int[] randomSelectColors(int maxColors) { + public static void randomSelectColors(final DeckManager deckManager) { + final int size = deckManager.getItemCount(); + if (size == 0) { return; } + int nColors = MyRandom.getRandom().nextInt(3) + 1; - int[] result = new int[nColors]; + Integer[] indices = new Integer[nColors]; for (int i = 0; i < nColors; i++) { - int next = MyRandom.getRandom().nextInt(maxColors); + int next = MyRandom.getRandom().nextInt(size); boolean isUnique = true; for (int j = 0; j < i; j++) { - if (result[j] == next) { + if (indices[j] == next) { isUnique = false; break; } } if (isUnique) { - result[i] = next; + indices[i] = next; } else { i--; // try over with this number } } - return result; + deckManager.setSelectedIndices(indices); } - /** @param lst0 {@link javax.swing.JList} */ - public static void randomSelect(final JList lst0) { - final int size = lst0.getModel().getSize(); + public static void randomSelect(final DeckManager deckManager) { + final int size = deckManager.getItemCount(); + if (size == 0) { return; } - if (size > 0) { - final Random r = new Random(); - final int i = r.nextInt(size); - - lst0.setSelectedIndex(i); - lst0.ensureIndexIsVisible(lst0.getSelectedIndex()); - } + deckManager.setSelectedIndex(MyRandom.getRandom().nextInt(size)); } /** Shows decklist dialog for a given deck. diff --git a/forge-gui/src/main/java/forge/gui/deckchooser/FDeckChooser.java b/forge-gui/src/main/java/forge/gui/deckchooser/FDeckChooser.java index 469f14e9c46..6c1c4569886 100644 --- a/forge-gui/src/main/java/forge/gui/deckchooser/FDeckChooser.java +++ b/forge-gui/src/main/java/forge/gui/deckchooser/FDeckChooser.java @@ -1,298 +1,286 @@ package forge.gui.deckchooser; -import java.awt.Color; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import javax.swing.BorderFactory; -import javax.swing.JList; import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.ListSelectionModel; -import javax.swing.ScrollPaneConstants; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; - import net.miginfocom.swing.MigLayout; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.tuple.ImmutablePair; - -import com.google.common.base.Function; - import forge.Command; import forge.Singletons; import forge.deck.Deck; +import forge.deck.DeckBase; +import forge.game.GameType; import forge.game.player.RegisteredPlayer; import forge.gui.MouseUtil; import forge.gui.MouseUtil.MouseCursor; import forge.gui.deckchooser.DecksComboBox.DeckType; import forge.gui.toolbox.FLabel; -import forge.gui.toolbox.FList; -import forge.gui.toolbox.FScrollPane; -import forge.gui.toolbox.FSkin; +import forge.gui.toolbox.itemmanager.DeckManager; +import forge.gui.toolbox.itemmanager.ItemManagerContainer; +import forge.item.PreconDeck; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; import forge.quest.QuestController; import forge.quest.QuestEvent; import forge.quest.QuestEventChallenge; import forge.quest.QuestUtil; -import forge.util.IHasName; -import forge.util.storage.IStorage; @SuppressWarnings("serial") public class FDeckChooser extends JPanel implements IDecksComboBoxListener { - private final Color BORDER_COLOR = FSkin.getColor(FSkin.Colors.CLR_TEXT).getColor().darker(); - private boolean isUISetup = false; private DecksComboBox decksComboBox; private DeckType selectedDeckType = DeckType.COLOR_DECK; - private List selectedDecks = new ArrayList(); - private final JList lstDecks = new FList(); + private final DeckManager lstDecks = new DeckManager(GameType.Constructed); private final FLabel btnRandom = new FLabel.ButtonBuilder().text("Random").fontSize(16).build(); - private final JScrollPane scrDecks = - new FScrollPane(lstDecks, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - private final FLabel lblDecklist = new FLabel.Builder().text("Double click deck for its decklist.").fontSize(12).build(); private boolean isAi; private final ForgePreferences prefs = Singletons.getModel().getPreferences(); private FPref stateSetting = null; - - private Function>, Void> onDeckSelected; - public void setChangeListener(Function>, Void> fn) { - onDeckSelected = fn; - } - - private final MouseAdapter madDecklist = new MouseAdapter() { - @Override - public void mouseClicked(final MouseEvent e) { - if (MouseEvent.BUTTON1 == e.getButton() && e.getClickCount() == 2) { - if (selectedDeckType != DeckType.COLOR_DECK && selectedDeckType != DeckType.THEME_DECK) { - DeckgenUtil.showDecklist(getDeck()); - } - } - } - }; - - private final ListSelectionListener selChangeListener = new ListSelectionListener(){ - @Override - public void valueChanged(ListSelectionEvent e) { - if( null != onDeckSelected ) - onDeckSelected.apply(ImmutablePair.of(selectedDeckType, getLstDecks().getSelectedValuesList())); - } - }; public FDeckChooser(final String titleText, boolean forAi, boolean canSwitchType) { setOpaque(false); isAi = forAi; + lstDecks.setItemActivateCommand(new Command() { + @Override + public void run() { + if (selectedDeckType != DeckType.COLOR_DECK && selectedDeckType != DeckType.THEME_DECK) { + DeckgenUtil.showDecklist(getDeck()); + } + } + }); } public FDeckChooser(String titleText, boolean forAi) { this(titleText, forAi, false); } - public void initialize(FPref savedStateSetting, DeckType defaultDeckType) { - stateSetting = savedStateSetting; - selectedDeckType = defaultDeckType; + public void initialize() { + initialize(DeckType.COLOR_DECK); } public void initialize(DeckType defaultDeckType) { initialize(null, defaultDeckType); } - public void initialize() { - initialize(DeckType.COLOR_DECK); + public void initialize(FPref savedStateSetting, DeckType defaultDeckType) { + stateSetting = savedStateSetting; + selectedDeckType = defaultDeckType; } - private JList getLstDecks() { return lstDecks; } - private FLabel getBtnRandom() { return btnRandom; } + public DeckType getSelectedDeckType() { return selectedDeckType; } + public void setSelectedDeckType(DeckType selectedDeckType0) { + if (selectedDeckType != selectedDeckType0) { + selectedDeckType = selectedDeckType0; + decksComboBox.refresh(selectedDeckType0); + } + } + + public DeckManager getLstDecks() { return lstDecks; } + private FLabel getBtnRandom() { return btnRandom; } + + private void updateCustom() { + lblDecklist.setVisible(true); + lstDecks.setAllowMultipleSelections(false); + + lstDecks.setPool(Singletons.getModel().getDecks().getConstructed()); + lstDecks.update(); + + getBtnRandom().setText("Random deck"); + getBtnRandom().setCommand(new Command() { + @Override + public void run() { + DeckgenUtil.randomSelect(lstDecks); + } + }); + + lstDecks.setSelectedIndex(0); + } + + //Deck that generates its card pool via some algorithm + private abstract class DeckGenerator extends Deck { + public DeckGenerator(final String name0) { + super(name0); + } + + @Override + protected DeckBase newInstance(final String name0) { + final DeckGenerator deckGen = this; + return new DeckGenerator(name0) { + @Override + public Deck generateDeck() { + return deckGen.generateDeck(); + } + }; + } + + public abstract Deck generateDeck(); + } + + private class ColorDeckGenerator extends DeckGenerator { + public ColorDeckGenerator(String name0) { + super(name0); + } + + @Override + public Deck generateDeck() { + List selection = new ArrayList(); + for (Deck deck : lstDecks.getSelectedItems()) { + selection.add(deck.getName()); + } + if (DeckgenUtil.colorCheck(selection)) { + return DeckgenUtil.buildColorDeck(selection, isAi); + } + return null; + } + } private void updateColors() { - final JList lst = getLstDecks(); - lst.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + lblDecklist.setVisible(false); + lstDecks.setAllowMultipleSelections(true); - final String[] listData = new String[] {"Random 1", "Random 2", "Random 3", "Black", "Blue", "Green", "Red", "White"}; - lst.setListData(listData); - lst.setName(DeckgenUtil.DeckTypes.COLORS.toString()); + ArrayList decks = new ArrayList(); + decks.add(new ColorDeckGenerator("Random 1")); + decks.add(new ColorDeckGenerator("Random 2")); + decks.add(new ColorDeckGenerator("Random 3")); + decks.add(new ColorDeckGenerator("White")); + decks.add(new ColorDeckGenerator("Blue")); + decks.add(new ColorDeckGenerator("Black")); + decks.add(new ColorDeckGenerator("Red")); + decks.add(new ColorDeckGenerator("Green")); - lst.removeListSelectionListener(selChangeListener); - lst.addListSelectionListener(selChangeListener); - - lst.removeMouseListener(madDecklist); - lst.addMouseListener(madDecklist); + lstDecks.setPool(decks); + lstDecks.update(true); getBtnRandom().setText("Random colors"); getBtnRandom().setCommand(new Command() { - @Override public void run() { lst.setSelectedIndices(DeckgenUtil.randomSelectColors(8)); } }); + @Override + public void run() { + DeckgenUtil.randomSelectColors(lstDecks); + } + }); - if (listData.length > 0) { - // default selection = basic two color deck - lst.setSelectedIndices(getSelectedDeckIndices(Arrays.asList(listData), new int[]{0, 1})); - lst.ensureIndexIsVisible(lst.getSelectedIndices()[0]); + // default selection = basic two color deck + lstDecks.setSelectedIndices(new Integer[]{0, 1}); + } + + private class ThemeDeckGenerator extends DeckGenerator { + public ThemeDeckGenerator(String name0) { + super(name0); + } + + @Override + public Deck generateDeck() { + return DeckgenUtil.buildThemeDeck(this.getName()); } } private void updateThemes() { - final JList lst = getLstDecks(); - lst.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + lblDecklist.setVisible(false); + lstDecks.setAllowMultipleSelections(false); - lst.removeListSelectionListener(selChangeListener); - lst.addListSelectionListener(selChangeListener); - - lst.removeMouseListener(madDecklist); - lst.addMouseListener(madDecklist); + ArrayList decks = new ArrayList(); + for (final String s : GenerateThemeDeck.getThemeNames()) { + decks.add(new ThemeDeckGenerator(s)); + } - final List listData = new ArrayList(); - for (final String s : GenerateThemeDeck.getThemeNames()) { listData.add(s); } - - lst.setListData(listData.toArray(ArrayUtils.EMPTY_STRING_ARRAY)); - lst.setName(DeckgenUtil.DeckTypes.THEMES.toString()); - lst.removeMouseListener(madDecklist); + lstDecks.setPool(decks); + lstDecks.update(true); getBtnRandom().setText("Random deck"); getBtnRandom().setCommand(new Command() { - @Override public void run() { DeckgenUtil.randomSelect(lst); } }); + @Override + public void run() { + DeckgenUtil.randomSelect(lstDecks); + } + }); - if (listData.size() > 0) { - lst.setSelectedIndices(getSelectedDeckIndices(listData, new int[]{0})); - lst.ensureIndexIsVisible(lst.getSelectedIndices()[0]); - } - } - - private void updateCustom() { - final JList lst = getLstDecks(); - lst.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - - final List listData = new ArrayList(); - addDecksRecursive(Singletons.getModel().getDecks().getConstructed(), listData, null); - - lst.setListData(listData.toArray(ArrayUtils.EMPTY_STRING_ARRAY)); - lst.setName(DeckgenUtil.DeckTypes.CUSTOM.toString()); - - lst.removeListSelectionListener(selChangeListener); - lst.addListSelectionListener(selChangeListener); - lst.removeMouseListener(madDecklist); - lst.addMouseListener(madDecklist); - - getBtnRandom().setText("Random deck"); - getBtnRandom().setCommand(new Command() { - @Override public void run() { DeckgenUtil.randomSelect(lst); } }); - - if (listData.size() > 0) { - lst.setSelectedIndices(getSelectedDeckIndices(listData, new int[]{0})); - lst.ensureIndexIsVisible(lst.getSelectedIndices()[0]); - } - } - - private void addDecksRecursive(IStorage node, List customNames, String namePrefix ) { - String path = namePrefix == null ? "" : namePrefix + " / "; - for (final String fn : node.getFolders().getItemNames() ) - { - IStorage f = node.getFolders().get(fn); - addDecksRecursive(f, customNames, path + fn); - } - for (final T d : node) { customNames.add(path + d.getName()); } + lstDecks.setSelectedIndex(0); } private void updatePrecons() { - final JList lst = getLstDecks(); - lst.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + lblDecklist.setVisible(true); + lstDecks.setAllowMultipleSelections(false); - final List listData = new ArrayList(); - addDecksRecursive(QuestController.getPrecons(), listData, null); + ArrayList decks = new ArrayList(); + for (final PreconDeck preconDeck : QuestController.getPrecons()) { + decks.add(preconDeck.getDeck()); + } - lst.setListData(listData.toArray(ArrayUtils.EMPTY_STRING_ARRAY)); - lst.setName(DeckgenUtil.DeckTypes.PRECON.toString()); - - lst.removeListSelectionListener(selChangeListener); - lst.addListSelectionListener(selChangeListener); - lst.removeMouseListener(madDecklist); - lst.addMouseListener(madDecklist); + lstDecks.setPool(decks); + lstDecks.update(false, true); getBtnRandom().setText("Random deck"); getBtnRandom().setCommand(new Command() { - @Override public void run() { DeckgenUtil.randomSelect(lst); } }); + @Override + public void run() { + DeckgenUtil.randomSelect(lstDecks); + } + }); - if (listData.size() > 0) { - lst.setSelectedIndices(getSelectedDeckIndices(listData, new int[]{0})); - lst.ensureIndexIsVisible(lst.getSelectedIndices()[0]); + lstDecks.setSelectedIndex(0); + } + + private class QuestEventDeckGenerator extends DeckGenerator { + public QuestEventDeckGenerator(String name0) { + super(name0); + } + + @Override + public Deck generateDeck() { + return DeckgenUtil.getQuestEvent(this.getName()).getEventDeck(); } } private void updateQuestEvents() { - final JList lst = getLstDecks(); - lst.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - - final List listData = new ArrayList(); + lblDecklist.setVisible(true); + lstDecks.setAllowMultipleSelections(false); + ArrayList decks = new ArrayList(); QuestController quest = Singletons.getModel().getQuest(); for (QuestEvent e : quest.getDuelsManager().getAllDuels()) { - listData.add(e.getName()); + decks.add(new QuestEventDeckGenerator(e.getName())); } - for (QuestEvent e : quest.getChallenges()) { - listData.add(e.getTitle()); + decks.add(new QuestEventDeckGenerator(e.getTitle())); } - lst.setListData(listData.toArray(ArrayUtils.EMPTY_STRING_ARRAY)); - lst.setName(DeckgenUtil.DeckTypes.QUESTEVENTS.toString()); - - lst.removeListSelectionListener(selChangeListener); - lst.addListSelectionListener(selChangeListener); - lst.removeMouseListener(madDecklist); - lst.addMouseListener(madDecklist); + lstDecks.setPool(decks); + lstDecks.update(true); getBtnRandom().setText("Random event"); getBtnRandom().setCommand(new Command() { - @Override public void run() { DeckgenUtil.randomSelect(lst); } }); + @Override + public void run() { + DeckgenUtil.randomSelect(lstDecks); + } + }); - if (listData.size() > 0) { - lst.setSelectedIndices(getSelectedDeckIndices(listData, new int[]{0})); - lst.ensureIndexIsVisible(lst.getSelectedIndices()[0]); - } + lstDecks.setSelectedIndex(0); } public Deck getDeck() { - JList lst0 = getLstDecks(); - final List selection = lst0.getSelectedValuesList(); - - if (selection.isEmpty()) { return null; } - - // Special branch for quest events - if (lst0.getName().equals(DeckgenUtil.DeckTypes.QUESTEVENTS.toString())) { - return DeckgenUtil.getQuestEvent(selection.get(0)).getEventDeck(); + Deck deck = lstDecks.getSelectedItem(); + if (deck instanceof DeckGenerator) { + return ((DeckGenerator)deck).generateDeck(); } - if (lst0.getName().equals(DeckgenUtil.DeckTypes.COLORS.toString()) && DeckgenUtil.colorCheck(selection)) { - return DeckgenUtil.buildColorDeck(selection, isAi); - } - if (lst0.getName().equals(DeckgenUtil.DeckTypes.THEMES.toString())) { - return DeckgenUtil.buildThemeDeck(selection.get(0)); - } - if (lst0.getName().equals(DeckgenUtil.DeckTypes.CUSTOM.toString())) { - return DeckgenUtil.getConstructedDeck(selection.get(0)); - } - if (lst0.getName().equals(DeckgenUtil.DeckTypes.PRECON.toString())) { - return DeckgenUtil.getPreconDeck(selection.get(0)); - } - return null; + return deck; } /** Generates deck from current list selection(s). */ public RegisteredPlayer getPlayer() { - if (getLstDecks().getSelectedValuesList().isEmpty()) { return null; } + if (lstDecks.getSelectedIndex() < 0) { return null; } // Special branch for quest events - if (getLstDecks().getName().equals(DeckgenUtil.DeckTypes.QUESTEVENTS.toString())) { - QuestEvent event = DeckgenUtil.getQuestEvent(getLstDecks().getSelectedValuesList().get(0)); + if (selectedDeckType == DeckType.QUEST_OPPONENT_DECK) { + QuestEvent event = DeckgenUtil.getQuestEvent(lstDecks.getSelectedItem().getName()); RegisteredPlayer result = new RegisteredPlayer(event.getEventDeck()); - if( event instanceof QuestEventChallenge ) { + if (event instanceof QuestEventChallenge) { result.setStartingLife(((QuestEventChallenge) event).getAiLife()); } result.setCardsOnBattlefield(QuestUtil.getComputerStartingCards(event)); @@ -310,10 +298,10 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener { setupUI(); removeAll(); this.setLayout(new MigLayout("insets 0, gap 0, flowy")); - this.add(decksComboBox.getComponent(), "w 10:100%, h 30px!"); - this.add(scrDecks, "w 10:100%, growy, pushy"); - this.add(btnRandom, "w 10:100%, h 26px!, gap 0 0 2px 0"); - this.add(lblDecklist, "w 10:100%, h 20px!, , gap 0 0 5px 0"); + this.add(decksComboBox.getComponent(), "w 10:100%, h 30px!, gapbottom 3px"); + this.add(new ItemManagerContainer(lstDecks), "w 10:100%, growy, pushy"); + this.add(btnRandom, "w 10:100%, h 26px!, gaptop 3px"); + this.add(lblDecklist, "w 10:100%, h 20px!, gaptop 5px"); if (isShowing()) { validate(); repaint(); @@ -346,9 +334,6 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener { isUISetup = true; // core UI components. decksComboBox = new DecksComboBox(); - // set component styles. - lstDecks.setOpaque(false); - scrDecks.setBorder(BorderFactory.createMatteBorder(0, 1, 1, 1, BORDER_COLOR)); // monitor events generated by these components. decksComboBox.addListener(this); // now everything is in place, fire initial populate event. @@ -358,29 +343,26 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener { } private void refreshDecksList(DeckType deckType) { + selectedDeckType = deckType; + lstDecks.setCaption(deckType.toString()); + switch (deckType) { case CUSTOM_DECK: updateCustom(); - lblDecklist.setVisible(true); break; case COLOR_DECK: updateColors(); - lblDecklist.setVisible(false); break; case THEME_DECK: updateThemes(); - lblDecklist.setVisible(false); break; case QUEST_OPPONENT_DECK: updateQuestEvents(); - lblDecklist.setVisible(true); break; case PRECONSTRUCTED_DECK: updatePrecons(); - lblDecklist.setVisible(true); break; } - selectedDeckType = deckType; } private final String SELECTED_DECK_DELIMITER = "::"; @@ -396,12 +378,14 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener { private String getState() { String deckType = decksComboBox.getDeckType().name(); String state = deckType; - final JList lst = getLstDecks(); state += ";"; - for (String value : lst.getSelectedValuesList()) { - state += value + SELECTED_DECK_DELIMITER; + Iterable selectedDecks = lstDecks.getSelectedItems(); + if (selectedDecks != null) { + for (Deck deck : selectedDecks) { + state += deck + SELECTED_DECK_DELIMITER; + } + state = state.substring(0, state.length() - SELECTED_DECK_DELIMITER.length()); } - state = state.substring(0, state.length()-SELECTED_DECK_DELIMITER.length()); return state; } @@ -409,31 +393,40 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener { public final String getStateForLabel() { String deckType = decksComboBox.getDeckType().toString(); String state = deckType; - final JList lst = getLstDecks(); state += ": "; - for (String value : lst.getSelectedValuesList()) { - state += value + ", "; + Iterable selectedDecks = lstDecks.getSelectedItems(); + if (selectedDecks != null) { + for (Deck deck : selectedDecks) { + state += deck + ", "; + } + state = state.substring(0, state.length() - 2); } - state = state.substring(0, state.length() - 2); return state; } private void restoreSavedState() { - if (stateSetting != null) { - String savedState = prefs.getPref(stateSetting); - selectedDeckType = getDeckTypeFromSavedState(savedState); - selectedDecks = getSelectedDecksFromSavedState(savedState); + if (stateSetting == null) { + //if can't restore saved state, just refresh decks combo box + decksComboBox.refresh(selectedDeckType); + return; } + + String savedState = prefs.getPref(stateSetting); + selectedDeckType = getDeckTypeFromSavedState(savedState); + decksComboBox.refresh(selectedDeckType); + lstDecks.setSelectedStrings(getSelectedDecksFromSavedState(savedState)); } private DeckType getDeckTypeFromSavedState(String savedState) { try { if (StringUtils.isBlank(savedState)) { return selectedDeckType; - } else { + } + else { return DeckType.valueOf(savedState.split(";")[0]); } - } catch (IllegalArgumentException ex) { + } + catch (IllegalArgumentException ex) { System.err.println(ex.getMessage() + ". Using default : " + selectedDeckType); return selectedDeckType; } @@ -443,31 +436,14 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener { try { if (StringUtils.isBlank(savedState)) { return new ArrayList(); - } else { + } + else { return Arrays.asList(savedState.split(";")[1].split(SELECTED_DECK_DELIMITER)); } - } catch (Exception ex) { + } + catch (Exception ex) { System.err.println(ex + " [savedState=" + savedState + "]"); return new ArrayList(); } } - - private int[] getSelectedDeckIndices(List listData, int[] defaultSelection) { - if (selectedDecks != null && selectedDecks.size() > 0) { - List selectedIndices = new ArrayList(); - for (String deck : selectedDecks) { - int index = listData.indexOf(deck); - if (index >= 0) { - selectedIndices.add(index); - } - } - int[] indices = ArrayUtils.toPrimitive(selectedIndices.toArray(new Integer[selectedIndices.size()])); - if (indices.length == 0) { indices = defaultSelection; } - // only do this once at startup. - selectedDecks = null; - return indices; - } else { - return defaultSelection; - } - } } diff --git a/forge-gui/src/main/java/forge/gui/home/sanctioned/VSubmenuConstructed.java b/forge-gui/src/main/java/forge/gui/home/sanctioned/VSubmenuConstructed.java index 17cf53e40bc..6655650cd40 100644 --- a/forge-gui/src/main/java/forge/gui/home/sanctioned/VSubmenuConstructed.java +++ b/forge-gui/src/main/java/forge/gui/home/sanctioned/VSubmenuConstructed.java @@ -26,11 +26,9 @@ import javax.swing.JRadioButton; import net.miginfocom.swing.MigLayout; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.ImmutablePair; - -import com.google.common.base.Function; - +import forge.Command; import forge.Singletons; +import forge.deck.Deck; import forge.game.GameType; import forge.gui.deckchooser.DecksComboBox.DeckType; import forge.gui.deckchooser.FDeckChooser; @@ -347,6 +345,7 @@ public enum VSubmenuConstructed implements IVSubmenu { /** Builds the actual deck panel layouts for each player. * These are added to a list which can be referenced to populate the deck panel appropriately. */ + @SuppressWarnings("serial") private void buildDeckPanel(final int playerIndex) { String sectionConstraints = "insets 8"; @@ -354,12 +353,12 @@ public enum VSubmenuConstructed implements IVSubmenu { FPanel mainDeckPanel = new FPanel(); mainDeckPanel.setLayout(new MigLayout(sectionConstraints)); - FDeckChooser mainChooser = new FDeckChooser("Main deck:", isPlayerAI(playerIndex)); + final FDeckChooser mainChooser = new FDeckChooser("Main deck:", isPlayerAI(playerIndex)); mainChooser.initialize(); - mainChooser.setChangeListener(new Function>, Void>(){ - @Override public Void apply(ImmutablePair> selection) { - VSubmenuConstructed.this.onDeckClicked(playerIndex, selection.left, selection.right); - return null; + mainChooser.getLstDecks().setSelectCommand(new Command() { + @Override + public void run() { + VSubmenuConstructed.this.onDeckClicked(playerIndex, mainChooser.getSelectedDeckType(), mainChooser.getLstDecks().getSelectedItems()); } }); deckChoosers.add(mainChooser); @@ -367,8 +366,8 @@ public enum VSubmenuConstructed implements IVSubmenu { deckPanelListMain.add(mainDeckPanel); } - protected void onDeckClicked(int iPlayer, DeckType type, List selectedLines) { - String text = type.toString() + ": " + Lang.joinHomogenous(selectedLines); + protected void onDeckClicked(int iPlayer, DeckType type, Iterable selectedDecks) { + String text = type.toString() + ": " + Lang.joinHomogenous(selectedDecks); deckSelectorBtns.get(iPlayer).setText(text); } diff --git a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/DeckManager.java b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/DeckManager.java index 14e6fa253bb..879335227fc 100644 --- a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/DeckManager.java +++ b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/DeckManager.java @@ -6,6 +6,7 @@ import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import javax.swing.JMenu; import javax.swing.JTable; @@ -55,6 +56,7 @@ public final class DeckManager extends ItemManager { private static final FSkin.SkinIcon icoEditOver = FSkin.getIcon(FSkin.InterfaceIcons.ICO_EDIT_OVER); private final GameType gametype; + private boolean nameOnly, preventEdit; private Command cmdDelete, cmdSelect; private final Map columns = SColumnUtil.getColumns( ColumnDef.DECK_ACTIONS, @@ -75,8 +77,7 @@ public final class DeckManager extends ItemManager { this.gametype = gt; columns.get(ColumnDef.DECK_ACTIONS).setCellRenderer(new DeckActionsRenderer()); - columns.get(ColumnDef.DECK_ACTIONS).setSortPriority(1); - columns.get(ColumnDef.NAME).setSortPriority(2); + columns.get(ColumnDef.NAME).setSortPriority(1); this.addSelectionListener(new ListSelectionListener() { @Override @@ -99,6 +100,29 @@ public final class DeckManager extends ItemManager { * Update table columns */ public void update() { + update(false, false); + } + public void update(boolean nameOnly0) { + update(nameOnly0, nameOnly0); + } + public void update(boolean nameOnly0, boolean preventEdit0) { + if (this.nameOnly != nameOnly0) { + this.nameOnly = nameOnly0; + boolean visible = !nameOnly0; + for (Entry column : columns.entrySet()) { + if (column.getKey() != ColumnDef.NAME) { + column.getValue().setVisible(visible); + } + } + this.restoreDefaultFilters(); + } + if (nameOnly0) { + preventEdit0 = true; //if name only, always prevent edit + } + if (this.preventEdit != preventEdit0) { + this.preventEdit = preventEdit0; + columns.get(ColumnDef.DECK_ACTIONS).setVisible(!preventEdit0); + } this.getTable().setup(columns); } @@ -122,7 +146,9 @@ public final class DeckManager extends ItemManager { @Override protected void addDefaultFilters() { - addFilter(new DeckColorFilter(this)); + if (!this.nameOnly) { + addFilter(new DeckColorFilter(this)); + } } @Override @@ -132,6 +158,8 @@ public final class DeckManager extends ItemManager { @Override protected void buildAddFilterMenu(JMenu menu) { + if (this.nameOnly) { return; } + GuiUtils.addSeparator(menu); //separate from current search item JMenu fmt = GuiUtils.createMenu("Format"); @@ -189,7 +217,7 @@ public final class DeckManager extends ItemManager { } private void editDeck(final Deck deck) { - if (deck == null) { return; } + if (deck == null || this.preventEdit) { return; } ACEditorBase editorCtrl = null; FScreen screen = null; @@ -228,7 +256,7 @@ public final class DeckManager extends ItemManager { } public boolean deleteDeck(Deck deck) { - if (deck == null) { return false; } + if (deck == null || this.preventEdit) { return false; } if (!FOptionPane.showConfirmDialog( "Are you sure you want to delete '" + deck.getName() + "'?", diff --git a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/ItemManager.java b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/ItemManager.java index 00ac426c719..f78a09f73d4 100644 --- a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/ItemManager.java +++ b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/ItemManager.java @@ -25,6 +25,7 @@ import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -499,6 +500,25 @@ public abstract class ItemManager extends JPanel { this.table.setSelectedItems(items); } + /** + * + * setSelectedStrings. + * + * @param strings - Strings to select + */ + public void setSelectedStrings(Iterable strings) { + List items = new ArrayList(); + for (String itemName : strings) { + for (Entry itemEntry : this.pool) { + if (itemEntry.getKey().toString().equals(itemName)) { + items.add(itemEntry.getKey()); + break; + } + } + } + this.table.setSelectedItems(items); + } + /** * * selectItemEntrys. @@ -549,6 +569,9 @@ public abstract class ItemManager extends JPanel { * * @param indices - Indices to select */ + public void setSelectedIndices(Integer[] indices) { + this.table.setSelectedIndices(Arrays.asList(indices)); + } public void setSelectedIndices(Iterable indices) { this.table.setSelectedIndices(indices); } @@ -733,6 +756,19 @@ public abstract class ItemManager extends JPanel { } } + public void restoreDefaultFilters() { + lockFiltering = true; + for (ItemFilter filter : this.orderedFilters) { + this.remove(filter.getPanel()); + } + this.filters.clear(); + this.orderedFilters.clear(); + addDefaultFilters(); + lockFiltering = false; + this.revalidate(); + this.applyFilters(); + } + @SuppressWarnings("unchecked") public void removeFilter(ItemFilter filter) { final Class> filterClass = (Class>) filter.getClass(); @@ -741,7 +777,7 @@ public abstract class ItemManager extends JPanel { if (classFilters.size() == 0) { this.filters.remove(filterClass); } - orderedFilters.remove(filter); + this.orderedFilters.remove(filter); this.remove(filter.getPanel()); this.revalidate(); applyFilters(); diff --git a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ItemColumn.java b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ItemColumn.java index 95e8b3b39ec..64f7a12972c 100644 --- a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ItemColumn.java +++ b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ItemColumn.java @@ -65,7 +65,7 @@ public class ItemColumn extends TableColumn { private final ColumnDef def; private SortState sortState = SortState.NONE; private int sortPriority = 0; - private boolean hide = false; + private boolean visible = true; private int index = 0; private final Function, Comparable> fnSort; private final Function, Object> fnDisplay; @@ -144,16 +144,12 @@ public class ItemColumn extends TableColumn { return this.def.sortState; } - public boolean isHidden() { - return this.hide; + public boolean isVisible() { + return this.visible; } - public void hide() { - this.hide = true; - } - - public void show() { - this.hide = false; + public void setVisible(boolean visible0) { + this.visible = visible0; } public Function, Comparable> getFnSort() { diff --git a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ItemListView.java b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ItemListView.java index 2cbcb77d708..8c8da629dbc 100644 --- a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ItemListView.java +++ b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ItemListView.java @@ -156,7 +156,7 @@ public final class ItemListView extends ItemView { for (Entry entry : list) { ItemColumn col = entry.getValue(); col.setModelIndex(colmodel.getColumnCount()); - if (!col.isHidden()) { colmodel.addColumn(col); } + if (col.isVisible()) { colmodel.addColumn(col); } } this.tableModel.addListeners(); @@ -424,7 +424,7 @@ public final class ItemListView extends ItemView { // Assemble priority sort. while (e.hasMoreElements()) { final ItemColumn col = (ItemColumn) e.nextElement(); - if (col.getSortPriority() > 0) { + if (col.getSortPriority() > 0 && col.getSortPriority() < sortcols.length) { sortcols[col.getSortPriority()] = col; } } diff --git a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/SColumnUtil.java b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/SColumnUtil.java index 65fa931bdc3..f7bec11e88a 100644 --- a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/SColumnUtil.java +++ b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/SColumnUtil.java @@ -63,8 +63,8 @@ public final class SColumnUtil { ColumnDef.RANKING); columns.get(ColumnDef.FAVORITE).setSortPriority(1); columns.get(ColumnDef.NAME).setSortPriority(2); - columns.get(ColumnDef.AI).hide(); - columns.get(ColumnDef.RANKING).hide(); + columns.get(ColumnDef.AI).setVisible(false); + columns.get(ColumnDef.RANKING).setVisible(false); return columns; } @@ -85,8 +85,8 @@ public final class SColumnUtil { columns.get(ColumnDef.CMC).setSortPriority(1); columns.get(ColumnDef.TYPE).setSortPriority(2); columns.get(ColumnDef.NAME).setSortPriority(3); - columns.get(ColumnDef.AI).hide(); - columns.get(ColumnDef.RANKING).hide(); + columns.get(ColumnDef.AI).setVisible(false); + columns.get(ColumnDef.RANKING).setVisible(false); return columns; } @@ -99,12 +99,12 @@ public final class SColumnUtil { public static void toggleColumn(final JTable table, final ItemColumn col0) { final TableColumnModel colmodel = table.getColumnModel(); - if (!col0.isHidden()) { - col0.hide(); + if (col0.isVisible()) { + col0.setVisible(false); colmodel.removeColumn(col0); } else { - col0.show(); + col0.setVisible(true); colmodel.addColumn(col0); if (col0.getModelIndex() < colmodel.getColumnCount()) {