如何在SWT中显示文件的系统图标?

我想显示一个文件树,类似于java2s.com’创建一个懒惰的文件树’ ,但包括实际的系统图标 – 特别是对于文件夹。 SWT似乎没有提供这个(程序API不支持文件夹),所以我想出了以下内容:

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; } 

但是,应该透明的区域以黑色显示。 我如何使这个工作,或者我应该采取另一种方法?

更新:

我认为原因是PaletteData根本不是透明的。

现在,我现在用Color.WHITE填充BufferedImage ,这是一个可接受的解决方法。 不过,我想知道真正的解决方案……

您需要一个类似下面的方法,这是来自http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet156的99%副本.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; } 

然后你可以这样称呼它:

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

对于文件,您可以使用org.eclipse.swt.program.Program获取给定文件结尾的图标(具有正确的设置透明度):

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

对于文件夹,您可以考虑使用静态图标。

我没有详细查看代码,但我注意到你使用的是TYPE_INT_RGB而不是TYPE_INT_ARGB (包括alpha / transparency支持)。


查看Eclipse站点上的Snippet32 ,我可以看到您通常可以使用Program类来获取图标。 使用扩展名“.Folder”似乎不返回实例,即使它是getExtensions()的成员。

此代码可以获取文件夹图标:

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

我认为,该代码需要精炼,但应该是正确方向的指针。 我只在英语Windows XP上测试过。