2009-06-10 13 views
9

Quiero mostrar un árbol de archivos de manera similar a java2s.com 'Create a lazy file tree', pero incluir los iconos del sistema real, especialmente para las carpetas. SWT no parece ofrecer este (API programa no admite carpetas), por lo que se me ocurrió lo siguiente:¿Cómo mostrar el ícono del sistema para un archivo en SWT?

public Image getImage(File file) 
{ 
    ImageIcon systemIcon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon(file); 
    java.awt.Image image = systemIcon.getImage(); 

    int width = image.getWidth(null); 
    int height = image.getHeight(null); 
    BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g2d = bufferedImage.createGraphics(); 
    g2d.drawImage(image, 0, 0, null); 
    g2d.dispose(); 
    int[] data = ((DataBufferInt) bufferedImage.getData().getDataBuffer()).getData(); 
    ImageData imageData = new ImageData(width, height, 24, new PaletteData(0xFF0000, 0x00FF00, 0x0000FF)); 
    imageData.setPixels(0, 0, data.length, data, 0); 
    Image swtImage = new Image(this.display, imageData); 
    return swtImage; 
} 

Sin embargo, las regiones que deben ser transparentes se muestran en negro. ¿Cómo hago que esto funcione, o hay otro enfoque que debería tomar?

Actualización:

Creo que la razón es que PaletteData no está destinado a la transparencia en absoluto.

Por ahora, llené el BufferedImage con Color.WHITE ahora, lo cual es una solución aceptable. Aún así, me gustaría saber la solución real aquí ...

Respuesta

6

se necesita un método como el siguiente, que es una copia del 99% de 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; 
} 

Entonces se le puede llamar como:

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)); 
} 
+1

Fui con ese enfoque. Me parece triste, sin embargo, que tengas que pasar por esos aros para que funcione. –

0

No he visto el código en detalle, pero veo que está utilizando TYPE & # x005f; INT & # x005f; RGB en lugar de TYPE_INT_ARGB (que incluye soporte alfa/transparencia).


En cuanto a Snippet32 en el sitio Eclipse, puedo ver que por lo general puede recoger iconos utilizando la clase Program. El uso de la extensión ".Folder" no parece devolver una instancia, a pesar de que es un miembro de getExtensions().

Este código se puede obtener un icono de carpeta:

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(); 

Ese código necesita refinado, creo, pero debe ser un puntero en la dirección correcta. Solo probé en Windows XP en inglés.

+0

El cambio a TYPE_INT_ARGB no cambió nada. // Realmente no quiero usar heurística para encontrar el ícono. ¿Qué pasa con varios tipos de unidades, como discos duros, tarjetas de memoria, unidades de DVD, lo que sea? –

1

Para los archivos, puede utilizar org.eclipse.swt.program.Program para obtener un icono (con la transparencia correcta conjunto) para un archivo determinado fin:

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

Para las carpetas, es posible considerar simplemente utilizando un icono estático.

+0

No, quiero los íconos reales. –

Cuestiones relacionadas