Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement type to seek for map table in download UI. #11804

Merged
merged 1 commit into from
Jul 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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));
}
}