在进行SWT开发桌面应用过程中,需要大量使用系统资源,比如Image、Cursor、Color等,这些资源的使用往往带来回收管理的问题。
大家知道,自己new的资源系统是不会自动帮你释放的,往往大量的资源new出来没有注销掉会导致资源占用过大直至崩溃。资源的释放应该是在该控件释放前释放,也就是在控件的dispose前释放,但一个界面控件往往非常多,如果每个控件都设置dispose那很麻烦,所以粒度不能过细,个人感觉基于shell足以,但也可以基于控件,看个人需求了。SWT自带了一个资源管理的工具,但使用起来感觉不是那么得心应手,所以自己写了个管理工具类,因为当前需求仅仅用到了Image和Color,所以没有关注其它资源,代码如下:
package org.ci.service;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Resource;
import org.eclipse.swt.widgets.Display;
/**
* 资源管理
* @author xoHome
*/
public class ResourceManage {
private static Map<String, Resource> resource = new HashMap<String, Resource>();
public void create(Map<String, String> urls) {
if(urls == null || urls.size() == 0){
return;
}
for(Map.Entry<String, String> entry : urls.entrySet()){
resource.put(entry.getKey(), getImage(entry.getValue()));
}
}
public void create(Map<String, RGB> rgbs) {
if(rgbs == null || rgbs.size() == 0){
return;
}
for(Map.Entry<String, RGB> entry : rgbs.entrySet()){
resource.put(entry.getKey(), getColor(entry.getValue()));
}
}
public static Resource get(String key){
return resource.get(key);
}
private boolean hasFile(String url) {
File file = new File(url);
if(file == null){
return false;
}
return file.exists();
}
private Image getImage(String url) {
if (hasFile(url)) {
return new Image(Display.getCurrent(), url);
}
return null;
}
private Color getColor(RGB rgb){
return new Color(Display.getCurrent(), rgb);
}
public static void dispose() {
if (resource == null || resource.size() == 0) {
return;
}
for(Resource rs : resource.values()){
if (rs != null && !rs.isDisposed()) {
rs.dispose();
}
}
resource.clear();
}
}
调用过程如下:
Display display = Display.getDefault();
Shell shell = new Shell(display);
ResourceManage r = new ResourceManage();
Map<String, String> urls = new HashMap<String, String>();
urls.put("logo", "img/logo.gif")
r.create(urls);
Button button = new Button(shell, SWT.NONE);
button.setBounds(0,0,50,20);
button.setImage((Image) ResourceManage.get("logo"));
shell.addListener(SWT.Dispose, new Listener() {
@Override
public void handleEvent(Event arg0) {
ResourceManage.dispose();
}
});
这里感觉参数传递还有点麻烦,需要构建Map,这个主要看各自的需求,我项目里就直接传递的JSON字符串。