環境:Windows7、Eclipse 3.5、JRE1.6
最近在研究SWT的TreeView控件,想要寫一個類似于Windows資料總管的目錄樹,弄了半天,目錄樹是出來了,但是圖示搞不出來,何解?FileSystemView.getFileSystemView().getSystemIcon(File f)這個函數傳回的是個Icon對象,是用在Swing上的,而我的目錄樹采用的是SWT/JFace TreeViewer控件,其ILabelProvider的getImage()接口傳回的是SWT的Image對象。這兩個玩意兒得轉換一下才能使用。
在網上找了半天的資料,發現沒有現成的API可以一句話就完成轉換,都是需要寫一段代碼來完成。有幾個方案,基本思路都是将Icon對象内所包含的Icon資料轉換成資料流,然後根據這個資料流重新生成Image,其代碼如下:
@Override
<b>public</b> Image getImage(Object element)
{
//得到檔案圖示
ImageIcon systemIcon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon((File) element);
java.awt.Image image = systemIcon.getImage();
<b>int</b> width = image.getWidth(<b>null</b>);
<b>int</b> height = image.getHeight(<b>null</b>);
//建立用于繪制Icon的緩沖區
BufferedImage bufferedImage = <b>new</b> BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//繪制Icon到緩沖區
Graphics2D g2d = bufferedImage.createGraphics();
g2d.drawImage(image, 0, 0, <b>null</b>);
g2d.dispose();
//讀取緩沖區圖檔資料到一個數組
<b>int</b>[] data = ((DataBufferInt) bufferedImage.getData().getDataBuffer()).getData();
//根據數組資料生成ImageData對象
ImageData imageData = <b>new</b> ImageData(width, height, 24, <b>new</b> PaletteData(0xFF0000, 0x00FF00, 0x0000FF));
imageData.setPixels(0, 0, data.length, data, 0);
//生成Image對象
Image swtImage = <b>new</b> Image(PlatformUI.getWorkbench().getDisplay(), imageData);
<b>return</b> swtImage;
}
Icon的确是轉換到Image了,看下面的效果圖:
<a href="http://lancelot.blog.51cto.com/attachment/201006/13/393579_12763975514X8E.jpg"></a>
雖然Icon轉換到了Image,可是圖檔周圍全都是黑色,這是因為Icon在轉換的時候,原來的圖檔裡面是透明色的像素點,轉換過來系統自動變成了黑色,是以代碼還需要額外的處理一下,修改後的代碼如下:
//将沒有顔色的點設定為白色
<b>for</b> (<b>int</b> i = 0; i &lt; data.length; i++)
{
<b>if</b> (data[i] == 0)
data[i] = 0xFFFFFF;
}
和上面的代碼相比,新增加了一個循環,将緩沖區内為0的資料修改為0xFFFFFF,也就是将相應的像素設定為白色,效果圖如下:
<a href="http://lancelot.blog.51cto.com/attachment/201006/13/393579_1276397553bu8y.jpg"></a>
看起來效果好多了,可是如果目光敏銳一點的話,還是能夠看出破綻來,截取一個圖示,放大後仔細看一看:
<a href="http://lancelot.blog.51cto.com/attachment/201006/13/393579_12763975540eYR.png"></a>
和正常的圖示對比一下,可以發現邊邊角角的顔色都不對,普遍偏深,可是網上找到的資料到這裡就為止了,沒有人提出來如何解決這個問題,當然,這也可能跟我的系統有關系。經過跟蹤和調試,發現其實調用systemIcon.getImage() 得到的對象就已經是一個BufferedImage對象了,沒有必要再去重新new一個,而事實證明,就是這個new操作,導緻轉換後的圖檔出現上述問題。
根據systemIcon.getImage()得到BufferedImage對象後,因為該對象内部資料實際上就已經是檔案圖示資料了,是以調用Graphics2D繪制Icon的操作也沒必要了,最後修改後的代碼如下:
//得到Icon的資料緩沖區
BufferedImage bufferedImage = (BufferedImage) systemIcon.getImage();
這回效果圖如下:
<a href="http://lancelot.blog.51cto.com/attachment/201006/13/393579_1276397556snvs.jpg"></a>
看起來好看多了,基本上跟Windows資料總管的效果差不多了。不過如果目光依舊敏銳的話,再繼續打開某一驅動器,看檔案夾圖示,還是有一點小小的瑕疵,有些Icon在轉換過來的時候,會莫名其妙的在原來沒有顔色的像素點上增加一點淡淡的顔色,不過影響已經不大了,就姑且這樣吧。期待有高手能夠進一步将其搞定。
本文轉自 tywali 51CTO部落格,原文連結:http://blog.51cto.com/lancelot/331636,如需轉載請自行聯系原作者