Fix so selection retained when changing sort

Fix so previously played deck restored on Constructed screen
This commit is contained in:
drdev
2014-01-18 19:26:01 +00:00
parent 6c82cabe3a
commit f87b262194
5 changed files with 111 additions and 90 deletions

View File

@@ -94,5 +94,4 @@ public class DecksComboBox extends FComboBoxWrapper<DeckType> {
selectedDeckType = valueOf; selectedDeckType = valueOf;
setSelectedItem(selectedDeckType); setSelectedItem(selectedDeckType);
} }
} }

View File

@@ -8,14 +8,13 @@ import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import forge.Command; import forge.Command;
import forge.Singletons; import forge.Singletons;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckBase; import forge.deck.DeckBase;
import forge.game.GameType; import forge.game.GameType;
import forge.game.player.RegisteredPlayer; import forge.game.player.RegisteredPlayer;
import forge.gui.MouseUtil;
import forge.gui.MouseUtil.MouseCursor;
import forge.gui.deckchooser.DecksComboBox.DeckType; import forge.gui.deckchooser.DecksComboBox.DeckType;
import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.itemmanager.DeckManager; import forge.gui.toolbox.itemmanager.DeckManager;
@@ -32,7 +31,7 @@ import forge.quest.QuestUtil;
public class FDeckChooser extends JPanel implements IDecksComboBoxListener { public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
private boolean isUISetup = false; private boolean isUISetup = false;
private DecksComboBox decksComboBox; private DecksComboBox decksComboBox = new DecksComboBox();
private DeckType selectedDeckType = DeckType.COLOR_DECK; private DeckType selectedDeckType = DeckType.COLOR_DECK;
private final DeckManager lstDecks = new DeckManager(GameType.Constructed); private final DeckManager lstDecks = new DeckManager(GameType.Constructed);
@@ -72,10 +71,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
public DeckType getSelectedDeckType() { return selectedDeckType; } public DeckType getSelectedDeckType() { return selectedDeckType; }
public void setSelectedDeckType(DeckType selectedDeckType0) { public void setSelectedDeckType(DeckType selectedDeckType0) {
if (selectedDeckType != selectedDeckType0) { refreshDecksList(selectedDeckType0, false, null);
selectedDeckType = selectedDeckType0;
decksComboBox.refresh(selectedDeckType0);
}
} }
public DeckManager getLstDecks() { return lstDecks; } public DeckManager getLstDecks() { return lstDecks; }
@@ -271,7 +267,6 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
} }
public void populate() { public void populate() {
setupUI();
removeAll(); removeAll();
this.setLayout(new MigLayout("insets 0, gap 0")); this.setLayout(new MigLayout("insets 0, gap 0"));
decksComboBox.addTo(this, "w 100%, h 30px!, gapbottom 5px, spanx 2, wrap"); decksComboBox.addTo(this, "w 100%, h 30px!, gapbottom 5px, spanx 2, wrap");
@@ -282,6 +277,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
validate(); validate();
repaint(); repaint();
} }
setupUI();
} }
public final boolean isAi() { public final boolean isAi() {
@@ -297,9 +293,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
*/ */
@Override @Override
public void deckTypeSelected(DecksComboBoxEvent ev) { public void deckTypeSelected(DecksComboBoxEvent ev) {
MouseUtil.setMouseCursor(MouseCursor.WAIT_CURSOR); refreshDecksList(ev.getDeckType(), false, ev);
refreshDecksList(ev.getDeckType());
MouseUtil.setMouseCursor(MouseCursor.DEFAULT_CURSOR);
} }
/** /**
@@ -312,18 +306,20 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
if (!isUISetup) { if (!isUISetup) {
// Only do this once. // Only do this once.
isUISetup = true; isUISetup = true;
// core UI components.
decksComboBox = new DecksComboBox();
// monitor events generated by these components. // monitor events generated by these components.
decksComboBox.addListener(this); decksComboBox.addListener(this);
// now everything is in place, fire initial populate event. // now everything is in place, fire initial populate event.
restoreSavedState(); restoreSavedState();
decksComboBox.refresh(selectedDeckType);
} }
} }
private void refreshDecksList(DeckType deckType) { private void refreshDecksList(DeckType deckType, boolean forceRefresh, DecksComboBoxEvent ev) {
if (selectedDeckType == deckType && !forceRefresh) { return; }
selectedDeckType = deckType; selectedDeckType = deckType;
if (ev == null) {
decksComboBox.refresh(deckType);
}
lstDecks.setCaption(deckType.toString()); lstDecks.setCaption(deckType.toString());
switch (deckType) { switch (deckType) {
@@ -386,14 +382,13 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
private void restoreSavedState() { private void restoreSavedState() {
if (stateSetting == null) { if (stateSetting == null) {
//if can't restore saved state, just refresh decks combo box //if can't restore saved state, just refresh deck list
decksComboBox.refresh(selectedDeckType); refreshDecksList(selectedDeckType, true, null);
return; return;
} }
String savedState = prefs.getPref(stateSetting); String savedState = prefs.getPref(stateSetting);
selectedDeckType = getDeckTypeFromSavedState(savedState); refreshDecksList(getDeckTypeFromSavedState(savedState), true, null);
decksComboBox.refresh(selectedDeckType);
lstDecks.setSelectedStrings(getSelectedDecksFromSavedState(savedState)); lstDecks.setSelectedStrings(getSelectedDecksFromSavedState(savedState));
} }

View File

@@ -275,7 +275,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
this.initialized = true; //must set flag just before applying filters this.initialized = true; //must set flag just before applying filters
if (!applyFilters()) { if (!applyFilters()) {
if (this.pool != null) { //ensure view updated even if filter predicate didn't change if (this.pool != null) { //ensure view updated even if filter predicate didn't change
this.updateView(true); this.updateView(true, null, 0);
} }
} }
} }
@@ -430,7 +430,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
this.pool = pool0; this.pool = pool0;
this.model.addItems(this.pool); this.model.addItems(this.pool);
this.model.setInfinite(infinite); this.model.setInfinite(infinite);
this.updateView(true); this.updateView(true, null, 0);
} }
public ItemListView<T> getTable() { public ItemListView<T> getTable() {
@@ -497,8 +497,8 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
* *
* @param item - Item to select * @param item - Item to select
*/ */
public void setSelectedItem(T item) { public boolean setSelectedItem(T item) {
this.table.setSelectedItem(item); return this.table.setSelectedItem(item);
} }
/** /**
@@ -507,8 +507,8 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
* *
* @param items - Items to select * @param items - Items to select
*/ */
public void setSelectedItems(Iterable<T> items) { public boolean setSelectedItems(Iterable<T> items) {
this.table.setSelectedItems(items); return this.table.setSelectedItems(items);
} }
/** /**
@@ -517,7 +517,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
* *
* @param strings - Strings to select * @param strings - Strings to select
*/ */
public void setSelectedStrings(Iterable<String> strings) { public boolean setSelectedStrings(Iterable<String> strings) {
List<T> items = new ArrayList<T>(); List<T> items = new ArrayList<T>();
for (String itemName : strings) { for (String itemName : strings) {
for (Entry<T, Integer> itemEntry : this.pool) { for (Entry<T, Integer> itemEntry : this.pool) {
@@ -527,7 +527,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
} }
} }
} }
this.table.setSelectedItems(items); return this.setSelectedItems(items);
} }
/** /**
@@ -536,12 +536,12 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
* *
* @param itemEntrys - Item entrys to select * @param itemEntrys - Item entrys to select
*/ */
public void selectItemEntrys(Iterable<Entry<T, Integer>> itemEntrys) { public boolean selectItemEntrys(Iterable<Entry<T, Integer>> itemEntrys) {
List<T> items = new ArrayList<T>(); List<T> items = new ArrayList<T>();
for (Entry<T, Integer> itemEntry : itemEntrys) { for (Entry<T, Integer> itemEntry : itemEntrys) {
items.add(itemEntry.getKey()); items.add(itemEntry.getKey());
} }
this.setSelectedItems(items); return this.setSelectedItems(items);
} }
/** /**
@@ -595,12 +595,14 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
* @param qty * @param qty
*/ */
public void addItem(final T item, int qty) { public void addItem(final T item, int qty) {
int selectedIndexBefore = this.getSelectedIndex();
this.pool.add(item, qty); this.pool.add(item, qty);
if (this.isUnfiltered()) { if (this.isUnfiltered()) {
this.model.addItem(item, qty); this.model.addItem(item, qty);
} }
this.updateView(false); List<T> items = new ArrayList<T>();
this.table.setSelectedItem(item); items.add(item);
this.updateView(false, items, selectedIndexBefore);
} }
/** /**
@@ -610,17 +612,17 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
* @param itemsToAdd * @param itemsToAdd
*/ */
public void addItems(Iterable<Entry<T, Integer>> itemsToAdd) { public void addItems(Iterable<Entry<T, Integer>> itemsToAdd) {
int selectedIndexBefore = this.getSelectedIndex();
this.pool.addAll(itemsToAdd); this.pool.addAll(itemsToAdd);
if (this.isUnfiltered()) { if (this.isUnfiltered()) {
this.model.addItems(itemsToAdd); this.model.addItems(itemsToAdd);
} }
this.updateView(false);
List<T> items = new ArrayList<T>(); List<T> items = new ArrayList<T>();
for (Map.Entry<T, Integer> item : itemsToAdd) { for (Map.Entry<T, Integer> item : itemsToAdd) {
items.add(item.getKey()); items.add(item.getKey());
} }
this.setSelectedItems(items); this.updateView(false, items, selectedIndexBefore);
} }
/** /**
@@ -638,8 +640,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
if (this.isUnfiltered()) { if (this.isUnfiltered()) {
this.model.removeItem(item, qty); this.model.removeItem(item, qty);
} }
this.updateView(false); this.updateView(false, selectedItemsBefore, selectedIndexBefore);
this.fixSelection(selectedIndexBefore, selectedItemsBefore);
} }
/** /**
@@ -658,8 +659,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
this.model.removeItem(item.getKey(), item.getValue()); this.model.removeItem(item.getKey(), item.getValue());
} }
} }
this.updateView(false); this.updateView(false, selectedItemsBefore, selectedIndexBefore);
this.fixSelection(selectedIndexBefore, selectedItemsBefore);
} }
/** /**
@@ -670,20 +670,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
public void removeAllItems() { public void removeAllItems() {
this.pool.clear(); this.pool.clear();
this.model.clear(); this.model.clear();
this.updateView(false); this.updateView(false, null, 0);
}
/**
*
* fixSelection.
*
* @param selectedIndexBefore
* @param selectedItemsBefore
*/
private void fixSelection(int selectedIndexBefore, final Iterable<T> selectedItemsBefore) {
if (!this.table.setSelectedItems(selectedItemsBefore)) {
this.table.setSelectedIndex(selectedIndexBefore); //restore selected index if couldn't restore selected items
}
} }
/** /**
@@ -813,7 +800,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
this.filterPredicate = newFilterPredicate; this.filterPredicate = newFilterPredicate;
if (this.pool != null) { if (this.pool != null) {
this.updateView(true); this.updateView(true, this.getSelectedItems(), 0);
} }
return true; return true;
} }
@@ -892,10 +879,10 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
* *
* @param bForceFilter * @param bForceFilter
*/ */
public void updateView(final boolean bForceFilter) { public void updateView(final boolean forceFilter, final Iterable<T> itemsToSelect, final int backupIndexToSelect) {
final boolean useFilter = (bForceFilter && (this.filterPredicate != null)) || !isUnfiltered(); final boolean useFilter = (forceFilter && (this.filterPredicate != null)) || !isUnfiltered();
if (useFilter || this.wantUnique || bForceFilter) { if (useFilter || this.wantUnique || forceFilter) {
this.model.clear(); this.model.clear();
} }
@@ -912,11 +899,11 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
Iterable<Entry<T, Integer>> items = Aggregates.uniqueByLast(this.pool, this.pool.FN_GET_NAME); Iterable<Entry<T, Integer>> items = Aggregates.uniqueByLast(this.pool, this.pool.FN_GET_NAME);
this.model.addItems(items); this.model.addItems(items);
} }
else if (!useFilter && bForceFilter) { else if (!useFilter && forceFilter) {
this.model.addItems(this.pool); this.model.addItems(this.pool);
} }
this.table.getTableModel().refreshSort(); this.table.refresh(itemsToSelect, backupIndexToSelect, false);
for (ItemFilter<? extends T> filter : this.orderedFilters) { for (ItemFilter<? extends T> filter : this.orderedFilters) {
filter.afterFiltersApplied(); filter.afterFiltersApplied();
@@ -938,16 +925,6 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
total = this.pool.countAll(); total = this.pool.countAll();
} }
this.lblRatio.setText("(" + this.getFilteredItems().countAll() + " / " + total + ")"); this.lblRatio.setText("(" + this.getFilteredItems().countAll() + " / " + total + ")");
//select first row if no row already selected
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (table.getCount() > 0 && table.getSelectionCount() == 0) {
table.setSelectedIndex(0);
}
}
});
} }
/** /**

View File

@@ -142,6 +142,7 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
* @param cols &emsp; List<TableColumnInfo<InventoryItem>> of additional columns for this * @param cols &emsp; List<TableColumnInfo<InventoryItem>> of additional columns for this
*/ */
public void setup(final Map<ColumnDef, ItemColumn> cols) { public void setup(final Map<ColumnDef, ItemColumn> cols) {
final Iterable<T> selectedItemsBefore = getSelectedItems();
final DefaultTableColumnModel colmodel = new DefaultTableColumnModel(); final DefaultTableColumnModel colmodel = new DefaultTableColumnModel();
//ensure columns ordered properly //ensure columns ordered properly
@@ -164,7 +165,7 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
this.table.setColumnModel(colmodel); this.table.setColumnModel(colmodel);
this.tableModel.setup(); this.tableModel.setup();
this.tableModel.refreshSort(); this.refresh(selectedItemsBefore, 0, false);
this.table.getTableHeader().setBackground(new Color(200, 200, 200)); this.table.getTableHeader().setBackground(new Color(200, 200, 200));
} }
@@ -210,25 +211,13 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
@Override @Override
protected void onSetSelectedIndex(int index) { protected void onSetSelectedIndex(int index) {
int count = getCount();
if (count == 0) { return; }
if (index >= count) {
index = count - 1;
}
this.table.setRowSelectionInterval(index, index); this.table.setRowSelectionInterval(index, index);
} }
@Override @Override
protected void onSetSelectedIndices(Iterable<Integer> indices) { protected void onSetSelectedIndices(Iterable<Integer> indices) {
int count = getCount();
if (count == 0) { return; }
this.table.clearSelection(); this.table.clearSelection();
for (Integer index : indices) { for (Integer index : indices) {
if (index >= count) {
index = count - 1;
}
this.table.addRowSelectionInterval(index, index); this.table.addRowSelectionInterval(index, index);
} }
} }
@@ -283,6 +272,11 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
return this.table.rowAtPoint(p); return this.table.rowAtPoint(p);
} }
@Override
protected void onRefresh() {
this.tableModel.refreshSort();
}
public final class ItemTable extends SkinnedTable { public final class ItemTable extends SkinnedTable {
@Override @Override
protected JTableHeader createDefaultTableHeader() { protected JTableHeader createDefaultTableHeader() {
@@ -505,16 +499,14 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
return; return;
} }
//backup selected items to restore
final Iterable<T> selectedItemsBefore = getSelectedItems();
// This will invert if needed // This will invert if needed
// 2012/07/21 - Changed from modelIndex to ColumnModelIndex due to a crash
// Crash was: Hide 2 columns, then search by last column.
ItemTableModel.this.cascadeManager.add((ItemColumn) table.getColumnModel().getColumn(columnModelIndex), false); ItemTableModel.this.cascadeManager.add((ItemColumn) table.getColumnModel().getColumn(columnModelIndex), false);
ItemTableModel.this.refreshSort(); refresh(selectedItemsBefore, 0, true);
table.tableChanged(new TableModelEvent(ItemTableModel.this)); table.tableChanged(new TableModelEvent(ItemTableModel.this));
table.repaint(); table.repaint();
if (getCount() > 0) {
table.setRowSelectionInterval(0, 0);
}
SItemManagerIO.savePreferences(getItemManager()); SItemManagerIO.savePreferences(getItemManager());
} }
@@ -544,7 +536,7 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
/** /**
* Resort. * Resort.
*/ */
public void refreshSort() { private void refreshSort() {
if (this.model.getOrderedList().size() == 0) { return; } if (this.model.getOrderedList().size() == 0) { return; }
Collections.sort(this.model.getOrderedList(), new MyComparator()); Collections.sort(this.model.getOrderedList(), new MyComparator());

View File

@@ -59,6 +59,33 @@ public abstract class ItemView<T extends InventoryItem> {
return this.isIncrementalSearchActive; return this.isIncrementalSearchActive;
} }
public void refresh(final Iterable<T> itemsToSelect, final int backupIndexToSelect, final boolean delaySelection) {
onRefresh();
if (delaySelection) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
fixSelection(itemsToSelect, backupIndexToSelect);
}
});
}
else {
fixSelection(itemsToSelect, backupIndexToSelect);
}
}
protected abstract void onRefresh();
private void fixSelection(final Iterable<T> itemsToSelect, final int backupIndexToSelect) {
if (itemsToSelect == null) {
setSelectedIndex(0); //select first item if no items to select
}
else {
if (!setSelectedItems(itemsToSelect)) {
setSelectedIndex(backupIndexToSelect);
}
}
}
public final T getSelectedItem() { public final T getSelectedItem() {
int index = getSelectedIndex(); int index = getSelectedIndex();
return index >= 0 ? getItemAtIndex(index) : null; return index >= 0 ? getItemAtIndex(index) : null;
@@ -98,7 +125,10 @@ public abstract class ItemView<T extends InventoryItem> {
} }
} }
if (indices.size() > 0) { if (indices.size() > 0) {
setSelectedIndices(indices, scrollIntoView); onSetSelectedIndices(indices);
if (scrollIntoView) {
scrollSelectionIntoView();
}
return true; return true;
} }
return false; return false;
@@ -108,6 +138,16 @@ public abstract class ItemView<T extends InventoryItem> {
setSelectedIndex(index, true); setSelectedIndex(index, true);
} }
public void setSelectedIndex(int index, boolean scrollIntoView) { public void setSelectedIndex(int index, boolean scrollIntoView) {
int count = getCount();
if (count == 0) { return; }
if (index < 0) {
index = 0;
}
else if (index >= count) {
index = count - 1;
}
onSetSelectedIndex(index); onSetSelectedIndex(index);
if (scrollIntoView) { if (scrollIntoView) {
scrollSelectionIntoView(); scrollSelectionIntoView();
@@ -118,7 +158,25 @@ public abstract class ItemView<T extends InventoryItem> {
setSelectedIndices(indices, true); setSelectedIndices(indices, true);
} }
public void setSelectedIndices(Iterable<Integer> indices, boolean scrollIntoView) { public void setSelectedIndices(Iterable<Integer> indices, boolean scrollIntoView) {
onSetSelectedIndices(indices); int count = getCount();
if (count == 0) { return; }
List<Integer> indexList = new ArrayList<Integer>();
for (Integer index : indices) {
if (index >= 0 && index < count) {
indexList.add(index);
}
}
if (indexList.isEmpty()) { //if no index in range, set selected index based on first index
for (Integer index : indices) {
setSelectedIndex(index);
return;
}
return;
}
onSetSelectedIndices(indexList);
if (scrollIntoView) { if (scrollIntoView) {
scrollSelectionIntoView(); scrollSelectionIntoView();
} }