环境: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,其代码如下:

        @Overridepublic Image getImage(Object element) {// 得到文件图标ImageIcon systemIcon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon((File) element);java.awt.Image image = systemIcon.getImage();int width = image.getWidth(null);int height = image.getHeight(null);// 创建用于绘制Icon的缓冲区BufferedImage bufferedImage = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);// 绘制Icon到缓冲区Graphics2D g2d = bufferedImage.createGraphics();g2d.drawImage(image, 0, 0, null);g2d.dispose();// 读取缓冲区图片数据到一个数组int[] data = ((DataBufferInt) bufferedImage.getData().getDataBuffer()).getData();// 根据数组数据生成ImageData对象ImageData imageData = new ImageData(width, height, 24, new PaletteData(0xFF0000, 0x00FF00, 0x0000FF));imageData.setPixels(0, 0, data.length, data, 0);// 生成Image对象Image swtImage = new Image(PlatformUI.getWorkbench().getDisplay(),imageData);return swtImage;}
Icon的确是转换到Image了,看下面的效果图:
虽然Icon转换到了Image,可是图片周围全都是黑色,这是因为Icon在转换的时候,原来的图片里面是透明色的像素点,转换过来系统自动变成了黑色,因此代码还需要额外的处理一下,修改后的代码如下:
  @Overridepublic Image getImage(Object element){//得到文件图标ImageIcon systemIcon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon((File) element);java.awt.Image image = systemIcon.getImage();int width = image.getWidth(null);int height = image.getHeight(null);//创建用于绘制Icon的缓冲区BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//绘制Icon到缓冲区Graphics2D g2d = bufferedImage.createGraphics();g2d.drawImage(image, 0, 0, null);g2d.dispose();//读取缓冲区图片数据到一个数组int[] data = ((DataBufferInt) bufferedImage.getData().getDataBuffer()).getData();//将没有颜色的点设置为白色for (int i = 0; i < data.length; i++){if (data[i] == 0)data[i] = 0xFFFFFF;}//根据数组数据生成ImageData对象ImageData imageData = new ImageData(width, height, 24, new PaletteData(0xFF0000, 0x00FF00, 0x0000FF));imageData.setPixels(0, 0, data.length, data, 0);//生成Image对象Image swtImage = new Image(PlatformUI.getWorkbench().getDisplay(), imageData);return swtImage;}

和上面的代码相比,新增加了一个循环,将缓冲区内为0的数据修改为0xFFFFFF,也就是将相应的像素设置为白色,效果图如下:
看起来效果好多了,可是如果目光敏锐一点的话,还是能够看出破绽来,截取一个图标,放大后仔细看一看:
和正常的图标对比一下,可以发现边边角角的颜色都不对,普遍偏深,可是网上找到的资料到这里就为止了,没有人提出来如何解决这个问题,当然,这也可能跟我的系统有关系。经过跟踪和调试,发现其实调用systemIcon.getImage() 得到的对象就已经是一个BufferedImage对象了,没有必要再去重新new一个,而事实证明,就是这个new操作,导致转换后的图片出现上述问题。
根据systemIcon.getImage()得到BufferedImage对象后,因为该对象内部数据实际上就已经是文件图标数据了,所以调用Graphics2D绘制Icon的操作也没必要了,最后修改后的代码如下:
  @Overridepublic Image getImage(Object element){//得到文件图标ImageIcon systemIcon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon((File) element);java.awt.Image image = systemIcon.getImage();int width = image.getWidth(null);int height = image.getHeight(null);//得到Icon的数据缓冲区BufferedImage bufferedImage = (BufferedImage) systemIcon.getImage();//读取缓冲区图片数据到一个数组int[] data = ((DataBufferInt) bufferedImage.getData().getDataBuffer()).getData();//将没有颜色的点设置为白色for (int i = 0; i < data.length; i++){if (data[i] == 0)data[i] = 0xFFFFFF;}//根据数组数据生成ImageData对象ImageData imageData = new ImageData(width, height, 24, new PaletteData(0xFF0000, 0x00FF00, 0x0000FF));imageData.setPixels(0, 0, data.length, data, 0);//生成Image对象Image swtImage = new Image(PlatformUI.getWorkbench().getDisplay(), imageData);return swtImage;}

这回效果图如下:
看起来好看多了,基本上跟Windows资源管理器的效果差不多了。不过如果目光依旧敏锐的话,再继续打开某一驱动器,看文件夹图标,还是有一点小小的瑕疵,有些Icon在转换过来的时候,会莫名其妙的在原来没有颜色的像素点上增加一点淡淡的颜色。
图片转换的效果虽然也是不错,但是比起原图来,还是有一点差距,眼神好的还是一眼就可以看出来,对于我这样精益求精的人来说总是心里觉得不爽。
这个问题很快就得到了解决。不过不是我刻意用心去寻找解决方案的,而是那一天想找个从dll文件里面提取图标的方法,找来找去,赫然在SWT的官方网站上找到了个例程,其名字就叫做:convert between SWT Image and AWT BufferedImage,TNND,真是无心插柳啊。不过话说回来,这也是典型的灯下黑,当时为了找图片格式转换的方法,在网上搜个昏天黑地的,又试验了各种方法,最后才得到一个不算完美的方法,结果,其实真正完美的解决办法敌人早就放在官方例程里面了。嗯,教训啊。
废话少说,先看下面的图:
左边是从资源管理器截的图,右边是我上一篇文章最后的解决方案转换后生成的图片,可以看到的确还是有个别像素点转换的有问题,convert between SWT Image and AWT BufferedImage的转换代码如下(我配合我的程序,做了一点小小修改,不过关键算法部分没有任何改动):
    public static Image getSWTImageFromSwing(Display display, File file){//得到文件图标ImageIcon imageIcon = (ImageIcon) FileSystemView.getFileSystemView().getSystemIcon(file);if (imageIcon.getImage() instanceof BufferedImage) {BufferedImage bufferedImage = (BufferedImage) imageIcon.getImage();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);//设置每个像素点的颜色与Alpha值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);}}}// 生成Image对象Image swtImage = new Image(display, data);return swtImage;} else return null;}

转载自:http://lancelot.blog.51cto.com/393579/331636 和 http://lancelot.blog.51cto.com/393579/336448。

把Swing的Icon转换到SWT的Image相关推荐

  1. JavaGUI编程 -- Swing之Icon、ImageIcon标签获取当前类同一级文件路径的资源

    1. Swing之Icon.ImageIcon标签&获取当前类同一级文件路径的资源 1.1 Icon标签 这个是使用画笔画自己心怡的图标 示例: package GUI.Swing;impor ...

  2. AWT/SWT/SWING 区别和联系

    1.AWT和Swing由JAVA开发,符合JAVA的跨平台原则,理念上更加支持移植: 2.SWT由IBM资助的eclipse团队开发,采用较为实用的用户体验原则,界面与各个操作系统平台更加接近: 3. ...

  3. 将JavaFX 2.0与Swing和SWT集成

    JavaFX 2.0对JavaFX的改进之一是可以更轻松地与Swing和SWT进行互操作 . 一些在线资源记录了如何完成此操作. 其中包括将JavaFX集成到Swing应用程序和SWT Interop ...

  4. SWT行 AWT/Swing也行系列 1 -实现半透明及不规则窗体

    对于Java来说,GUI开发一直都是项比较头疼的事情.从AWT的功能奇缺,到Swing的臃肿不堪,往如梦魇般困扰着Java开发人员. 于是,有一群人开始走向了邪路-- 这群误入岐途的人(至少Sun是这 ...

  5. java图形化界面编程之Swing

    三. Swing 编程 3.1 Swing概述 ​ 前一章己经介绍过AWT和Swing 的关系 , 因此不难知道 : 实际使用 Java 开发图形界面程序时 ,很少使用 AWT 组件,绝大部分时候都是 ...

  6. 【java毕业设计】基于java+swing+GUI的连连看游戏设计与实现(毕业论文+程序源码)——连连看游戏

    基于java+swing+GUI的连连看游戏设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+swing+GUI的连连看游戏设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦 ...

  7. java开发之图形界面GUI初步-Swing几种常用组件及其应用

    package test; import java.awt.*; import java.awt.event.KeyEvent; import javax.swing.*; /* * 作者:钟志钢 * ...

  8. java swing 例子(一些)

    码码: package swing1;import javax.swing.JFrame; import javax.swing.WindowConstants; public class Empty ...

  9. Swing的设计是MVC的典范

    无论你的项目是否用到了Swing技术,我都要说,Swing是一个设计优秀的Java包,它充满了大师的智慧.假设你学了Java却连一个Button还不会写,就象你学习Visual Basic却不会用Bu ...

最新文章

  1. css rem 大屏开发_px和em、rem单元如何选择?
  2. pandas dataframe column_Python数据分析——Pandas 教程(下)
  3. 面状县级行政区划转地级行政区划,并关联属性字段
  4. MyBatis 源码分析系列文章导读
  5. explode() 字符串转换数组
  6. Android JNI_OnLoad()函数
  7. 数学狂想曲(十一)——高阶统计, 最速降线, 泛函 变分
  8. Insus Binary Utility
  9. 通过百度 vs 奇虎,来谈博客搜索
  10. [AtCoder Educational DP Contest] J - Sushi(期望dp)
  11. JAVA多线程和并发基础面试问答(转载)
  12. 关于tomcat内路径跳转的一些思考
  13. 引入外部js如何通知页面其编码格式
  14. 1024程序员的节日~
  15. TensorFlow中数据读取—如何载入样本
  16. SCPPO(十一):网站发布中的问题锦集—ReportViewer版本问题
  17. 【hiho】127 后缀自动机一·基本概念 【后缀自动机】
  18. 电脑cpu温度过高怎么办_解决电脑主板CPU温度过高,COC机箱提升电脑健康指数
  19. Atitit 常见项目角色与职责 目录 1.1. 常见项目角色与职责 1 1.2. 解决问题思路:一般百度,问同事,问上一级 1 1.3. 解决问题时限:与跳过法 1 1.4. 解决方法,一般实
  20. LabVIEW编程LabVIEW控制Keithley 2400例程与相关资料

热门文章

  1. setTimeout函数的参数
  2. ubuntu 安装中文输入法(超简靠谱版)
  3. A. Chess Placing
  4. 计算机英文缩写ISA,计算机中的英文缩写
  5. mysqldump 使用总结
  6. Spring 增强处理Advice
  7. 微信小程序实现两数相加
  8. node内存溢出:JavaScript heap out of memory
  9. 在微信公众号中使用jquery和微信SDK
  10. 项目实战:ASP.NET:B/S结构 个人空间相册、照片上传下载系统