file icons

This commit is contained in:
Radek Davidek 2026-01-16 18:24:33 +01:00
parent 0d051f240d
commit ae7cf32132

View File

@ -1532,9 +1532,14 @@ public class FilePanelTab extends JPanel {
Icon icon = item.getIcon();
if (item.getName().equals("..")) {
icon = new UpArrowIcon(getForeground());
} else if (item.isDirectory() && persistedConfig != null) {
} else if (item.isDirectory()) {
if (persistedConfig != null) {
icon = new ColoredFolderIcon(persistedConfig.getFolderColor());
}
} else {
// Use type-specific icon for files
icon = new FileSpecificIcon(getFileType(item.getName()));
}
if (viewMode == ViewMode.BRIEF) {
// In BRIEF mode all columns are names
@ -2268,6 +2273,137 @@ public class FilePanelTab extends JPanel {
}
}
/**
* Custom icon for files that provides different visuals for different file types.
*/
private static class FileSpecificIcon implements Icon {
public enum Type { IMAGE, VIDEO, AUDIO, ARCHIVE, CODE, TEXT, DOC, EXEC, OTHER }
private final Type type;
private final Color color;
public FileSpecificIcon(Type type) {
this.type = type;
switch (type) {
case IMAGE: this.color = new Color(70, 130, 180); break; // SteelBlue
case VIDEO: this.color = new Color(205, 92, 92); break; // IndianRed
case AUDIO: this.color = new Color(147, 112, 219); break; // MediumSlateBlue
case ARCHIVE: this.color = new Color(210, 180, 140); break; // Tan
case CODE: this.color = new Color(60, 179, 113); break; // MediumSeaGreen
case TEXT: this.color = Color.GRAY; break;
case DOC: this.color = new Color(70, 90, 180); break; // Darker blue
case EXEC: this.color = new Color(0, 128, 128); break; // Teal
default: this.color = Color.LIGHT_GRAY; break;
}
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(color);
// Draw a basic "sheet" shape
g2.fillRect(x + 3, y + 2, 10, 13);
// Draw a tiny folded corner
g2.setColor(color.darker());
int[] cx = {x + 10, x + 13, x + 10};
int[] cy = {y + 2, y + 5, y + 5};
g2.fillPolygon(cx, cy, 3);
// Draw a small indicator for the type
g2.setColor(Color.WHITE);
switch (type) {
case IMAGE:
g2.fillOval(x + 5, y + 6, 2, 2); // "Sun"
g2.drawRect(x + 5, y + 9, 4, 3); // Simple mountain
break;
case VIDEO:
int[] vxp = {x + 6, x + 6, x + 10};
int[] vyp = {y + 5, y + 11, y + 8};
g2.fillPolygon(vxp, vyp, 3);
break;
case AUDIO:
g2.fillRect(x + 6, y + 5, 3, 2);
g2.fillRect(x + 8, y + 5, 1, 6);
g2.fillOval(x + 5, y + 10, 3, 3);
break;
case ARCHIVE:
g2.drawRect(x + 5, y + 4, 6, 8);
g2.drawLine(x + 5, y + 7, x + 11, y + 7);
g2.drawLine(x + 5, y + 10, x + 11, y + 10);
break;
case CODE:
g2.drawLine(x + 5, y + 9, x + 7, y + 7); // <
g2.drawLine(x + 5, y + 9, x + 7, y + 11);
g2.drawLine(x + 9, y + 7, x + 11, y + 9); // >
g2.drawLine(x + 9, y + 11, x + 11, y + 9);
break;
case TEXT:
case DOC:
g2.drawLine(x + 5, y + 6, x + 11, y + 6);
g2.drawLine(x + 5, y + 9, x + 11, y + 9);
g2.drawLine(x + 5, y + 12, x + 8, y + 12);
break;
case EXEC:
g2.drawOval(x + 5, y + 5, 6, 6);
g2.drawLine(x + 8, y + 4, x + 8, y + 12);
g2.drawLine(x + 4, y + 8, x + 12, y + 8);
break;
default:
break;
}
g2.dispose();
}
@Override
public int getIconWidth() { return 16; }
@Override
public int getIconHeight() { return 16; }
}
private FileSpecificIcon.Type getFileType(String fileName) {
String name = fileName.toLowerCase();
if (name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".png") ||
name.endsWith(".gif") || name.endsWith(".bmp") || name.endsWith(".svg") ||
name.endsWith(".webp") || name.endsWith(".ico") || name.endsWith(".tif")) return FileSpecificIcon.Type.IMAGE;
if (name.endsWith(".mp4") || name.endsWith(".mkv") || name.endsWith(".avi") ||
name.endsWith(".mov") || name.endsWith(".wmv") || name.endsWith(".flv") ||
name.endsWith(".webm") || name.endsWith(".mpg") || name.endsWith(".mpeg")) return FileSpecificIcon.Type.VIDEO;
if (name.endsWith(".mp3") || name.endsWith(".wav") || name.endsWith(".ogg") ||
name.endsWith(".flac") || name.endsWith(".m4a") || name.endsWith(".aac") ||
name.endsWith(".wma")) return FileSpecificIcon.Type.AUDIO;
if (name.endsWith(".zip") || name.endsWith(".rar") || name.endsWith(".7z") ||
name.endsWith(".tar") || name.endsWith(".gz") || name.endsWith(".bz2") ||
name.endsWith(".xz") || name.endsWith(".jar") || name.endsWith(".deb") ||
name.endsWith(".rpm")) return FileSpecificIcon.Type.ARCHIVE;
if (name.endsWith(".java") || name.endsWith(".c") || name.endsWith(".cpp") ||
name.endsWith(".h") || name.endsWith(".py") || name.endsWith(".js") ||
name.endsWith(".html") || name.endsWith(".css") || name.endsWith(".ts") ||
name.endsWith(".xml") || name.endsWith(".json") || name.endsWith(".sh") ||
name.endsWith(".php") || name.endsWith(".kt") || name.endsWith(".cs") ||
name.endsWith(".go") || name.endsWith(".rb") || name.endsWith(".sql")) return FileSpecificIcon.Type.CODE;
if (name.endsWith(".pdf") || name.endsWith(".doc") || name.endsWith(".docx") ||
name.endsWith(".odt") || name.endsWith(".xls") || name.endsWith(".xlsx") ||
name.endsWith(".ppt") || name.endsWith(".pptx") || name.endsWith(".rtf")) return FileSpecificIcon.Type.DOC;
if (name.endsWith(".txt") || name.endsWith(".md") || name.endsWith(".log") ||
name.endsWith(".conf") || name.endsWith(".ini") || name.endsWith(".csv") ||
name.endsWith(".properties")) return FileSpecificIcon.Type.TEXT;
if (name.endsWith(".exe") || name.endsWith(".bin") || name.endsWith(".com") ||
name.endsWith(".bat") || name.endsWith(".msi") || name.endsWith(".appimage")) return FileSpecificIcon.Type.EXEC;
return FileSpecificIcon.Type.OTHER;
}
private void showAssociationDialog(File file) {
String name = file.getName();
String ext = "";