fixed scroll panel on archive exit

This commit is contained in:
Radek Davidek 2026-02-20 15:57:15 +01:00
parent a92fe10581
commit 01b8edabd4

View File

@ -65,6 +65,8 @@ public class FilePanelTab extends JPanel {
// we can cleanup older temp directories when navigation changes. // we can cleanup older temp directories when navigation changes.
private Path currentArchiveTempDir = null; private Path currentArchiveTempDir = null;
private File currentArchiveSourceFile = null; private File currentArchiveSourceFile = null;
private File archiveReturnDirectory = null;
private Point archiveReturnViewPosition = null;
private boolean inlineRenameActive = false; private boolean inlineRenameActive = false;
private boolean active = false; private boolean active = false;
private final Map<String, Long> changeTimestamps = new HashMap<>(); private final Map<String, Long> changeTimestamps = new HashMap<>();
@ -1397,6 +1399,7 @@ public class FilePanelTab extends JPanel {
} }
public void showArchiveFile(File archive, String entryName) { public void showArchiveFile(File archive, String entryName) {
rememberArchiveReturnState(archive);
Path temp = extractArchiveToTemp(archive); Path temp = extractArchiveToTemp(archive);
if (temp != null) { if (temp != null) {
// Delete any previous temp dir if different // Delete any previous temp dir if different
@ -1408,6 +1411,11 @@ public class FilePanelTab extends JPanel {
currentArchiveTempDir = temp; currentArchiveTempDir = temp;
currentArchiveSourceFile = archive; currentArchiveSourceFile = archive;
if (entryName == null || entryName.isBlank()) {
loadDirectory(temp.toFile(), true, true);
return;
}
File targetFile = new File(temp.toFile(), entryName); File targetFile = new File(temp.toFile(), entryName);
File targetDir = targetFile.isDirectory() ? targetFile : targetFile.getParentFile(); File targetDir = targetFile.isDirectory() ? targetFile : targetFile.getParentFile();
@ -1420,6 +1428,8 @@ public class FilePanelTab extends JPanel {
} else { } else {
loadDirectory(temp.toFile(), true, true); loadDirectory(temp.toFile(), true, true);
} }
} else {
clearArchiveReturnState();
} }
} }
@ -1494,6 +1504,7 @@ public class FilePanelTab extends JPanel {
if (item.getName().equals("..")) { if (item.getName().equals("..")) {
navigateUp(); navigateUp();
} else if (FileOperations.isArchiveFile(item.getFile())) { } else if (FileOperations.isArchiveFile(item.getFile())) {
rememberArchiveReturnState(item.getFile());
Path temp = extractArchiveToTemp(item.getFile()); Path temp = extractArchiveToTemp(item.getFile());
if (temp != null) { if (temp != null) {
// Delete any previous temp dir if different // Delete any previous temp dir if different
@ -1505,6 +1516,8 @@ public class FilePanelTab extends JPanel {
currentArchiveTempDir = temp; currentArchiveTempDir = temp;
currentArchiveSourceFile = item.getFile(); currentArchiveSourceFile = item.getFile();
loadDirectory(temp.toFile()); loadDirectory(temp.toFile());
} else {
clearArchiveReturnState();
} }
} else if (item.isDirectory()) { } else if (item.isDirectory()) {
loadDirectory(item.getFile()); loadDirectory(item.getFile());
@ -1633,6 +1646,7 @@ public class FilePanelTab extends JPanel {
if (item.getName().equals("..")) { if (item.getName().equals("..")) {
navigateUp(); navigateUp();
} else if (FileOperations.isArchiveFile(item.getFile())) { } else if (FileOperations.isArchiveFile(item.getFile())) {
rememberArchiveReturnState(item.getFile());
Path temp = extractArchiveToTemp(item.getFile()); Path temp = extractArchiveToTemp(item.getFile());
if (temp != null) { if (temp != null) {
try { try {
@ -1643,6 +1657,8 @@ public class FilePanelTab extends JPanel {
currentArchiveTempDir = temp; currentArchiveTempDir = temp;
currentArchiveSourceFile = item.getFile(); currentArchiveSourceFile = item.getFile();
loadDirectory(temp.toFile(), true, true); loadDirectory(temp.toFile(), true, true);
} else {
clearArchiveReturnState();
} }
} else if (item.isDirectory()) { } else if (item.isDirectory()) {
loadDirectory(item.getFile()); loadDirectory(item.getFile());
@ -2007,10 +2023,17 @@ public class FilePanelTab extends JPanel {
deleteTempDirRecursively(currentArchiveTempDir); deleteTempDirRecursively(currentArchiveTempDir);
currentArchiveTempDir = null; currentArchiveTempDir = null;
currentArchiveSourceFile = null; currentArchiveSourceFile = null;
loadDirectory(parent, false); loadDirectory(parent, false, true, () -> {
// Restore original viewport position and keep focus on archive item.
// Select the archive file we just left // In BRIEF mode some selection listeners may still run later, so apply once more on EDT tail.
SwingUtilities.invokeLater(() -> selectItemByName(archiveName)); restoreArchiveReturnPosition();
selectItemByName(archiveName, true, false);
SwingUtilities.invokeLater(() -> {
restoreArchiveReturnPosition();
selectItemByName(archiveName, true, false);
clearArchiveReturnState();
});
});
} }
return; return;
} }
@ -2032,6 +2055,10 @@ public class FilePanelTab extends JPanel {
} }
public void selectItemByName(String name, boolean requestFocus) { public void selectItemByName(String name, boolean requestFocus) {
selectItemByName(name, requestFocus, true);
}
private void selectItemByName(String name, boolean requestFocus, boolean scrollToItem) {
if (viewMode == ViewMode.BRIEF) { if (viewMode == ViewMode.BRIEF) {
// Re-calculate layout if needed before searching to ensure current mapping // Re-calculate layout if needed before searching to ensure current mapping
if (tableModel.items.size() > 0 && (tableModel.briefColumns == 0 || tableModel.briefRowsPerColumn == 0)) { if (tableModel.items.size() > 0 && (tableModel.briefColumns == 0 || tableModel.briefRowsPerColumn == 0)) {
@ -2047,7 +2074,9 @@ public class FilePanelTab extends JPanel {
if (column < fileTable.getColumnCount()) { if (column < fileTable.getColumnCount()) {
briefCurrentColumn = column; briefCurrentColumn = column;
fileTable.setRowSelectionInterval(row, row); fileTable.setRowSelectionInterval(row, row);
if (scrollToItem) {
fileTable.scrollRectToVisible(fileTable.getCellRect(row, column, true)); fileTable.scrollRectToVisible(fileTable.getCellRect(row, column, true));
}
fileTable.repaint(); fileTable.repaint();
if (requestFocus) { if (requestFocus) {
fileTable.requestFocusInWindow(); fileTable.requestFocusInWindow();
@ -2062,7 +2091,9 @@ public class FilePanelTab extends JPanel {
FileItem item = tableModel.getItem(i); FileItem item = tableModel.getItem(i);
if (item != null && item.getName().equalsIgnoreCase(name)) { if (item != null && item.getName().equalsIgnoreCase(name)) {
fileTable.setRowSelectionInterval(i, i); fileTable.setRowSelectionInterval(i, i);
if (scrollToItem) {
fileTable.scrollRectToVisible(fileTable.getCellRect(i, 0, true)); fileTable.scrollRectToVisible(fileTable.getCellRect(i, 0, true));
}
if (requestFocus) { if (requestFocus) {
fileTable.requestFocusInWindow(); fileTable.requestFocusInWindow();
} }
@ -2073,6 +2104,37 @@ public class FilePanelTab extends JPanel {
} }
} }
private void rememberArchiveReturnState(File archiveFile) {
if (archiveFile == null) return;
archiveReturnDirectory = archiveFile.getParentFile();
Rectangle visibleRect = fileTable.getVisibleRect();
archiveReturnViewPosition = (visibleRect != null) ? visibleRect.getLocation() : null;
}
private void restoreArchiveReturnPosition() {
if (archiveReturnViewPosition == null || archiveReturnDirectory == null || currentDirectory == null) return;
if (!currentDirectory.equals(archiveReturnDirectory)) return;
Point target = new Point(archiveReturnViewPosition);
if (fileTable.getParent() instanceof JViewport viewport) {
Dimension pref = fileTable.getPreferredSize();
int contentW = Math.max(fileTable.getWidth(), pref != null ? pref.width : 0);
int contentH = Math.max(fileTable.getHeight(), pref != null ? pref.height : 0);
int maxX = Math.max(0, contentW - viewport.getWidth());
int maxY = Math.max(0, contentH - viewport.getHeight());
target.x = Math.max(0, Math.min(target.x, maxX));
target.y = Math.max(0, Math.min(target.y, maxY));
viewport.setViewPosition(target);
} else {
fileTable.scrollRectToVisible(new Rectangle(target.x, target.y, 1, 1));
}
}
private void clearArchiveReturnState() {
archiveReturnDirectory = null;
archiveReturnViewPosition = null;
}
/** /**
* Public wrapper to select an item by name from outside this class. * Public wrapper to select an item by name from outside this class.
* Useful for other UI components to request focusing a specific file. * Useful for other UI components to request focusing a specific file.