diff --git a/src/main/java/cz/kamma/kfmanager/ui/FilePanel.java b/src/main/java/cz/kamma/kfmanager/ui/FilePanel.java index ec1f40c..e295db3 100644 --- a/src/main/java/cz/kamma/kfmanager/ui/FilePanel.java +++ b/src/main/java/cz/kamma/kfmanager/ui/FilePanel.java @@ -19,6 +19,7 @@ public class FilePanel extends JPanel { private JLabel driveInfoLabel; private cz.kamma.kfmanager.config.AppConfig appConfig; private Runnable onDirectoryChangedAll; + private boolean ignoreComboActions = false; public FilePanel(String initialPath) { initComponents(); @@ -112,22 +113,31 @@ public class FilePanel extends JPanel { driveInfoLabel.setFont(new Font("SansSerif", Font.PLAIN, 12)); driveInfoLabel.setBorder(BorderFactory.createEmptyBorder(0,6,0,6)); - // Require explicit confirmation (Enter) to load selected drive. - // Selection changes (mouse/typing) only update the selected item; loading occurs on Enter. - driveCombo.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ENTER, 0), "confirmDrive"); - driveCombo.getActionMap().put("confirmDrive", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - Object selObj = driveCombo.getSelectedItem(); - if (selObj instanceof File) { - File sel = (File) selObj; - FilePanelTab currentTab = getCurrentTab(); - if (currentTab != null) { - currentTab.loadDirectory(sel); - SwingUtilities.invokeLater(() -> { - try { currentTab.getFileTable().requestFocusInWindow(); } catch (Exception ignore) {} - }); - } + // Interaction behavior: + // - Mouse click in dropdown: Refresh immediately. + // - Keyboard navigation (arrows): Update info label only, refresh only on Enter. + driveCombo.addActionListener(e -> { + if (ignoreComboActions) return; + + // Determine if we should trigger directory load. + // We want to skip arrow keys and only react to Mouse or Enter. + java.awt.AWTEvent currentEvent = java.awt.EventQueue.getCurrentEvent(); + if (currentEvent instanceof java.awt.event.KeyEvent) { + java.awt.event.KeyEvent ke = (java.awt.event.KeyEvent) currentEvent; + if (ke.getKeyCode() != java.awt.event.KeyEvent.VK_ENTER) { + return; + } + } + + Object selObj = driveCombo.getSelectedItem(); + if (selObj instanceof File) { + File sel = (File) selObj; + FilePanelTab currentTab = getCurrentTab(); + if (currentTab != null) { + currentTab.loadDirectory(sel); + SwingUtilities.invokeLater(() -> { + try { currentTab.getFileTable().requestFocusInWindow(); } catch (Exception ignore) {} + }); } } }); @@ -413,65 +423,70 @@ public class FilePanel extends JPanel { } private void populateDrives() { - driveCombo.removeAllItems(); - java.util.Set driveSet = new java.util.LinkedHashSet<>(); - - // Add standard roots - File[] roots = File.listRoots(); - if (roots != null) { - for (File r : roots) { - driveSet.add(r); + ignoreComboActions = true; + try { + driveCombo.removeAllItems(); + java.util.Set driveSet = new java.util.LinkedHashSet<>(); + + // Add standard roots + File[] roots = File.listRoots(); + if (roots != null) { + for (File r : roots) { + driveSet.add(r); + } } - } - - // Add home directory - driveSet.add(new File(System.getProperty("user.home"))); - - // On Linux/Unix, add common mount points - String os = System.getProperty("os.name").toLowerCase(); - if (!os.contains("win")) { - // Common Linux/Unix mount points - String user = System.getProperty("user.name"); - // Typical locations for removable media - String[] commonMountPoints = { - "/media/" + user, - "/run/media/" + user, - "/mnt", - "/Volumes" // macOS - }; + // Add home directory + driveSet.add(new File(System.getProperty("user.home"))); - for (String path : commonMountPoints) { - File dir = new File(path); - if (dir.exists() && dir.isDirectory()) { - File[] subDirs = dir.listFiles(); - if (subDirs != null) { - for (File sub : subDirs) { - if (sub.isDirectory()) { - driveSet.add(sub); + // On Linux/Unix, add common mount points + String os = System.getProperty("os.name").toLowerCase(); + if (!os.contains("win")) { + // Common Linux/Unix mount points + String user = System.getProperty("user.name"); + + // Typical locations for removable media + String[] commonMountPoints = { + "/media/" + user, + "/run/media/" + user, + "/mnt", + "/Volumes" // macOS + }; + + for (String path : commonMountPoints) { + File dir = new File(path); + if (dir.exists() && dir.isDirectory()) { + File[] subDirs = dir.listFiles(); + if (subDirs != null) { + for (File sub : subDirs) { + if (sub.isDirectory()) { + driveSet.add(sub); + } } + } else if (!path.contains(user)) { + // For /mnt we might also add the directory itself if it's empty but meant to be used + driveSet.add(dir); } - } else if (!path.contains(user)) { - // For /mnt we might also add the directory itself if it's empty but meant to be used - driveSet.add(dir); } } } - } - - for (File d : driveSet) { - try { - driveCombo.addItem(d); - } catch (Exception ignore) {} - } + + for (File d : driveSet) { + try { + driveCombo.addItem(d); + } catch (Exception ignore) {} + } - // Initialize selection - if (driveCombo.getItemCount() > 0) { - driveCombo.setSelectedIndex(0); - } + // Initialize selection + if (driveCombo.getItemCount() > 0) { + driveCombo.setSelectedIndex(0); + } - // Update info for currently selected drive - updateDriveInfoFromSelection(); + // Update info for currently selected drive + updateDriveInfoFromSelection(); + } finally { + ignoreComboActions = false; + } // Update info label on selection changes (visual selection only) driveCombo.addItemListener(ev -> { @@ -577,6 +592,7 @@ public class FilePanel extends JPanel { FilePanelTab currentTab = getCurrentTab(); if (currentTab != null) { // Update drive combo selection to match current directory + ignoreComboActions = true; try { File cur = currentTab.getCurrentDirectory(); if (cur != null) { @@ -585,7 +601,10 @@ public class FilePanel extends JPanel { // also update info label to reflect current tab's root updateDriveInfo(root); } - } catch (Exception ignore) {} + } catch (Exception ignore) { + } finally { + ignoreComboActions = false; + } } }