2009-06-10 10 views
9

Je souhaite afficher une arborescence de fichiers de la même manière que java2s.com 'Create a lazy file tree', mais incluez les icônes système actuelles - en particulier pour les dossiers. SWT ne semble pas offrir ce (API du programme ne prend pas en charge les dossiers), alors je suis venu avec ce qui suit:Comment afficher l'icône du système pour un fichier dans 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; 
} 

Cependant, les régions qui devraient être transparentes sont affichées en noir. Comment est-ce que cela fonctionne, ou y a-t-il une autre approche que je devrais suivre?

Mise à jour:

Je pense que la raison est que PaletteData ne vise pas la transparence du tout.

Pour l'instant, je remplis le BufferedImage avec Color.WHITE maintenant, ce qui est une solution de contournement acceptable. Pourtant, je voudrais savoir la vraie solution ici ...

Répondre

6

Vous avez besoin d'une méthode comme suit, qui est une copie de 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; 
} 

Ensuite, vous pouvez l'appeler comme:

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

Je suis allé avec cette approche. Cependant, je trouve triste que vous ayez à traverser de tels obstacles pour que cela fonctionne. –

0

Je n'ai pas regardé le code en détail, mais je remarque que vous utilisez TYPE & # x005f; INT & # x005f; RGB au lieu de TYPE_INT_ARGB (qui inclut le support alpha/transparence).


regardant Snippet32 sur le site Eclipse, je peux voir que vous pourrez récupérer les icônes en utilisant la classe Program. L'utilisation de l'extension ".Folder" ne semble pas renvoyer une instance, même si elle est membre de getExtensions().

Ce code peut obtenir une icône de dossier:

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

Ce code doit raffiné, je pense, mais doit être un pointeur dans la bonne direction. J'ai seulement testé sur Windows XP en anglais.

+0

Le passage à TYPE_INT_ARGB n'a pas changé quoi que ce soit. // Je ne veux pas vraiment utiliser l'heuristique pour trouver l'icône. Qu'en est-il des différents types de disques, tels que les disques durs, les clés USB, les lecteurs de DVD, etc. –

1

Pour les fichiers, vous pouvez utiliser org.eclipse.swt.program.Program pour obtenir une icône (avec la transparence de jeu correct) pour un fichier donné fin

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

Pour les dossiers, vous pouvez envisager simplement en utilisant une icône statique.

+0

Non, je veux les vraies icônes. –