How to display system icon for a file in SWT?

后端 未结 4 1421
谎友^
谎友^ 2021-01-02 04:40

I want to display a file tree similarly to java2s.com \'Create a lazy file tree\', but include the actual system icons - especially for folders. SWT does not seem to offer t

相关标签:
4条回答
  • 2021-01-02 05:09

    You need a method like the following, which is a 99% copy from http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet156.java?view=co :

    static ImageData convertToSWT(BufferedImage bufferedImage) {
        if (bufferedImage.getColorModel() instanceof DirectColorModel) {
            DirectColorModel colorModel = (DirectColorModel)bufferedImage.getColorModel();
            PaletteData palette = new PaletteData(colorModel.getRedMask(), colorModel.getGreenMask(), colorModel.getBlueMask());
            ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette);
            for (int y = 0; y < data.height; y++) {
                for (int x = 0; x < data.width; x++) {
                    int rgb = bufferedImage.getRGB(x, y);
                    int pixel = palette.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF)); 
                    data.setPixel(x, y, pixel);
                    if (colorModel.hasAlpha()) {
                        data.setAlpha(x, y, (rgb >> 24) & 0xFF);
                    }
                }
            }
            return data;        
        } else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
            IndexColorModel colorModel = (IndexColorModel)bufferedImage.getColorModel();
            int size = colorModel.getMapSize();
            byte[] reds = new byte[size];
            byte[] greens = new byte[size];
            byte[] blues = new byte[size];
            colorModel.getReds(reds);
            colorModel.getGreens(greens);
            colorModel.getBlues(blues);
            RGB[] rgbs = new RGB[size];
            for (int i = 0; i < rgbs.length; i++) {
                rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
            }
            PaletteData palette = new PaletteData(rgbs);
            ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette);
            data.transparentPixel = colorModel.getTransparentPixel();
            WritableRaster raster = bufferedImage.getRaster();
            int[] pixelArray = new int[1];
            for (int y = 0; y < data.height; y++) {
                for (int x = 0; x < data.width; x++) {
                    raster.getPixel(x, y, pixelArray);
                    data.setPixel(x, y, pixelArray[0]);
                }
            }
            return data;
        }
        return null;
    }
    

    Then you can call it like:

    static Image getImage(File file) {
        ImageIcon systemIcon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon(file);
        java.awt.Image image = systemIcon.getImage();
        if (image instanceof BufferedImage) {
            return new Image(display, convertToSWT((BufferedImage)image));
        }
        int width = image.getWidth(null);
        int height = image.getHeight(null);
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = bufferedImage.createGraphics();
        g2d.drawImage(image, 0, 0, null);
        g2d.dispose();
        return new Image(display, convertToSWT(bufferedImage));
    }
    
    0 讨论(0)
  • 2021-01-02 05:16

    share you the code,it works ok for me.

        /** extract the exe file's icon */
    public static Image getImage4exe(String path) {
        /* Use the character encoding for the default locale */
        TCHAR lpszFile = new TCHAR(0, path, true);
        long[] phiconSmall = new long[1];
        OS.ExtractIconEx(lpszFile, 0, null, phiconSmall, 1);
        if (phiconSmall[0] == 0) {
            return null;
        }
        Image ret = Image.win32_new(null, SWT.ICON, phiconSmall[0]);
        return ret;
    }
    
    0 讨论(0)
  • 2021-01-02 05:21

    I haven't looked at the code in detail, but I notice you are using TYPE_INT_RGB instead of TYPE_INT_ARGB (which includes alpha/transparency support).


    Looking at Snippet32 on the Eclipse site, I can see that you can usually pick up icons using the Program class. Using the extension ".Folder" doesn't seem to return an instance, even though it is a member of getExtensions().

    This code can get a folder icon:

    Display display = new Display();
    Shell shell = new Shell(display);
    Label label = new Label(shell, SWT.NONE);
    label.setText("Can't find icon");
    Image image = null;
    for (Program p : Program.getPrograms()) {
      if ("Folder".equals(p.getName())) {
        ImageData data = p.getImageData();
        if (data != null) {
          image = new Image(display, data);
          label.setImage(image);
        }
        break;
      }
    }
    label.pack();
    shell.pack();
    shell.open();
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch())
        display.sleep();
    }
    if (image != null)
      image.dispose();
    display.dispose();
    

    That code needs refined, I think, but should be a pointer in the right direction. I only tested on English-language Windows XP.

    0 讨论(0)
  • 2021-01-02 05:23

    For files, you can use org.eclipse.swt.program.Program to obtain an icon (with correct set transparency) for a given file ending:

    File file=...
    String fileEnding = file.getName().substring(file.getName().lastIndexOf('.'));
    ImageData iconData=Program.findProgram(fileEnding ).getImageData();
    Image icon= new Image(Display.getCurrent(), iconData);
    

    For folders, you might consider just using a static icon.

    0 讨论(0)
提交回复
热议问题