mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
implement basic find-as-you-type for deck editor tables
This commit is contained in:
@@ -70,16 +70,6 @@ public final class EditorTableModel<T extends InventoryItem> extends AbstractTab
|
|||||||
private final int maxSortDepth = 3;
|
private final int maxSortDepth = 3;
|
||||||
private boolean infiniteSupply;
|
private boolean infiniteSupply;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the infiniteSupply
|
|
||||||
*/
|
|
||||||
public boolean isInfinite() {
|
|
||||||
return infiniteSupply;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new table model, using a JTable,
|
* Instantiates a new table model, using a JTable,
|
||||||
* a column set, and a data set of generic type <T>.
|
* a column set, and a data set of generic type <T>.
|
||||||
@@ -101,7 +91,6 @@ public final class EditorTableModel<T extends InventoryItem> extends AbstractTab
|
|||||||
// Assemble priority sort.
|
// Assemble priority sort.
|
||||||
while (e.hasMoreElements()) {
|
while (e.hasMoreElements()) {
|
||||||
final TableColumnInfo<InventoryItem> col = (TableColumnInfo<InventoryItem>) e.nextElement();
|
final TableColumnInfo<InventoryItem> col = (TableColumnInfo<InventoryItem>) e.nextElement();
|
||||||
|
|
||||||
if (col.getSortPriority() > 0) {
|
if (col.getSortPriority() > 0) {
|
||||||
sortcols[col.getSortPriority()] = col;
|
sortcols[col.getSortPriority()] = col;
|
||||||
}
|
}
|
||||||
@@ -408,11 +397,14 @@ public final class EditorTableModel<T extends InventoryItem> extends AbstractTab
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for this method.
|
* Sets whether this table's pool of cards is in infinite supply. If false, cards in the
|
||||||
* @param infinite
|
* table have a limited number of copies.
|
||||||
*/
|
*/
|
||||||
public void setInfinite(boolean infinite) {
|
public void setInfinite(boolean infinite) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
this.infiniteSupply = infinite;
|
this.infiniteSupply = infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isInfinite() {
|
||||||
|
return infiniteSupply;
|
||||||
|
}
|
||||||
} // CardTableModel
|
} // CardTableModel
|
||||||
|
|||||||
@@ -21,17 +21,22 @@ import java.awt.Color;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.KeyboardFocusManager;
|
import java.awt.KeyboardFocusManager;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusEvent;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
|
import java.awt.event.KeyAdapter;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.JViewport;
|
||||||
import javax.swing.event.TableModelEvent;
|
import javax.swing.event.TableModelEvent;
|
||||||
import javax.swing.event.TableModelListener;
|
import javax.swing.event.TableModelListener;
|
||||||
import javax.swing.table.DefaultTableColumnModel;
|
import javax.swing.table.DefaultTableColumnModel;
|
||||||
@@ -81,19 +86,17 @@ public final class EditorTableView<T extends InventoryItem> {
|
|||||||
/**
|
/**
|
||||||
* TableWithCards.
|
* TableWithCards.
|
||||||
*
|
*
|
||||||
* @param cls
|
* @param type0 the class of item that this table will contain
|
||||||
* the cls
|
|
||||||
*/
|
*/
|
||||||
public EditorTableView(final Class<T> cls) {
|
public EditorTableView(final Class<T> type0) {
|
||||||
this(false, cls);
|
this(false, type0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TableWithCards Constructor.
|
* TableWithCards Constructor.
|
||||||
*
|
*
|
||||||
* @param forceUnique
|
* @param forceUnique whether this table should display only one item with the same name
|
||||||
* a boolean
|
* @param type0 the class of item that this table will contain
|
||||||
* @param type0 the cls
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public EditorTableView(final boolean forceUnique, final Class<T> type0) {
|
public EditorTableView(final boolean forceUnique, final Class<T> type0) {
|
||||||
@@ -197,6 +200,65 @@ public final class EditorTableView<T extends InventoryItem> {
|
|||||||
// prevent tables from intercepting tab focus traversals
|
// prevent tables from intercepting tab focus traversals
|
||||||
table.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
|
table.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
|
||||||
table.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);
|
table.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);
|
||||||
|
|
||||||
|
// highlight items as the user types a portion of their names
|
||||||
|
table.addKeyListener(new _FindAsYouType());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class _FindAsYouType extends KeyAdapter {
|
||||||
|
private StringBuilder str = new StringBuilder();
|
||||||
|
private long lastUpdatedTimestamp;
|
||||||
|
|
||||||
|
private void _findNextMatch(int startIdx) {
|
||||||
|
int numItems = model.getRowCount();
|
||||||
|
if (0 == numItems) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the next item that matches the string
|
||||||
|
startIdx %= numItems;
|
||||||
|
int stopIdx = (startIdx - 1 + numItems) % numItems;
|
||||||
|
String searchStr = str.toString().toLowerCase(Locale.ENGLISH);
|
||||||
|
for (int idx = startIdx; idx != stopIdx; idx = (idx + 1) % numItems) {
|
||||||
|
if (model.rowToCard(idx).getKey().getName().toLowerCase(Locale.ENGLISH).contains(searchStr)) {
|
||||||
|
selectAndScrollTo(idx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
if (KeyEvent.VK_F3 == e.getKeyCode()) {
|
||||||
|
_findNextMatch(table.getSelectedRow() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
long curTime = System.currentTimeMillis();
|
||||||
|
if (5000 < curTime - lastUpdatedTimestamp) {
|
||||||
|
// too long since last update; clear the search string
|
||||||
|
str = new StringBuilder();
|
||||||
|
}
|
||||||
|
lastUpdatedTimestamp = curTime;
|
||||||
|
|
||||||
|
switch (e.getKeyChar()) {
|
||||||
|
case KeyEvent.CHAR_UNDEFINED:
|
||||||
|
return;
|
||||||
|
|
||||||
|
case KeyEvent.VK_BACK_SPACE:
|
||||||
|
if (!str.toString().isEmpty()) {
|
||||||
|
str.deleteCharAt(str.toString().length() - 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
str.append(e.getKeyChar());
|
||||||
|
}
|
||||||
|
|
||||||
|
_findNextMatch(Math.max(0, table.getSelectedRow()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -267,7 +329,7 @@ public final class EditorTableView<T extends InventoryItem> {
|
|||||||
newRow = numRows - 1;
|
newRow = numRows - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.setRowSelectionInterval(newRow, newRow);
|
selectAndScrollTo(newRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -521,4 +583,28 @@ public final class EditorTableView<T extends InventoryItem> {
|
|||||||
public void setWantElasticColumns(boolean value) {
|
public void setWantElasticColumns(boolean value) {
|
||||||
table.setAutoResizeMode(value ? JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS : JTable.AUTO_RESIZE_NEXT_COLUMN);
|
table.setAutoResizeMode(value ? JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS : JTable.AUTO_RESIZE_NEXT_COLUMN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void selectAndScrollTo(int rowIdx) {
|
||||||
|
if (!(table.getParent() instanceof JViewport)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JViewport viewport = (JViewport)table.getParent();
|
||||||
|
|
||||||
|
// compute where we're going and where we are
|
||||||
|
Rectangle targetRect = table.getCellRect(rowIdx, 0, true);
|
||||||
|
Rectangle curViewRect = viewport.getViewRect();
|
||||||
|
|
||||||
|
// if the target cell is not visible, attempt to jump to a location where it is
|
||||||
|
// visible but not on the edge of the viewport
|
||||||
|
if (targetRect.y + targetRect.height > curViewRect.y + curViewRect.height) {
|
||||||
|
// target is below us, move to position 3 rows below target
|
||||||
|
targetRect.setLocation(targetRect.x, targetRect.y + (targetRect.height * 3));
|
||||||
|
} else if (targetRect.y < curViewRect.y) {
|
||||||
|
// target is above is, move to position 3 rows above target
|
||||||
|
targetRect.setLocation(targetRect.x, targetRect.y - (targetRect.height * 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
table.scrollRectToVisible(targetRect);
|
||||||
|
table.setRowSelectionInterval(rowIdx, rowIdx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user