2009-06-10 14 views
9

Desidero visualizzare un albero di file allo stesso modo di java2s.com 'Create a lazy file tree', ma includere le icone di sistema effettive, in particolare per le cartelle. SWT non sembra offrire questo (API programma non supporta le cartelle), quindi mi si avvicinò con il seguente:Come visualizzare l'icona di sistema per un file in 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; 
} 

Tuttavia, le regioni che dovrebbero essere trasparenti sono visualizzati in nero. Come faccio a farlo funzionare, o c'è un altro approccio che dovrei prendere?

Aggiornamento:

Penso che il motivo è che PaletteData non è previsto per la trasparenza a tutti.

Per ora, compilo il BufferedImage con Color.WHITE ora, che è una soluzione accettabile. Tuttavia, mi piacerebbe conoscere la vera soluzione qui ...

risposta

6

è necessario un metodo come il seguente, che è una copia del 99% da 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; 
} 

Poi si può chiamare come:

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

Sono andato con questo approccio. Trovo triste, tuttavia, che devi saltare attraverso questi cerchi per farlo funzionare. –

0

Non ho guardato il codice in dettaglio, ma noto che stai usando TYPE & # x005f; INT & # x005f; RGB invece di TYPE_INT_ARGB (che include supporto alfa/trasparenza).


Guardando Snippet32 sul sito di Eclipse, vedo che di solito è possibile raccogliere le icone utilizzando la classe Program. L'utilizzo dell'estensione ".Folder" non sembra restituire un'istanza, anche se è un membro di getExtensions().

Questo codice può ottenere un icona di una cartella:

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

Questo codice deve raffinato, credo, ma dovrebbe essere un puntatore nella direzione giusta. Ho provato solo su Windows XP in lingua inglese.

+0

passaggio a TYPE_INT_ARGB non cambiare nulla. // Non voglio davvero usare l'euristica per trovare l'icona. Che ne dite di vari tipi di unità, come dischi rigidi, chiavette di memoria, unità DVD, lo nominate? –

1

Per i file, è possibile utilizzare org.eclipse.swt.program.Program per ottenere un'icona (con la corretta trasparenza set) per un dato file che termina:

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

Per le cartelle, si potrebbe considerare semplicemente utilizzando l'icona statica.

+0

No, voglio le icone reali. –

Problemi correlati