diff --git a/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java b/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java index fb33740..498a9dd 100644 --- a/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java +++ b/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java @@ -7,10 +7,12 @@ import cz.kamma.kfmanager.service.ClipboardService; import cz.kamma.kfmanager.service.FileOperations; import javax.swing.*; +import javax.swing.filechooser.FileSystemView; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.JTableHeader; import java.awt.*; +import java.awt.image.BufferedImage; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.datatransfer.DataFlavor; @@ -3059,8 +3061,8 @@ public class FilePanelTab extends JPanel { fileTable.getColumnModel().getColumn(i).setCellRenderer(renderer); } } - private final java.util.Map iconCache = new java.util.HashMap<>(); + private final FileSystemView fileSystemView = FileSystemView.getFileSystemView(); private Icon getItemIcon(FileItem item) { if (item == null) return null; @@ -3068,29 +3070,76 @@ public class FilePanelTab extends JPanel { if (name.equals("..")) { return new UpArrowIcon(getForeground()); } - + String key; if (item.isDirectory()) { Color folderColor = (persistedConfig != null) ? persistedConfig.getFolderColor() : new Color(255, 203, 111); key = "DIR_" + folderColor.getRGB(); } else { - key = "FILE_" + FileSpecificIcon.getFileType(name); + FileSpecificIcon.Type fileType = FileSpecificIcon.getFileType(name); + if (isExecutableWithEmbeddedIcon(item, fileType)) { + File file = item.getFile(); + key = "FILE_EMBEDDED_" + file.getAbsolutePath() + "_" + file.lastModified(); + } else { + key = "FILE_" + fileType; + } } - + Icon cached = iconCache.get(key); if (cached != null) return cached; - + Icon icon; if (item.isDirectory()) { Color folderColor = (persistedConfig != null) ? persistedConfig.getFolderColor() : new Color(255, 203, 111); icon = new ColoredFolderIcon(folderColor); } else { - icon = new FileSpecificIcon(FileSpecificIcon.getFileType(name)); + icon = getExecutableEmbeddedIcon(item); + if (icon == null) { + icon = new FileSpecificIcon(FileSpecificIcon.getFileType(name)); + } } iconCache.put(key, icon); return icon; } + private boolean isExecutableWithEmbeddedIcon(FileItem item, FileSpecificIcon.Type fileType) { + if (MainApp.CURRENT_OS != MainApp.OS.WINDOWS || item == null || fileType != FileSpecificIcon.Type.EXEC) { + return false; + } + File file = item.getFile(); + return file != null && file.isFile() && file.exists(); + } + + private Icon getExecutableEmbeddedIcon(FileItem item) { + if (!isExecutableWithEmbeddedIcon(item, FileSpecificIcon.getFileType(item.getName()))) { + return null; + } + try { + Icon systemIcon = fileSystemView.getSystemIcon(item.getFile()); + return normalizeIconSize(systemIcon, 16, 16); + } catch (Exception ignored) { + return null; + } + } + + private Icon normalizeIconSize(Icon icon, int width, int height) { + if (icon == null) return null; + if (icon.getIconWidth() == width && icon.getIconHeight() == height) { + return icon; + } + + BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); + Graphics2D g2 = image.createGraphics(); + try { + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + icon.paintIcon(null, g2, 0, 0); + } finally { + g2.dispose(); + } + Image scaled = image.getScaledInstance(width, height, Image.SCALE_SMOOTH); + return new ImageIcon(scaled); + } + private int calculateCurrentColumnWidth() { if (tableModel.items == null || tableModel.items.isEmpty()) return 0; @@ -3766,3 +3815,4 @@ public class FilePanelTab extends JPanel { } } } + diff --git a/src/main/java/cz/kamma/kfmanager/ui/MainWindow.java b/src/main/java/cz/kamma/kfmanager/ui/MainWindow.java index 73d6cef..20ade08 100644 --- a/src/main/java/cz/kamma/kfmanager/ui/MainWindow.java +++ b/src/main/java/cz/kamma/kfmanager/ui/MainWindow.java @@ -8,7 +8,9 @@ import cz.kamma.kfmanager.service.FileOperations; import cz.kamma.kfmanager.service.FileOperationQueue; import javax.swing.*; +import javax.swing.filechooser.FileSystemView; import java.awt.*; +import java.awt.image.BufferedImage; import java.awt.datatransfer.DataFlavor; import java.awt.event.*; import java.io.File; @@ -575,16 +577,10 @@ public class MainWindow extends JFrame { if (target.isDirectory()) { customIcon = new ColoredFolderIcon(config.getFolderColor(), s.label); } else { - customIcon = new FileSpecificIcon(FileSpecificIcon.getFileType(target.getName())); + customIcon = getToolbarShortcutIcon(target); } - - // Scale custom icon to toolbar size - java.awt.image.BufferedImage img = new java.awt.image.BufferedImage( - customIcon.getIconWidth(), customIcon.getIconHeight(), java.awt.image.BufferedImage.TYPE_INT_ARGB); - java.awt.Graphics g = img.getGraphics(); - customIcon.paintIcon(null, g, 0, 0); - g.dispose(); - btn.setIcon(new ImageIcon(img.getScaledInstance(iconSize, iconSize, Image.SCALE_SMOOTH))); + + btn.setIcon(scaleIcon(customIcon, iconSize, iconSize)); hasIcon = true; } } catch (Exception ignore) {} @@ -668,6 +664,37 @@ public class MainWindow extends JFrame { toolBar.repaint(); } + + private Icon getToolbarShortcutIcon(File target) { + FileSpecificIcon.Type fileType = FileSpecificIcon.getFileType(target.getName()); + if (MainApp.CURRENT_OS == MainApp.OS.WINDOWS && fileType == FileSpecificIcon.Type.EXEC && target.isFile()) { + try { + Icon systemIcon = FileSystemView.getFileSystemView().getSystemIcon(target); + if (systemIcon != null) { + return systemIcon; + } + } catch (Exception ignored) { + // Fallback to default file-type icon + } + } + return new FileSpecificIcon(fileType); + } + + private Icon scaleIcon(Icon icon, int width, int height) { + if (icon == null) return null; + if (icon.getIconWidth() == width && icon.getIconHeight() == height) { + return icon; + } + BufferedImage img = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); + Graphics g = img.getGraphics(); + try { + icon.paintIcon(null, g, 0, 0); + } finally { + g.dispose(); + } + return new ImageIcon(img.getScaledInstance(width, height, Image.SCALE_SMOOTH)); + } + private void setupMainToolbarButton(JButton btn, String tooltip, Color color) { int btnSize = config != null ? config.getToolbarButtonSize() : 35; if (btnSize < 35) btnSize = 35;