Skip to content

Commit

Permalink
Implement type to seek for map table in download UI.
Browse files Browse the repository at this point in the history
  • Loading branch information
asvitkine committed Jul 22, 2023
1 parent 849f33f commit f0a7a1a
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,12 @@ private JTabbedPane newAvailableInstalledTabbedPanel(
mapList.getOutOfDateExcluding(pendingDownloads);
// For the UX, always show an available maps tab, even if it is empty
final JPanel available =
newMapSelectionPanel(mapList.getAvailableExcluding(pendingDownloads), MapAction.INSTALL);
newMapSelectionPanel(
mapList.getAvailableExcluding(pendingDownloads), MapAction.INSTALL, true);
tabbedPane.addTab("New Maps", available);

if (!outOfDateDownloads.isEmpty()) {
final JPanel outOfDate = newMapSelectionPanel(outOfDateDownloads, MapAction.UPDATE);
final JPanel outOfDate = newMapSelectionPanel(outOfDateDownloads, MapAction.UPDATE, false);
tabbedPane.addTab("Updates Available", outOfDate);
}

Expand All @@ -247,14 +248,17 @@ private JTabbedPane newAvailableInstalledTabbedPanel(
mapList.getInstalled().keySet().stream()
.sorted(Comparator.comparing(m -> m.getMapName().toUpperCase()))
.collect(Collectors.toList()),
MapAction.REMOVE);
MapAction.REMOVE,
false);
tabbedPane.addTab("Installed", installed);
}
return tabbedPane;
}

private JPanel newMapSelectionPanel(
final List<MapDownloadItem> unsortedMaps, final MapAction action) {
final List<MapDownloadItem> unsortedMaps,
final MapAction action,
final boolean requestFocus) {
final JPanel main = new JPanelBuilder().border(30).borderLayout().build();
final JEditorPane descriptionPane = SwingComponents.newHtmlJEditorPane();
main.add(SwingComponents.newJScrollPane(descriptionPane), BorderLayout.CENTER);
Expand All @@ -264,6 +268,9 @@ private JPanel newMapSelectionPanel(
if (!unsortedMaps.isEmpty()) {
final MapDownloadSwingTable mapDownloadSwingTable = new MapDownloadSwingTable(unsortedMaps);
final JTable gamesList = mapDownloadSwingTable.getSwingComponent();
if (requestFocus) {
SwingUtilities.invokeLater(() -> gamesList.requestFocus());
}
mapDownloadSwingTable.addMapSelectionListener(
mapSelections ->
newDescriptionPanelUpdatingSelectionListener(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.triplea.http.client.maps.listing.MapDownloadItem;
import org.triplea.http.client.maps.listing.MapTag;
import org.triplea.swing.JTableBuilder;
import org.triplea.swing.JTableTypeAheadListener;

/**
* UI component representing a list of maps to download. The table is sortable and displays
Expand Down Expand Up @@ -50,6 +51,7 @@ public MapDownloadSwingTable(final Collection<MapDownloadItem> maps) {
.collect(Collectors.toList()))
.rowMapper(mapDownloadListing -> rowMapper(mapDownloadListing, tagNames))
.build();
table.addKeyListener(new JTableTypeAheadListener(table, 0));
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.triplea.swing;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JTable;
import lombok.RequiredArgsConstructor;

/** A KeyListener that implements row selection in a JTable by prefix-matching typed text. */
@RequiredArgsConstructor
public class JTableTypeAheadListener extends KeyAdapter {
private static int INPUT_RESET_TIME_MS = 500; // 0.5s

private final JTable table;
// Column that contains text data that should be matched.
private final int columnIndex;

private String inputString = "";
private long keyPressTime;

@Override
public void keyPressed(KeyEvent evt) {
char ch = evt.getKeyChar();
if (!Character.isLetterOrDigit(ch)) {
return;
}

long time = System.currentTimeMillis();
if (time > keyPressTime + INPUT_RESET_TIME_MS) {
inputString = "";
}
keyPressTime = keyPressTime;
inputString += Character.toLowerCase(ch);

final var tableModel = table.getModel();
final int rowCount = tableModel.getRowCount();
final int selectedRow = table.getSelectedRow();
for (int i = 0; i < rowCount; i++) {
int row = (selectedRow + i) % rowCount;
String str = "" + tableModel.getValueAt(row, columnIndex);
if (str.toLowerCase().startsWith(inputString)) {
selectRow(row);
break;
}
}
}

private void selectRow(int rowIndex) {
table.setRowSelectionInterval(rowIndex, rowIndex);
table.scrollRectToVisible(table.getCellRect(rowIndex, 0, true));
}
}

0 comments on commit f0a7a1a

Please sign in to comment.