2009-06-10 9 views
9

Chcę wyświetlić drzewo plików podobnie jak java2s.com 'Create a lazy file tree', ale uwzględnij rzeczywiste ikony systemu - szczególnie w przypadku folderów. SWT nie wydają się zaoferować to (program API nie obsługuje foldery), więc wpadłem na następujący:Jak wyświetlić ikonę systemu dla pliku w 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; 
} 

Jednakże regiony, które powinny być przezroczyste są wyświetlane w kolorze czarnym. Jak to działa, czy jest inne podejście, które powinienem podjąć?

Aktualizacja:

Myślę, że powodem jest to, że PaletteData nie jest przeznaczony dla przejrzystości w ogóle.

Na razie wypełniam teraz BufferedImage z Color.WHITE, co jest akceptowalnym sposobem obejścia tego problemu. Mimo to chciałbym poznać prawdziwe rozwiązanie ...

Odpowiedz

6

Trzeba metody takie jak poniżej, co stanowi 99% odpis z 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; 
} 

Następnie można nazwać to lubią:

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

Poszedłem z takim podejściem. Jednak uważam, że trzeba przeskakiwać przez takie obręcze, aby działało. –

0

Nie zajrzałem szczegółowo do kodu, ale zauważyłem, że używasz TYPE & # x005f; INT & # x005f; RGB zamiast TYPE_INT_ARGB (które zawiera obsługę alfa/przezroczystości).


Patrząc na Snippet32 na stronie Eclipse, widzę, że zazwyczaj można odebrać ikony przy użyciu klasy Program. Używanie rozszerzenia ".Folder" nie wydaje się zwracać instancji, mimo że jest członkiem getExtensions().

Kod ten można uzyskać ikonę folderu:

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

Ten kod musi wyrafinowany, jak sądzę, ale powinien być wskaźnikiem we właściwym kierunku. Testowałem tylko w języku angielskim Windows XP.

+0

Przejście do TYPE_INT_ARGB niczego nie zmieni. // Naprawdę nie chcę używać heurystyki, aby znaleźć ikonę. A co z różnego rodzaju dyskami, takimi jak dyski twarde, karty pamięci, napędy DVD? –

1

przypadku plików, można użyć org.eclipse.swt.program.Program uzyskanie ikonę (z właściwej przejrzystości zadanej) dla danego pliku kończącym:

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

przypadku folderów, można rozważyć tylko za pomocą ikony statycznej.

+0

Nie, chcę prawdziwe ikony. –

Powiązane problemy