首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 獲取系統文件圖標:FileSystemView 與 ShellFolder 實現

     編輯:Java 相關知識

在 Swing 桌面應用中,根據文件擴展名獲取系統原生圖標(小圖標 16×16、大圖標 32×32/48×48)能顯著提升用戶體驗。本文展示基於 FileSystemView(跨平台小圖標)與 ShellFolder(Windows 大圖標)的組合方案。

核心實現類

import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import sun.awt.shell.ShellFolder;  // 內部 API,僅 Windows

public class FileIconExtractor extends JFrame implements ActionListener {
    private JButton getIconBtn = new JButton("Get Icon");
    private JPanel iconPanel = new JPanel();
    private JTextField extField = new JTextField();
    private JLabel smallIconLabel = new JLabel("Small Icon");
    private JLabel bigIconLabel = new JLabel("Big Icon");

    public FileIconExtractor() {
        setSize(400, 300);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        getIconBtn.setActionCommand("GETICON");
        getIconBtn.addActionListener(this);

        iconPanel.setLayout(new BoxLayout(iconPanel, BoxLayout.Y_AXIS));
        iconPanel.add(smallIconLabel);
        iconPanel.add(bigIconLabel);

        add(extField, BorderLayout.NORTH);
        add(iconPanel, BorderLayout.CENTER);
        add(getIconBtn, BorderLayout.SOUTH);
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if ("GETICON".equals(e.getActionCommand())) {
            String ext = extField.getText().trim();
            if (ext.isEmpty()) return;

            try {
                // 1. 創建臨時文件(帶目標擴展名)
                File file = File.createTempFile("icon", "." + ext);

                // 2. 獲取小圖標(跨平台,FileSystemView)
                FileSystemView fsv = FileSystemView.getFileSystemView();
                Icon smallIcon = fsv.getSystemIcon(file);

                // 3. 獲取大圖標(Windows 專用,ShellFolder)
                Icon bigIcon = null;
                try {
                    ShellFolder shellFolder = ShellFolder.getShellFolder(file);
                    bigIcon = new ImageIcon(shellFolder.getIcon(true));  // true=大圖標
                } catch (Exception ex) {
                    // 非 Windows 或獲取失敗,回退小圖標放大
                    bigIcon = smallIcon;
                }

                // 4. 顯示
                smallIconLabel.setIcon(smallIcon);
                smallIconLabel.setText("Small (16x16): " + ext);
                bigIconLabel.setIcon(bigIcon);
                bigIconLabel.setText("Large (32x32+): " + ext);

                // 5. 清理臨時文件
                file.delete();

            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(FileIconExtractor::new);
    }
}

關鍵技術點

API包來源平台圖標尺寸用途
FileSystemView.getSystemIcon() javax.swing.filechooser 跨平台 16×16 (小) 通用文件列表、樹形圖標
ShellFolder.getShellFolder().getIcon(true) sun.awt.shell (內部) 僅 Windows 32×32/48×48 (大) Windows 風格大圖標視圖

注意事項與最佳實踐

  1. 臨時文件法:系統根據擴展名關聯圖標,創建帶目標後綴的臨時文件最可靠
  2. ShellFolder 是內部 API:sun.* 包不保證跨版本兼容,JDK 9+ 模組化後需 --add-exports 或反射調用
  3. 跨平台回退策略:Windows 用 ShellFolder 大圖標,Linux/macOS 回退放大小圖標或使用圖標主題庫
  4. 緩存優化:同擴展名圖標可緩存 Map,避免重複創建臨時文件
  5. 高 DPI 適配:HiDPI 屏需獲取 48×48 或 256×256 圖標,ShellFolder.getIcon(true) 通常返回系統當前 DPI 對應尺寸

JDK 9+ 模組化訪問 ShellFolder

// 編譯/運行需添加導出
--add-exports java.desktop/sun.awt.shell=ALL-UNNAMED

// 或反射調用(不需編譯時依賴)
Class shellFolderClass = Class.forName("sun.awt.shell.ShellFolder");
Method getShellFolder = shellFolderClass.getDeclaredMethod("getShellFolder", File.class);
Object shellFolder = getShellFolder.invoke(null, file);
Method getIcon = shellFolderClass.getDeclaredMethod("getIcon", boolean.class);
Icon bigIcon = (Icon) getIcon.invoke(shellFolder, true);

獲取系統原生文件圖標是桌面應用專業度的細節體現。組合 FileSystemView(跨平台基礎)與 ShellFolder(Windows 增強),配合緩存與回退策略,能構建健壯的圖標服務層。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved