diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index fe6072a0290..313a541aa0b 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.EnumMap; import java.util.HashMap; import java.util.Iterator; @@ -85,7 +86,7 @@ public class Card extends GameEntity implements Comparable { private int uniqueNumber; private final Map characteristicsMap - = new EnumMap(CardCharacteristicName.class); + = new EnumMap(CardCharacteristicName.class); private CardCharacteristicName curCharacteristics = CardCharacteristicName.Original; private CardCharacteristicName preTFDCharacteristic = CardCharacteristicName.Original; @@ -5642,6 +5643,32 @@ public class Card extends GameEntity implements Comparable { return 0; } } + + private static Comparator _nameComparator = new Comparator() { + @Override + public int compare(Card me, Card other) { + if (me == other) { + return 0; + } + if (null == other) { + return 1; + } + if (me.getName() == other.getName()) { + return 0; + } + if (null == me.getName()) { + return -1; + } + return me.getName().compareTo(other.getName()); + } + }; + + /** + * For sorting lists of cards by name instead of by id + */ + public static final Comparator getNameComparator() { + return _nameComparator; + } /** {@inheritDoc} */ @Override diff --git a/src/main/java/forge/card/ability/effects/ChooseGenericEffect.java b/src/main/java/forge/card/ability/effects/ChooseGenericEffect.java index cb9caaaa632..7005d2d5360 100644 --- a/src/main/java/forge/card/ability/effects/ChooseGenericEffect.java +++ b/src/main/java/forge/card/ability/effects/ChooseGenericEffect.java @@ -6,6 +6,7 @@ import java.util.Map; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; +import com.google.common.collect.Lists; import forge.Card; import forge.card.ability.AbilityFactory; @@ -50,7 +51,7 @@ public class ChooseGenericEffect extends SpellEffect { } SpellAbility chosenSA = null; if (p.isHuman()) { - String choice = GuiChoose.one("Choose one", choices.values()); + String choice = GuiChoose.one("Choose one", Lists.newArrayList(choices.values())); chosenSA = AbilityFactory.getAbility(host.getSVar(choices.inverse().get(choice)), host); } else { //Computer AI chosenSA = AbilityFactory.getAbility(host.getSVar(sa.getParam("Choices").split(",")[0]), host); diff --git a/src/main/java/forge/card/ability/effects/ManaReflectedEffect.java b/src/main/java/forge/card/ability/effects/ManaReflectedEffect.java index fce00e63768..1a48e32431d 100644 --- a/src/main/java/forge/card/ability/effects/ManaReflectedEffect.java +++ b/src/main/java/forge/card/ability/effects/ManaReflectedEffect.java @@ -1,9 +1,9 @@ package forge.card.ability.effects; import java.util.ArrayList; -import java.util.Collection; import java.util.HashSet; import java.util.List; + import forge.Card; import forge.CardUtil; import forge.card.MagicColor; @@ -26,7 +26,8 @@ public class ManaReflectedEffect extends SpellEffect { AbilityManaPart ma = sa.getManaPart(); sa.setUndoable(sa.isAbility() && sa.isUndoable()); - final Collection colors = CardUtil.getReflectableManaColors(sa, sa, new HashSet(), new ArrayList()); + final List colors = new ArrayList( + CardUtil.getReflectableManaColors(sa, sa, new HashSet(), new ArrayList())); final List tgtPlayers = getTargetPlayers(sa); for (final Player player : tgtPlayers) { @@ -61,7 +62,7 @@ public class ManaReflectedEffect extends SpellEffect { * a {@link forge.game.player.Player} object. * @return a {@link java.lang.String} object. */ - private static String generatedReflectedMana(final SpellAbility sa, final Collection colors, final Player player) { + private static String generatedReflectedMana(final SpellAbility sa, final List colors, final Player player) { // Calculate generated mana here for stack description and resolving final int amount = sa.hasParam("Amount") ? AbilityUtils.calculateAmount(sa.getSourceCard(), sa.getParam("Amount"), sa) : 1; diff --git a/src/main/java/forge/card/replacement/ReplacementEffect.java b/src/main/java/forge/card/replacement/ReplacementEffect.java index 07ab9e4fd69..ddb5d70bc0a 100644 --- a/src/main/java/forge/card/replacement/ReplacementEffect.java +++ b/src/main/java/forge/card/replacement/ReplacementEffect.java @@ -22,7 +22,6 @@ import java.util.HashMap; import java.util.List; import forge.Card; - import forge.CardLists; import forge.CardUtil; import forge.Singletons; @@ -39,7 +38,7 @@ import forge.util.Expressions; * TODO: Write javadoc for this type. * */ -public abstract class ReplacementEffect extends TriggerReplacementBase { +public abstract class ReplacementEffect extends TriggerReplacementBase implements Comparable { private ReplacementLayer layer = ReplacementLayer.None; @@ -439,4 +438,25 @@ public abstract class ReplacementEffect extends TriggerReplacementBase { public void setLayer(ReplacementLayer layer0) { this.layer = layer0; } + + /* (non-Javadoc) + * used only for ordering, just sort by card + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + @Override + public int compareTo(ReplacementEffect other) { + if (null == other) { + return 1; + } + if (hostCard == other.hostCard) { + return 0; + } + if (null == hostCard) { + return -1; + } + if (null == other.hostCard) { + return 1; + } + return hostCard.getName().compareTo(other.hostCard.getName()); + } } diff --git a/src/main/java/forge/card/spellability/SpellAbility.java b/src/main/java/forge/card/spellability/SpellAbility.java index 6ce6965acd5..0cca398906f 100644 --- a/src/main/java/forge/card/spellability/SpellAbility.java +++ b/src/main/java/forge/card/spellability/SpellAbility.java @@ -26,7 +26,6 @@ import java.util.Set; import org.apache.commons.lang.StringUtils; import forge.Card; - import forge.GameEntity; import forge.Singletons; import forge.card.SpellManaCost; @@ -48,7 +47,7 @@ import forge.game.player.Player; * @author Forge * @version $Id$ */ -public abstract class SpellAbility implements ISpellAbility { +public abstract class SpellAbility implements ISpellAbility, Comparable { // choices for constructor isPermanent argument private String description = ""; @@ -1782,4 +1781,25 @@ public abstract class SpellAbility implements ISpellAbility { } return true; } + + /* (non-Javadoc) + * used for ordering in lists -- we just want to group by card + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + @Override + public int compareTo(SpellAbility other) { + if (null == other) { + return 1; + } + if (sourceCard == other.sourceCard) { + return 0; + } + if (null == sourceCard) { + return -1; + } + if (null == other.sourceCard) { + return 1; + } + return sourceCard.getName().compareTo(other.sourceCard.getName()); + } } diff --git a/src/main/java/forge/game/GameActionPlay.java b/src/main/java/forge/game/GameActionPlay.java index 8a34b9db9e2..7b0715cf9a2 100644 --- a/src/main/java/forge/game/GameActionPlay.java +++ b/src/main/java/forge/game/GameActionPlay.java @@ -179,14 +179,13 @@ public class GameActionPlay { untappedCreats = CardLists.filter(untappedCreats, CardPredicates.Presets.UNTAPPED); if (untappedCreats.size() != 0) { - final ArrayList choices = new ArrayList(); + final List choices = new ArrayList(); for (final Card c : untappedCreats) { choices.add(c); } - choices.add("DONE"); ArrayList usableColors = new ArrayList(); ManaCostBeingPaid newCost = new ManaCostBeingPaid(originalCost.toString()); - Object tapForConvoke = null; + Card tapForConvoke = null; if (sa.getActivatingPlayer().isHuman()) { tapForConvoke = GuiChoose.oneOrNone("Tap for Convoke? " + newCost.toString(), choices); @@ -195,7 +194,7 @@ public class GameActionPlay { // Probably along with deciding how many creatures to // tap } - while ((tapForConvoke != null) && (tapForConvoke instanceof Card) && (untappedCreats.size() != 0)) { + while (tapForConvoke != null && untappedCreats.size() != 0) { final Card workingCard = (Card) tapForConvoke; usableColors = CardUtil.getConvokableColors(workingCard, newCost); diff --git a/src/main/java/forge/game/GameFormat.java b/src/main/java/forge/game/GameFormat.java index afa3f49a7d7..6efc126ec95 100644 --- a/src/main/java/forge/game/GameFormat.java +++ b/src/main/java/forge/game/GameFormat.java @@ -34,7 +34,7 @@ import forge.item.CardPrinted; * TODO: Write javadoc for this type. * */ -public class GameFormat { +public class GameFormat implements Comparable { private final String name; // contains allowed sets, when empty allows all sets @@ -158,4 +158,22 @@ public class GameFormat { } }; + /* (non-Javadoc) + * just used for ordering -- comparing the name is sufficient + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + @Override + public int compareTo(GameFormat other) { + if (null == other) { + return 1; + } + if (name == other.name) { + return 0; + } + if (null == name) { + return -1; + } + return name.compareTo(other.name); + } + } diff --git a/src/main/java/forge/game/player/PlayerControllerHuman.java b/src/main/java/forge/game/player/PlayerControllerHuman.java index 706bc9f566b..91052097950 100644 --- a/src/main/java/forge/game/player/PlayerControllerHuman.java +++ b/src/main/java/forge/game/player/PlayerControllerHuman.java @@ -142,32 +142,28 @@ public class PlayerControllerHuman extends PlayerController { CardPool sideboard = deck.get(DeckSection.Sideboard); CardPool main = deck.get(DeckSection.Main); - // + deck.getSideboard().countAll() int deckMinSize = Math.min(main.countAll(), gameType.getDecksFormat().getMainRange().getMinimumInteger()); - //IntRange sbRange = gameType.getDecksFormat().getSideRange(); - int sideboardSize = sideboard.countAll(); CardPool newSb = new CardPool(); List newMain = null; - while (newMain == null || newMain.size() < deckMinSize) { - - if ( newMain != null ) { + if (newMain != null) { String errMsg = String.format("Too few cards in your main deck (minimum %d), please make modifications to your deck again.", deckMinSize); JOptionPane.showMessageDialog(null, errMsg, "Invalid deck", JOptionPane.ERROR_MESSAGE); } - newMain = GuiChoose.order("Sideboard", "Main Deck", sideboardSize, sideboard.toFlatList(), main.toFlatList(), null, true); + newMain = GuiChoose.sideboard(sideboard.toFlatList(), main.toFlatList()); } newSb.clear(); newSb.addAll(main); newSb.addAll(sideboard); - for(CardPrinted c : newMain) + for(CardPrinted c : newMain) { newSb.remove(c); + } - Deck res = (Deck) deck.copyTo(deck.getName()); + Deck res = (Deck)deck.copyTo(deck.getName()); res.getMain().clear(); res.getMain().add(newMain); CardPool resSb = res.getOrCreate(DeckSection.Sideboard); diff --git a/src/main/java/forge/gui/DualListBox.java b/src/main/java/forge/gui/DualListBox.java index 35e27f5888e..c2febd0c79b 100644 --- a/src/main/java/forge/gui/DualListBox.java +++ b/src/main/java/forge/gui/DualListBox.java @@ -10,7 +10,11 @@ import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import javax.swing.JDialog; @@ -21,7 +25,7 @@ import javax.swing.event.ListDataListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; -import com.google.common.base.Function; +import com.google.common.collect.Lists; import forge.Card; import forge.card.spellability.SpellAbility; @@ -42,41 +46,141 @@ import forge.item.CardPrinted; // Single Arrows in between left box and right box for ordering // Multi Arrows for moving everything in order // Up/down arrows on the right of the right box for swapping -// Single ok button, disabled until left box is empty +// Single ok button, disabled until left box has specified number of items remaining @SuppressWarnings("serial") -public class DualListBox extends FPanel { - private FList sourceList; +public class DualListBox> extends FPanel { + private final FList sourceList; + private final UnsortedListModel sourceListModel; - private UnsortedListModel sourceListModel; + private final FList destList; + private final UnsortedListModel destListModel; - private FList destList; + private final FButton addButton; + private final FButton addAllButton; + private final FButton removeButton; + private final FButton removeAllButton; + private final FButton okButton; + private final FButton autoButton; - private UnsortedListModel destListModel; + private final FLabel orderedLabel; + private final FLabel selectOrder; - private FButton addButton; - private FButton addAllButton; - - private FButton removeButton; - private FButton removeAllButton; - - private FButton okButton; - private FButton autoButton; - - private FLabel orderedLabel; - private FLabel selectOrder; - - private int remainingObjects = 0; + private final int targetRemainingSources; private boolean sideboardingMode = false; private boolean showCard = true; - public DualListBox(int remainingObjects, String label, List sourceElements, List destElements, - Card referenceCard) { - this.remainingObjects = remainingObjects; - initScreen(); - orderedLabel.setText(label); + public DualListBox(int remainingSources, String label, List sourceElements, List destElements, + boolean startSorted, Comparator sortComparator) { + targetRemainingSources = remainingSources; + sourceListModel = new UnsortedListModel(); + sourceList = new FList(sourceListModel); + destListModel = new UnsortedListModel(); + destList = new FList(destListModel); + + setPreferredSize(new Dimension(650, 300)); + setLayout(new GridLayout(0, 3)); + setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME)); + setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT)); + + final Runnable onAdd = new Runnable() { + @Override + public void run() { + @SuppressWarnings("unchecked") + List selected = (List) Arrays.asList(sourceList.getSelectedValues()); + addDestinationElements(selected); + clearSourceSelected(); + sourceList.validate(); + _setButtonState(); + } + }; + + final Runnable onRemove = new Runnable() { + @Override + public void run() { + @SuppressWarnings("unchecked") + List selected = (List) Arrays.asList(destList.getSelectedValues()); + clearDestinationSelected(); + addSourceElements(selected); + _setButtonState(); + } + }; + + sourceList.addKeyListener(new KeyAdapter() { + @Override public void keyPressed(final KeyEvent e) { + _handleListKey(e, onAdd, destList); + } + }); + sourceList.addMouseListener(new MouseAdapter() { + @Override public void mouseClicked(MouseEvent e) { + if (MouseEvent.BUTTON1 == e.getButton() && 2 == e.getClickCount()) { onAdd.run(); } + } + }); + + destList.addKeyListener(new KeyAdapter() { + @Override public void keyPressed(final KeyEvent e) { + _handleListKey(e, onRemove, sourceList); + } + }); + destList.addMouseListener(new MouseAdapter() { + @Override public void mouseClicked(MouseEvent e) { + if (MouseEvent.BUTTON1 == e.getButton() && 2 == e.getClickCount()) { onRemove.run(); } + } + }); + + // Dual List control buttons + addButton = new FButton(">"); + addButton.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) { onAdd.run(); } }); + addAllButton = new FButton(">>"); + addAllButton.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) { _addAll(); } }); + removeButton = new FButton("<"); + removeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { onRemove.run(); } }); + removeAllButton = new FButton("<<"); + removeAllButton.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) { _removeAll(); } }); + + // Dual List Complete Buttons + okButton = new FButton("OK"); + okButton.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) { _finish(); } }); + autoButton = new FButton("Auto"); + autoButton.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) { _addAll(); _finish(); } }); + + FPanel leftPanel = new FPanel(new BorderLayout()); + selectOrder = new FLabel.Builder().text("Select Order:").build(); + leftPanel.setSize(300, 300); + leftPanel.add(selectOrder, BorderLayout.NORTH); + leftPanel.add(new FScrollPane(sourceList), BorderLayout.CENTER); + leftPanel.add(okButton, BorderLayout.SOUTH); + + FPanel centerPanel = new FPanel(new GridLayout(6, 1)); + centerPanel.setSize(50, this.getHeight()); + centerPanel.add(new FPanel()); // empty panel to take up the first slot + centerPanel.add(addButton); + centerPanel.add(addAllButton); + centerPanel.add(removeButton); + centerPanel.add(removeAllButton); + + orderedLabel = new FLabel.Builder().text(label).build(); + + FPanel rightPanel = new FPanel(new BorderLayout()); + rightPanel.setSize(300, 300); + rightPanel.add(orderedLabel, BorderLayout.NORTH); + rightPanel.add(new FScrollPane(destList), BorderLayout.CENTER); + rightPanel.add(autoButton, BorderLayout.SOUTH); + + add(leftPanel); + add(centerPanel); + add(rightPanel); + + _addListListeners(sourceList); + _addListListeners(destList); + if (destElements != null && !destElements.isEmpty()) { + if (startSorted) { + // it would be nice if we could sort in place, but it might mess up our callers + destElements = Lists.newArrayList(destElements); + Collections.sort(destElements, sortComparator); + } addDestinationElements(destElements); SwingUtilities.invokeLater(new Runnable() { @@ -86,7 +190,12 @@ public class DualListBox extends FPanel { } }); } + if (sourceElements != null && !sourceElements.isEmpty()) { + if (startSorted) { + sourceElements = Lists.newArrayList(sourceElements); + Collections.sort(sourceElements, sortComparator); + } addSourceElements(sourceElements); SwingUtilities.invokeLater(new Runnable() { @@ -96,13 +205,12 @@ public class DualListBox extends FPanel { } }); } - this.setButtonState(); + + _setButtonState(); } - public DualListBox(int remainingObjects, String label, List sourceElements, List destElements, Card referenceCard, boolean isSideboardDialog) { - this(remainingObjects, label, sourceElements, destElements, referenceCard); - - this.sideboardingMode = isSideboardDialog; + public void setSideboardMode( boolean isSideboardMode) { + sideboardingMode = isSideboardMode; if (sideboardingMode) { addAllButton.setVisible(false); removeAllButton.setVisible(false); @@ -112,6 +220,30 @@ public class DualListBox extends FPanel { } } + private void _handleListKey (KeyEvent e, Runnable onSpace, FList arrowFocusTarget) { + switch (e.getKeyCode()) { + case KeyEvent.VK_SPACE: + onSpace.run(); + break; + + case KeyEvent.VK_LEFT: + case KeyEvent.VK_RIGHT: + arrowFocusTarget.requestFocusInWindow(); + break; + + case KeyEvent.VK_ENTER: + if (okButton.isEnabled()) { + okButton.doClick(); + } else if (autoButton.isEnabled()) { + autoButton.doClick(); + } + break; + + default: + break; + } + } + public void clearSourceListModel() { sourceListModel.clear(); } @@ -197,7 +329,7 @@ public class DualListBox extends FPanel { } } - private void addCardViewListener(final FList list) { + private void _addListListeners(final FList list) { list.getModel().addListDataListener(new ListDataListener() { int callCount = 0; @Override @@ -276,157 +408,19 @@ public class DualListBox extends FPanel { }); } - private void initScreen() { - setPreferredSize(new Dimension(650, 300)); - setLayout(new GridLayout(0, 3)); - setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME)); - setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT)); - sourceListModel = new UnsortedListModel(); - sourceList = new FList(sourceListModel); - destListModel = new UnsortedListModel(); - destList = new FList(destListModel); - - final Runnable onAdd = new Runnable() { - @Override - public void run() { - @SuppressWarnings("unchecked") - List selected = (List) Arrays.asList(sourceList.getSelectedValues()); - addDestinationElements(selected); - clearSourceSelected(); - sourceList.validate(); - setButtonState(); - } - }; - - final Runnable onRemove = new Runnable() { - @Override - public void run() { - @SuppressWarnings("unchecked") - List selected = (List) Arrays.asList(destList.getSelectedValues()); - clearDestinationSelected(); - addSourceElements(selected); - setButtonState(); - } - }; - - ActionListener addListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - onAdd.run(); - } - }; - - ActionListener removeListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - onRemove.run(); - } - }; - - final Function onEnter = new Function() { - @Override - public Void apply (KeyEvent e) { - if (e.getKeyCode() == 10) { - if (e.isControlDown() || e.isMetaDown()) { - autoButton.doClick(); - } else { - okButton.doClick(); - } - } - - return null; - } - }; - - sourceList.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(final KeyEvent e) { - if (e.getKeyChar() == ' ') { onAdd.run(); } - else { onEnter.apply(e); } - } - }); - - destList.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(final KeyEvent e) { - if (e.getKeyChar() == ' ') { onRemove.run(); } - else { onEnter.apply(e); } - } - }); - - // Dual List control buttons - addButton = new FButton(">"); - addButton.addActionListener(addListener); - addAllButton = new FButton(">>"); - addAllButton.addActionListener(new AddAllListener()); - removeButton = new FButton("<"); - removeButton.addActionListener(removeListener); - removeAllButton = new FButton("<<"); - removeAllButton.addActionListener(new RemoveAllListener()); - - // Dual List Complete Buttons - okButton = new FButton("OK"); - okButton.addActionListener(new OkListener()); - - autoButton = new FButton("Auto"); - autoButton.addActionListener(new AutoListener()); - - FPanel leftPanel = new FPanel(new BorderLayout()); - selectOrder = new FLabel.Builder().build(); - selectOrder.setText("Select Order:"); - leftPanel.setSize(300, 300); - leftPanel.add(selectOrder, BorderLayout.NORTH); - leftPanel.add(new FScrollPane(sourceList), BorderLayout.CENTER); - leftPanel.add(okButton, BorderLayout.SOUTH); - - FPanel centerPanel = new FPanel(new GridLayout(5, 1)); - centerPanel.setSize(50, this.getHeight()); - centerPanel.add(addButton); - centerPanel.add(addAllButton); - centerPanel.add(removeButton); - centerPanel.add(removeAllButton); - - orderedLabel = new FLabel.Builder().build(); - orderedLabel.setText("Selected Elements:"); - - FPanel rightPanel = new FPanel(new BorderLayout()); - rightPanel.setSize(300, 300); - rightPanel.add(orderedLabel, BorderLayout.NORTH); - rightPanel.add(new FScrollPane(destList), BorderLayout.CENTER); - rightPanel.add(autoButton, BorderLayout.SOUTH); - - add(leftPanel); - add(centerPanel); - add(rightPanel); - - addCardViewListener(sourceList); - addCardViewListener(destList); - } - - private void addAll() { + private void _addAll() { addDestinationElements(sourceListModel); clearSourceListModel(); - setButtonState(); + _setButtonState(); + } + + private void _removeAll() { + addSourceElements(destListModel); + clearDestinationListModel(); + _setButtonState(); } - private class AddAllListener implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - addAll(); - setButtonState(); - } - } - - private class RemoveAllListener implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - addSourceElements(destListModel); - clearDestinationListModel(); - setButtonState(); - } - } - - public void setButtonState() { + private void _setButtonState() { if (sideboardingMode) { removeAllButton.setVisible(false); addAllButton.setVisible(false); @@ -434,15 +428,11 @@ public class DualListBox extends FPanel { orderedLabel.setText(String.format("Main Deck (%d):", destListModel.getSize())); } - if (remainingObjects != -1) { - okButton.setEnabled(sourceListModel.getSize() == remainingObjects); + if (targetRemainingSources != -1) { + okButton.setEnabled(sourceListModel.getSize() == targetRemainingSources); } - if (remainingObjects < 1) { - if (!sideboardingMode) { - autoButton.setEnabled(sourceListModel.getSize() != remainingObjects); - } else { - autoButton.setEnabled(false); - } + if (targetRemainingSources < 1 && !sideboardingMode) { + autoButton.setEnabled(sourceListModel.getSize() != targetRemainingSources); } else { autoButton.setEnabled(false); } @@ -453,27 +443,11 @@ public class DualListBox extends FPanel { addAllButton.setEnabled(sourceListModel.getSize() != 0); } - private void finishOrdering() { - System.out.println("Attempting to finish."); + private void _finish() { this.setVisible(false); Container grandpa = this.getParent().getParent(); JDialog dialog = (JDialog) grandpa.getParent(); dialog.dispose(); } - - private class OkListener implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - finishOrdering(); - } - } - - private class AutoListener implements ActionListener { - @Override - public void actionPerformed(ActionEvent e) { - addAll(); - finishOrdering(); - } - } } diff --git a/src/main/java/forge/gui/GuiChoose.java b/src/main/java/forge/gui/GuiChoose.java index bf4f787d780..f00e45c5b8e 100644 --- a/src/main/java/forge/gui/GuiChoose.java +++ b/src/main/java/forge/gui/GuiChoose.java @@ -1,8 +1,8 @@ package forge.gui; import java.awt.BorderLayout; -import java.util.ArrayList; -import java.util.Collection; +import java.util.Arrays; +import java.util.Comparator; import java.util.List; import javax.swing.JDialog; @@ -14,6 +14,7 @@ import javax.swing.event.ListSelectionListener; import forge.Card; import forge.gui.match.CMatchUI; +import forge.item.CardPrinted; import forge.item.InventoryItem; /** @@ -21,116 +22,22 @@ import forge.item.InventoryItem; * */ public class GuiChoose { - - /** - * Convenience for getChoices(message, 0, 1, choices). - * - * @param - * is automatically inferred. - * @param message - * a {@link java.lang.String} object. - * @param choices - * a T object. - * @return null if choices is missing, empty, or if the users' choices are - * empty; otherwise, returns the first item in the List returned by - * getChoices. - * @see #getChoices(String, int, int, Object...) - */ - public static T oneOrNone(final String message, final T[] choices) { - if ((choices == null) || (choices.length == 0)) { - return null; - } - final List choice = GuiChoose.getChoices(message, 0, 1, choices); - return choice.isEmpty() ? null : choice.get(0); - } // getChoiceOptional(String,T...) - - public static T oneOrNone(final String message, final Collection choices) { + public static > T oneOrNone(String message, List choices, boolean sort, Comparator sortComparator) { if ((choices == null) || (choices.size() == 0)) { return null; } - final List choice = GuiChoose.getChoices(message, 0, 1, choices); + final List choice = _getChoices(message, 0, 1, choices, sort, sortComparator); return choice.isEmpty() ? null : choice.get(0); - } // getChoiceOptional(String,T...) - - // returned Object will never be null - /** - *

- * getChoice. - *

- * - * @param - * a T object. - * @param message - * a {@link java.lang.String} object. - * @param choices - * a T object. - * @return a T object. - */ - public static T one(final String message, final T[] choices) { - final List choice = GuiChoose.getChoices(message, 1, 1, choices); - assert choice.size() == 1; - return choice.get(0); - } // getChoice() - - // Nothing to choose here. Code uses this to just show a card. - public static Card one(final String message, final Card singleChoice) { - List choices = new ArrayList(); - choices.add(singleChoice); - return one(message, choices); + } + public static > T oneOrNone(String message, List choices) { + return oneOrNone(message, choices, false, null); + } + public static > T oneOrNone(String message, T[] choices) { + if ((choices == null)) { return null; } + return oneOrNone(message, Arrays.asList(choices)); } - public static T one(final String message, final Collection choices) { - if ((choices == null) || (choices.size() == 0)) { - return null; - } - final List choice = GuiChoose.getChoices(message, 1, 1, choices); - assert choice.size() == 1; - return choice.get(0); - } - - // returned Object will never be null /** - *

- * getChoicesOptional. - *

- * - * @param - * a T object. - * @param message - * a {@link java.lang.String} object. - * @param choices - * a T object. - * @return a {@link java.util.List} object. - */ - public static List noneOrMany(final String message, final T[] choices) { - return GuiChoose.getChoices(message, 0, choices.length, choices); - } // getChoice() - - public static List noneOrMany(final String message, final Collection choices) { - return GuiChoose.getChoices(message, 0, choices.size(), choices); - } - - // returned Object will never be null - /** - *

- * getChoices. - *

- * - * @param - * a T object. - * @param message - * a {@link java.lang.String} object. - * @param choices - * a T object. - * @return a {@link java.util.List} object. - */ - public static List oneOrMany(final String message, final T[] choices) { - return GuiChoose.getChoices(message, 1, choices.length, choices); - } // getChoice() - - //returned Object will never be null - /** - *

* Presents a list of choices where the player must choose exactly *amount* options. * @param message * the message to display to the player. @@ -140,58 +47,80 @@ public class GuiChoose { * the amount of options that must be chosen. * @return */ - public static List amount(final String message, final T[] choices, final int amount) { - if ((choices == null) || (choices.length == 0) || choices.length < amount) { + public static > List amount(String message, List choices, int amt, boolean sort, Comparator sortComparator) { + if (null == choices || 0 == choices.size() || 0 == amt) { return null; } - - return GuiChoose.getChoices(message, amount, amount, choices); + final List choice = _getChoices(message, amt, amt, choices, sort, sortComparator); + assert choice.size() == amt; + return choice; + } + public static > List amount(String message, List choices, int amt) { + return amount(message, choices, amt, false, null); + } + public static > List amount(String message, T[] choices, int amt) { + if ((choices == null)) { return null; } + return amount(message, Arrays.asList(choices), amt); } - public static List amount(final String message, final Collection choices, final int amount) { - if ((choices == null) || (choices.size() == 0) || choices.size() < amount) { + public static > T one(String message, List choices, boolean sort, Comparator sortComparator) { + List choice = amount(message, choices, 1, sort, sortComparator); + if (null == choice || choice.isEmpty()) { return null; } + return choice.get(0); + } + public static > T one(String message, List choices) { + return one(message, choices, false, null); + } + public static > T one(String message, T[] choices) { + if ((choices == null)) { return null; } + return one(message, Arrays.asList(choices)); + } + // Nothing to choose here. Code uses this to just show a card. + public static Card one(String message, Card singleChoice) { + List choices = Arrays.asList(singleChoice); + return one(message, choices); + } - return GuiChoose.getChoices(message, amount, amount, choices); + public static > List noneOrMany(String message, List choices, boolean sort, Comparator sortComparator) { + if ((choices == null) || (choices.size() == 0)) { + return null; + } + final List choice = _getChoices(message, 0, choices.size(), choices, sort, sortComparator); + return choice.isEmpty() ? null : choice; + } + public static > List noneOrMany(String message, List choices) { + return noneOrMany(message, choices, false, null); + } + + public static > List oneOrMany(String message, List choices, boolean sort, Comparator sortComparator) { + if ((choices == null) || (choices.size() == 0)) { + return null; + } + final List choice = _getChoices(message, 1, choices.size(), choices, sort, sortComparator); + return choice.isEmpty() ? null : choice; + } + public static > List oneOrMany(String message, List choices) { + return oneOrMany(message, choices, false, null); + } + public static > List oneOrMany(String message, T[] choices) { + if ((choices == null)) { return null; } + return oneOrMany(message, Arrays.asList(choices)); } // returned Object will never be null - /** - *

- * getChoices. - *

- * - * @param - * a T object. - * @param message - * a {@link java.lang.String} object. - * @param min - * a int. - * @param max - * a int. - * @param choices - * a T object. - * @return a {@link java.util.List} object. - */ - private static List getChoices(final String message, final int min, final int max, final T[] choices) { - final ListChooser c = new ListChooser(message, null, min, max, choices); - return getChoices(c); + private static > List _getChoices(String message, int min, int max, List choices, + boolean sort, Comparator sortComparator) { + return _getChoices(new ListChooser(message, min, max, choices, sort, sortComparator)); } - - private static List getChoices(final String message, final int min, final int max, final Collection choices) { - final ListChooser c = new ListChooser(message, min, max, choices); - return getChoices(c); - } - - private static List getChoices(final ListChooser c) { + private static > List _getChoices(ListChooser c) { final JList list = c.getJList(); list.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(final ListSelectionEvent ev) { if (list.getSelectedValue() instanceof Card) { CMatchUI.SINGLETON_INSTANCE.setCard((Card) list.getSelectedValue()); - GuiUtils.clearPanelSelections(); GuiUtils.setPanelSelection((Card) list.getSelectedValue()); } @@ -200,21 +129,31 @@ public class GuiChoose { } } }); + c.show(); GuiUtils.clearPanelSelections(); return c.getSelectedValues(); - } // getChoice() - - public static List order(final String title, final String top, int remainingObjects, - final List sourceChoices, List destChoices, Card referenceCard) { - return order(title, top, remainingObjects, sourceChoices, destChoices, referenceCard, false); } - public static List order(final String title, final String top, int remainingObjects, - final List sourceChoices, List destChoices, Card referenceCard, boolean sideboardingMode) { + public static > List order(String title, String top, int remainingObjects, + List sourceChoices, List destChoices, Card referenceCard, boolean sort, Comparator sortComparator) { + return _order(title, top, remainingObjects, sourceChoices, destChoices, referenceCard, sort, sortComparator, false); + } + public static > List order(String title, String top, int remainingObjects, + List sourceChoices, List destChoices, Card referenceCard) { + return order(title, top, remainingObjects, sourceChoices, destChoices, referenceCard, false, null); + } + public static List sideboard(List sideboard, List deck) { + return _order("Sideboard", "Main Deck", sideboard.size(), sideboard, deck, null, true, null, true); + } + + private static > List _order( + String title, String top, int remainingObjects, List sourceChoices, List destChoices, + Card referenceCard, boolean startSorted, Comparator sortComparator, boolean sideboardingMode) { // An input box for handling the order of choices. final JFrame frame = new JFrame(); - DualListBox dual = new DualListBox(remainingObjects, top, sourceChoices, destChoices, referenceCard, sideboardingMode); + DualListBox dual = new DualListBox(remainingObjects, top, sourceChoices, destChoices, startSorted, sortComparator); + dual.setSideboardMode(sideboardingMode); frame.setLayout(new BorderLayout()); frame.setSize(dual.getPreferredSize()); @@ -229,10 +168,12 @@ public class GuiChoose { dialog.setLocationRelativeTo(null); dialog.pack(); dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + if (referenceCard != null) { CMatchUI.SINGLETON_INSTANCE.setCard(referenceCard); // MARKED FOR UPDATE } + dialog.setVisible(true); List objects = dual.getOrderedList(); @@ -241,6 +182,4 @@ public class GuiChoose { GuiUtils.clearPanelSelections(); return objects; } - } - diff --git a/src/main/java/forge/gui/ListChooser.java b/src/main/java/forge/gui/ListChooser.java index 63c909d34a3..d576e6fee58 100644 --- a/src/main/java/forge/gui/ListChooser.java +++ b/src/main/java/forge/gui/ListChooser.java @@ -25,8 +25,8 @@ import java.awt.event.WindowEvent; import java.awt.event.WindowFocusListener; import java.util.AbstractList; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import javax.swing.AbstractAction; @@ -65,7 +65,7 @@ import javax.swing.event.ListSelectionListener; * @author Forge * @version $Id$ */ -public class ListChooser { +public class ListChooser> { // Data and number of choices for the list private List list; @@ -83,68 +83,15 @@ public class ListChooser { private JOptionPane optionPane; private Action ok, cancel; - - /** - *

- * Constructor for ListChooser. - *

- * - * @param title - * a {@link java.lang.String} object. - * @param message - * a {@link java.lang.String} object. - * @param minChoices - * a int. - * @param maxChoices - * a int. - * @param list - * a T object. - */ - public ListChooser(final String title, final String message, final int minChoices, final int maxChoices, - final T[] list) { - this(title, message, minChoices, maxChoices, Arrays.asList(list)); - } - - /** - *

- * Constructor for ListChooser. - *

- * - * @param title - * a {@link java.lang.String} object. - * @param minChoices - * a int. - * @param maxChoices - * a int. - * @param list - * a {@link java.util.List} object. - */ - public ListChooser(final String title, final int minChoices, final int maxChoices, final Collection list) { - this(title, null, minChoices, maxChoices, list); - } - - /** - *

- * Constructor for ListChooser. - *

- * - * @param title - * a {@link java.lang.String} object. - * @param message - * a {@link java.lang.String} object. - * @param minChoices - * a int. - * @param maxChoices - * a int. - * @param list - * a {@link java.util.List} object. - */ - public ListChooser(final String title, final String message, final int minChoices, final int maxChoices, - final Collection list) { + public ListChooser(final String title, final int minChoices, final int maxChoices, + final List list, boolean startSorted, Comparator sortComparator) { this.title = title; this.minChoices = minChoices; this.maxChoices = maxChoices; this.list = new ArrayList(list); + if (startSorted) { + Collections.sort(this.list, sortComparator); + } this.jList = new JList(new ChooserListModel()); this.ok = new CloseAction(JOptionPane.OK_OPTION, "OK"); this.ok.setEnabled(minChoices == 0); @@ -160,7 +107,7 @@ public class ListChooser { this.jList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); } - this.optionPane = new JOptionPane(new Object[] { message, new JScrollPane(this.jList) }, JOptionPane.QUESTION_MESSAGE, + this.optionPane = new JOptionPane(new JScrollPane(this.jList), JOptionPane.QUESTION_MESSAGE, JOptionPane.DEFAULT_OPTION, null, options, options[0]); this.jList.getSelectionModel().addListSelectionListener(new SelListener()); this.jList.addMouseListener(new DblListener()); @@ -178,7 +125,7 @@ public class ListChooser { /** @return boolean */ public synchronized boolean show() { - return this.show(0); + return show(list.get(0)); } /** @@ -187,7 +134,7 @@ public class ListChooser { * @param index0 index to select when shown * @return a boolean. */ - public synchronized boolean show(int index0) { + public synchronized boolean show(T item) { if (this.called) { throw new IllegalStateException("Already shown"); } @@ -198,7 +145,11 @@ public class ListChooser { this.dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); } - this.jList.setSelectedIndex(index0); + if (list.contains(item)) { + jList.setSelectedValue(item, true); + } else { + jList.setSelectedIndex(0); + } this.dialog.addWindowFocusListener(new WindowFocusListener() { @Override diff --git a/src/main/java/forge/gui/match/QuestWinLose.java b/src/main/java/forge/gui/match/QuestWinLose.java index c8621aff35a..4f2282d750d 100644 --- a/src/main/java/forge/gui/match/QuestWinLose.java +++ b/src/main/java/forge/gui/match/QuestWinLose.java @@ -545,19 +545,18 @@ public class QuestWinLose extends ControlWinLose { if (qData.getFormat() == null) { final List formats = new ArrayList(); - String prefferedFormat = Singletons.getModel().getQuestPreferences().getPreference(QPref.BOOSTER_FORMAT); + String preferredFormat = Singletons.getModel().getQuestPreferences().getPreference(QPref.BOOSTER_FORMAT); - int index = 0, i = 0; + GameFormat pref = null; for (GameFormat f : Singletons.getModel().getFormats()) { formats.add(f); - if (f.toString().equals(prefferedFormat)) { - index = i; + if (f.toString().equals(preferredFormat)) { + pref = f; } - i++; } - final ListChooser ch = new ListChooser("Choose bonus booster format", 1, 1, formats); - ch.show(index); + final ListChooser ch = new ListChooser("Choose bonus booster format", 1, 1, formats, true, null); + ch.show(pref); final GameFormat selected = ch.getSelectedValue(); Singletons.getModel().getQuestPreferences().setPreference(QPref.BOOSTER_FORMAT, selected.toString()); diff --git a/src/main/java/forge/quest/QuestWorld.java b/src/main/java/forge/quest/QuestWorld.java index ec274f09580..f2037dd4457 100644 --- a/src/main/java/forge/quest/QuestWorld.java +++ b/src/main/java/forge/quest/QuestWorld.java @@ -30,7 +30,7 @@ import forge.util.StorageReaderFile; * This function holds the "world info" for the current quest. * */ -public class QuestWorld { +public class QuestWorld implements Comparable{ private final String name; private final String dir; private final GameFormatQuest format; @@ -161,4 +161,21 @@ public class QuestWorld { } } + + /* (non-Javadoc) + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + @Override + public int compareTo(QuestWorld other) { + if (null == other) { + return 1; + } + if (name == other.name) { + return 0; + } + if (null == name) { + return -1; + } + return name.compareTo(other.name); + } } diff --git a/src/test/java/forge/gui/ListChooserTest.java b/src/test/java/forge/gui/ListChooserTest.java index a152266c098..04db9bc30ae 100644 --- a/src/test/java/forge/gui/ListChooserTest.java +++ b/src/test/java/forge/gui/ListChooserTest.java @@ -1,5 +1,7 @@ package forge.gui; +import java.util.Arrays; + import org.testng.annotations.Test; /** @@ -13,7 +15,7 @@ public class ListChooserTest { */ @Test(groups = { "UnitTest", "fast" }, timeOut = 1000, enabled = false) public void listChooserTest1() { - final ListChooser c = new ListChooser("test", "choose a or b", 0, 2, new String[] {"a", "b"}); + final ListChooser c = new ListChooser("choose a or b", 0, 2, Arrays.asList("a", "b"), false, null); System.out.println(c.show()); for (final String s : c.getSelectedValues()) { System.out.println(s);