refresh panels
This commit is contained in:
parent
64da0a8b1f
commit
6a9a0f32aa
@ -464,6 +464,14 @@ public class AppConfig {
|
||||
public void setIgnoreLeadingDot(boolean enabled) {
|
||||
properties.setProperty("global.sort.ignore.leadingdot", String.valueOf(enabled));
|
||||
}
|
||||
|
||||
public int getAutoRefreshInterval() {
|
||||
return Integer.parseInt(properties.getProperty("panel.autoRefreshInterval", "2000"));
|
||||
}
|
||||
|
||||
public void setAutoRefreshInterval(int interval) {
|
||||
properties.setProperty("panel.autoRefreshInterval", String.valueOf(interval));
|
||||
}
|
||||
|
||||
// -- Multiple sort criteria persistence
|
||||
public java.util.List<String> getMultipleSortCriteria() {
|
||||
|
||||
@ -69,6 +69,19 @@ public class FileItem {
|
||||
return isDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this item is the same as another item based on metadata.
|
||||
*/
|
||||
public boolean isSameAs(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
FileItem other = (FileItem) obj;
|
||||
return isDirectory == other.isDirectory &&
|
||||
size == other.size &&
|
||||
(name != null ? name.equals(other.name) : other.name == null) &&
|
||||
(modified != null ? modified.getTime() == other.modified.getTime() : other.modified == null);
|
||||
}
|
||||
|
||||
public Icon getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@ -717,6 +717,13 @@ public class FilePanel extends JPanel {
|
||||
updatePathField();
|
||||
}
|
||||
}
|
||||
|
||||
public void refresh(boolean requestFocus) {
|
||||
FilePanelTab tab = getCurrentTab();
|
||||
if (tab != null) {
|
||||
tab.refresh(requestFocus);
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleSelectionAndMoveDown() {
|
||||
FilePanelTab tab = getCurrentTab();
|
||||
|
||||
@ -861,29 +861,7 @@ public class FilePanelTab extends JPanel {
|
||||
lastValidRow = 0;
|
||||
lastValidBriefColumn = 0;
|
||||
|
||||
File[] files = directory.listFiles();
|
||||
List<FileItem> items = new ArrayList<>();
|
||||
|
||||
File parent = directory.getParentFile();
|
||||
if (parent != null) {
|
||||
items.add(new FileItem(parent) {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "..";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (files != null && files.length > 0) {
|
||||
Arrays.sort(files, Comparator
|
||||
.comparing((File f) -> !f.isDirectory())
|
||||
.thenComparing(File::getName, String.CASE_INSENSITIVE_ORDER));
|
||||
|
||||
for (File file : files) {
|
||||
items.add(new FileItem(file));
|
||||
}
|
||||
}
|
||||
|
||||
List<FileItem> items = createFileItemList(directory);
|
||||
tableModel.setItems(items);
|
||||
|
||||
if (viewMode == ViewMode.BRIEF) {
|
||||
@ -912,11 +890,11 @@ public class FilePanelTab extends JPanel {
|
||||
if (autoSelectFirst && fileTable.getRowCount() > 0) {
|
||||
int startIndex = 0;
|
||||
fileTable.setRowSelectionInterval(startIndex, startIndex);
|
||||
if (requestFocus) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
try { fileTable.requestFocusInWindow(); } catch (Exception ignore) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (requestFocus) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
try { fileTable.requestFocusInWindow(); } catch (Exception ignore) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -928,6 +906,94 @@ public class FilePanelTab extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the current directory while attempting to preserve selection and focus.
|
||||
*/
|
||||
public void refresh(boolean requestFocus) {
|
||||
List<FileItem> newItems = createFileItemList(currentDirectory);
|
||||
if (isSameContent(newItems, tableModel.items)) {
|
||||
return;
|
||||
}
|
||||
|
||||
FileItem focused = getFocusedItem();
|
||||
final String focusedName = (focused != null) ? focused.getName() : null;
|
||||
|
||||
final List<String> markedNames = new ArrayList<>();
|
||||
for (FileItem item : tableModel.items) {
|
||||
if (item.isMarked()) {
|
||||
markedNames.add(item.getName());
|
||||
}
|
||||
}
|
||||
|
||||
loadDirectory(currentDirectory, false, requestFocus);
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
// Restore marks
|
||||
for (FileItem item : tableModel.items) {
|
||||
if (markedNames.contains(item.getName())) {
|
||||
item.setMarked(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Restore focus
|
||||
if (focusedName != null) {
|
||||
for (int i = 0; i < tableModel.items.size(); i++) {
|
||||
if (tableModel.items.get(i).getName().equals(focusedName)) {
|
||||
int row = i;
|
||||
if (viewMode == ViewMode.BRIEF) {
|
||||
int selRow = row % tableModel.briefRowsPerColumn;
|
||||
int selCol = row / tableModel.briefRowsPerColumn;
|
||||
briefCurrentColumn = selCol;
|
||||
fileTable.getSelectionModel().setSelectionInterval(selRow, selRow);
|
||||
fileTable.getColumnModel().getSelectionModel().setSelectionInterval(selCol, selCol);
|
||||
fileTable.scrollRectToVisible(fileTable.getCellRect(selRow, selCol, true));
|
||||
} else {
|
||||
fileTable.getSelectionModel().setSelectionInterval(row, row);
|
||||
fileTable.scrollRectToVisible(fileTable.getCellRect(row, 0, true));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fileTable.repaint();
|
||||
updateStatus();
|
||||
});
|
||||
}
|
||||
|
||||
private List<FileItem> createFileItemList(File directory) {
|
||||
if (directory == null || !directory.isDirectory()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
File[] files = directory.listFiles();
|
||||
List<FileItem> items = new ArrayList<>();
|
||||
File parent = directory.getParentFile();
|
||||
if (parent != null) {
|
||||
items.add(new FileItem(parent) {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "..";
|
||||
}
|
||||
});
|
||||
}
|
||||
if (files != null && files.length > 0) {
|
||||
Arrays.sort(files, Comparator
|
||||
.comparing((File f) -> !f.isDirectory())
|
||||
.thenComparing(File::getName, String.CASE_INSENSITIVE_ORDER));
|
||||
for (File file : files) {
|
||||
items.add(new FileItem(file));
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private boolean isSameContent(List<FileItem> list1, List<FileItem> list2) {
|
||||
if (list1.size() != list2.size()) return false;
|
||||
for (int i = 0; i < list1.size(); i++) {
|
||||
if (!list1.get(i).isSameAs(list2.get(i))) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup previous archive temp dir when navigating away from it.
|
||||
*/
|
||||
|
||||
@ -28,6 +28,7 @@ public class MainWindow extends JFrame {
|
||||
private JComboBox<String> commandLine;
|
||||
private JLabel cmdLabel;
|
||||
private AppConfig config;
|
||||
private Timer autoRefreshTimer;
|
||||
|
||||
public MainWindow() {
|
||||
super("KF Manager v" + MainApp.APP_VERSION);
|
||||
@ -55,6 +56,14 @@ public class MainWindow extends JFrame {
|
||||
MainWindow.this.saveConfigAndExit();
|
||||
}
|
||||
});
|
||||
|
||||
// Refresh panels when application gains focus
|
||||
addWindowFocusListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowGainedFocus(WindowEvent e) {
|
||||
refreshPanels();
|
||||
}
|
||||
});
|
||||
|
||||
// After start, set focus and selection to the active panel
|
||||
String initialActiveSide = config.getActivePanel();
|
||||
@ -69,6 +78,9 @@ public class MainWindow extends JFrame {
|
||||
updateActivePanelBorder();
|
||||
updateCommandLinePrompt();
|
||||
});
|
||||
|
||||
// Setup auto-refresh timer from config
|
||||
updateAutoRefreshTimer();
|
||||
}
|
||||
|
||||
private void loadAppIcon() {
|
||||
@ -399,6 +411,18 @@ public class MainWindow extends JFrame {
|
||||
|
||||
toolBar.removeAll();
|
||||
|
||||
// Refresh button
|
||||
JButton btnRefresh = new JButton("↻");
|
||||
btnRefresh.setToolTipText("Refresh active panel");
|
||||
btnRefresh.setFocusable(false);
|
||||
btnRefresh.addActionListener(e -> {
|
||||
if (activePanel != null && activePanel.getCurrentDirectory() != null) {
|
||||
activePanel.refresh(true);
|
||||
}
|
||||
});
|
||||
toolBar.add(btnRefresh);
|
||||
toolBar.addSeparator();
|
||||
|
||||
// Button for BRIEF mode
|
||||
JButton btnBrief = new JButton("☰ Brief");
|
||||
btnBrief.setToolTipText("Brief mode - multiple columns (Ctrl+F1)");
|
||||
@ -725,6 +749,7 @@ public class MainWindow extends JFrame {
|
||||
* Apply appearance settings (font/colors) from config to UI components.
|
||||
*/
|
||||
private void applyAppearanceSettings() {
|
||||
updateAutoRefreshTimer();
|
||||
Font gfont = config.getGlobalFont();
|
||||
if (gfont != null) {
|
||||
// Apply to toolbars, buttons and tables
|
||||
@ -1749,16 +1774,14 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh both panels
|
||||
* Refresh both panels while preserving selection and active panel focus.
|
||||
*/
|
||||
private void refreshPanels() {
|
||||
// Refresh is now automatic upon changes
|
||||
// If manual refresh is needed, we can call loadDirectory
|
||||
if (leftPanel.getCurrentDirectory() != null) {
|
||||
leftPanel.loadDirectory(leftPanel.getCurrentDirectory());
|
||||
if (leftPanel != null && leftPanel.getCurrentDirectory() != null) {
|
||||
leftPanel.refresh(activePanel == leftPanel);
|
||||
}
|
||||
if (rightPanel.getCurrentDirectory() != null) {
|
||||
rightPanel.loadDirectory(rightPanel.getCurrentDirectory());
|
||||
if (rightPanel != null && rightPanel.getCurrentDirectory() != null) {
|
||||
rightPanel.refresh(activePanel == rightPanel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2177,6 +2200,9 @@ public class MainWindow extends JFrame {
|
||||
* Save configuration and exit application
|
||||
*/
|
||||
private void saveConfigAndExit() {
|
||||
if (autoRefreshTimer != null) {
|
||||
autoRefreshTimer.stop();
|
||||
}
|
||||
// Save window state
|
||||
config.saveWindowState(this);
|
||||
|
||||
@ -2257,4 +2283,17 @@ public class MainWindow extends JFrame {
|
||||
activePanel.getFileTable().requestFocusInWindow();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAutoRefreshTimer() {
|
||||
if (autoRefreshTimer != null) {
|
||||
autoRefreshTimer.stop();
|
||||
}
|
||||
int interval = config.getAutoRefreshInterval();
|
||||
autoRefreshTimer = new Timer(interval, e -> {
|
||||
if (activePanel != null && activePanel.getCurrentDirectory() != null) {
|
||||
activePanel.refresh(false);
|
||||
}
|
||||
});
|
||||
autoRefreshTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,6 +209,8 @@ public class SettingsDialog extends JDialog {
|
||||
try {
|
||||
JSpinner mws = (JSpinner) behaviorHolder.getClientProperty("mouseWheelSteps");
|
||||
if (mws != null) config.setBriefMouseWheelSteps((Integer) mws.getValue());
|
||||
JSpinner ari = (JSpinner) behaviorHolder.getClientProperty("autoRefreshInterval");
|
||||
if (ari != null) config.setAutoRefreshInterval((Integer) ari.getValue());
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
|
||||
@ -436,8 +438,17 @@ public class SettingsDialog extends JDialog {
|
||||
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
||||
grid.add(mwSteps, gbc);
|
||||
|
||||
// Auto-refresh interval
|
||||
gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0.0;
|
||||
grid.add(new JLabel("Auto-refresh interval (ms):"), gbc);
|
||||
|
||||
JSpinner refreshInt = new JSpinner(new SpinnerNumberModel(config.getAutoRefreshInterval(), 100, 600000, 100));
|
||||
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
||||
grid.add(refreshInt, gbc);
|
||||
|
||||
p.add(grid, BorderLayout.NORTH);
|
||||
p.putClientProperty("mouseWheelSteps", mwSteps);
|
||||
p.putClientProperty("autoRefreshInterval", refreshInt);
|
||||
panels.put("Behavior", p);
|
||||
return p;
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 164 KiB |
Loading…
x
Reference in New Issue
Block a user