关于一个TableViewer的注解封装

     在项目你可能为多个TableViewer编写多个IContentProvider和多个ILabelProvider ,那么可以采用注解方式减少。TableViewer这些辅助类的编写。(备注源码转载的,在此谢谢源码作者 solonote )

  这用注解方式类似Hibernate中注解应用消除了xml的描述作用。

 

注解代码重点如下:

一自定义注解类:

 

 

import java.lang.annotation.*;

/**
 * 表格中一列的注解
 * @author solonote
 * @version 0.1.0 2007-12-17 下午05:16:26
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ColumnAnnotation {

	/**
	 * 返回表头
	 * @return 表头
	 */
	String header();

	/**
	 * 返回列宽
	 * @return 列宽
	 */
	int width();
	
	/**
	 * 返回图片所在的BundleId 如果length=0 则不在Bundle中查找图片
	 * @return 图片所在的BundleId 如果length=0 则不在Bundle中查找图片
	 */
	String imageBundleId() default("");
	
	/**
	 * 返回图片的url 如果length=0 则不存在图片
	 * @return 图片的url 如果length=0 则不存在图片
	 */
	String imangURL() default("");

	/**
	 * 返回是否排序
	 * @return 是否排序
	 */
	boolean isSort() default(true);
}

 

  获取各类中对应表各类的注解

 

    /**
     * 
     * @param tClass
     * @return
     * @throws SecurityException
     * @throws NoSuchMethodException
     */
	private List<IColumn> createCloumnList(final Class<?> tClass) throws SecurityException, NoSuchMethodException {
		List<IColumn> columnL = new ArrayList<IColumn>();
		for (Field f : tClass.getDeclaredFields()) 
		{		
			if (f.isAnnotationPresent(ColumnAnnotation.class)) {
				Column column = new Column();
				ColumnAnnotation annotation = f.getAnnotation(ColumnAnnotation.class);
				column.setHeader(annotation.header());
				column.setWidth(annotation.width());
				column.setImageBundleId(annotation.imageBundleId());
				column.setImageURL(annotation.imangURL());
				column.setSort(annotation.isSort());
				Method m = tClass.getMethod(toGetMethodString(f.getName()));
				setGetValueStrategy(m,column);
				if(column.isSort())
				{
					setCompareStrategy(m,column);
				}
				columnL.add(column);
			}		
		}
		return columnL;
	}

 

看看源码:

定义一个比较器接口:

package solonote.common.swt.table;

/**
 * 
 * @author longgangbai
 *
 */
public interface IColumnCompareStrategy {
 public int compare(Object obj1, Object obj2);
}

定义一个获取值的策略:

package solonote.common.swt.table;

/**
 * 列显示内容的策略
 * @author solonote
 * @version 0.1.0 2007-12-17 上午11:39:14
 */
public interface IColumnGetValueStrategy { 
 public String getVlaue(Object obj); 
}

package solonote.common.swt.table;

import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;

import solonote.common.swt.ImageResource;

/**
 * 表中的一列的属性模型
 * @author longgangbai
 *
 */
public class Column implements IColumn{
 
 /**
  * 列标题
  */
 private String header;

 /**
  * 列宽
  */
 private int width;
 
 /**
  * 列的图片资源所在的Bundle的Id
  */
 private String imageBundleId;
 
 /**
  * 列的图片资源URL
  */
 private String imageURL;
 
 /**
  * 是否排序
  */
 private boolean isSort;
 
 /**
  * 列显示内容的策略
  */
 private IColumnGetValueStrategy columnGetValueStrategy;
 
 /**
  * 列比较方法的策略
  */
 private IColumnCompareStrategy columnCompareStrategy;
 
 /**
  * @see solonote.common.swt.table.IColumn#getValue(java.lang.Object)
  */
 public String getValue(Object obj)
 {
  if(columnGetValueStrategy != null)
   return columnGetValueStrategy.getVlaue(obj);
  else
   return "";
 }
 
 /**
  * @see solonote.common.swt.table.IColumn#compare(java.lang.Object, java.lang.Object)
  */
 public int compare(Object obj1, Object obj2)
 {
  if(columnCompareStrategy != null)
   return columnCompareStrategy.compare(obj1, obj2);
  else
   return 0;
 }
 
 /**
  * @see solonote.common.swt.table.IColumn#getImage()
  */
 public Image getImage(){
  if(imageURL.length() == 0)
   return null;
  try{
   if(imageBundleId.length() == 0)
    return ImageResource.getImage(Display.getDefault(),imageURL);
   return ImageResource.getBundleImage(imageBundleId, imageURL); 
  }catch(Exception e)
  {
   return null;
  }
 }

 /**
  * @see solonote.common.swt.table.IColumn#getHeader()
  */
 public String getHeader() {
  return header;
 }

 /**
  * 设置列标题
  * @param header 列标题
  */
 public void setHeader(String header) {
  this.header = header;
 }

 /**
  * @see solonote.common.swt.table.IColumn#getWidth()
  */
 public int getWidth() {
  return width;
 }

 /**
  * 设置列宽
  * @param width 列宽
  */
 public void setWidth(int width) {
  this.width = width;
 }

 /**
  * 返回列的图片资源所在的Bundle的Id
  * @return 列的图片资源所在的Bundle的Id
  */
 public String getImageBundleId() {
  return imageBundleId;
 }

 /**
  * 设置列的图片资源所在的Bundle的Id
  * @param imageBundleId 列的图片资源所在的Bundle的Id
  */
 public void setImageBundleId(String imageBundleId) {
  this.imageBundleId = imageBundleId;
 }

 /**
  * 返回列的图片资源URL
  * @return 列的图片资源URL
  */
 public String getImageURL() {
  return imageURL;
 }

 /**
  * 设置列的图片资源URL
  * @param imageURL 列的图片资源URL
  */
 public void setImageURL(String imageURL) {
  this.imageURL = imageURL;
 }

 /**
  * 返回列显示内容的策略
  * @return 列显示内容的策略
  */
 public IColumnGetValueStrategy getColumnGetValueStrategy() {
  return columnGetValueStrategy;
 }

 /**
  * 设置列显示内容的策略
  * @param columnGetValueStrategy 列显示内容的策略
  */
 public void setColumnGetValueStrategy(
   IColumnGetValueStrategy columnGetValueStrategy) {
  this.columnGetValueStrategy = columnGetValueStrategy;
 }

 /**
  * 返回列比较方法的策略
  * @return 列比较方法的策略
  */
 public IColumnCompareStrategy getColumnCompareStrategy() {
  return columnCompareStrategy;
 }

 /**
  * 设置列比较方法的策略
  * @param columnCompareStrategy 列比较方法的策略
  */
 public void setColumnCompareStrategy(
   IColumnCompareStrategy columnCompareStrategy) {
  this.columnCompareStrategy = columnCompareStrategy;
 }

 /**
  * @see solonote.common.swt.table.IColumn#isSort()
  */
 public boolean isSort() {
  return isSort;
 }

 /**
  * 设置是否排序
  * @param isSort 是否排序
  */
 public void setSort(boolean isSort) {
  this.isSort = isSort;
 }
}

 

package solonote.common.swt.table;

import java.lang.annotation.*;

/**
 * 表格中一列的注解
 * (
 *       @Retention(RetentionPolicy.RUNTIME)
 *       @Target(ElementType.FIELD)
 *       public @interface ColumnAnnotation
 *  
 *       @Retention(RetentionPolicy.RUNTIME) 由此可以看出此处在运行时将注解进行编译的 ,
 *       @Target(ElementType.FIELD) 说明此处仅仅针对表中列的
 * )
 * @author longgangbai
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ColumnAnnotation {

	/**
	 * 返回表头
	 * @return 表头
	 */
	String header();

	/**
	 * 返回列宽
	 * @return 列宽
	 */
	int width();
	
	/**
	 * 返回图片所在的BundleId 如果length=0 则不在Bundle中查找图片
	 * @return 图片所在的BundleId 如果length=0 则不在Bundle中查找图片
	 */
	String imageBundleId() default("");
	
	/**
	 * 返回图片的url 如果length=0 则不存在图片
	 * @return 图片的url 如果length=0 则不存在图片
	 */
	String imangURL() default("");

	/**
	 * 返回是否排序
	 * @return 是否排序
	 */
	boolean isSort() default(true);
}

 

package solonote.common.swt.table;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
 * 注解的一个工具类
 * @author longgangbai
 *
 */
public class ColumnAnnotationFactory {
	
	/**
	 * 定义类对应的类的Map 
	 */
	private HashMap<Class<?>,List<IColumn>> columnMap;
	
	/**
	 * 
	 * @param key 需要获取的类
	 * @return  获取相关的列 
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 */
	public List<IColumn> getCloumnList(Class<?> key) throws SecurityException, NoSuchMethodException
	{
		if(getColumnMap().containsKey(key))
			return getColumnMap().get(key);
		List<IColumn> columnL = createCloumnList(key);
		getColumnMap().put(key, columnL);		
		return columnL;		
	}
	
/**
 *  
 * @param key
 * @return
 * @throws SecurityException
 * @throws NoSuchMethodException
 */
	public IColumn[] getCloumnArray(Class<?> key) throws SecurityException, NoSuchMethodException
	{
		List<IColumn> columnL = getCloumnList(key);
		
		IColumn[] columns = new IColumn[columnL.size()];
		//下面代码可以用一下代码替换,为了保持原著没有替换 
		//columnL.toArray(columns);
		
		//针对 原 author solonote本人认为建议如果采用遍历需要索引尽量采用
		//for(int i=0;i<N ;i++)  下面这种有点费事 
		int i = 0;
		for(IColumn column : columnL)
		{
			columns[i] = column;
			i++;
		}
		return columns;
	}

    /**
     * 获取一个对应的各列的注解信息
     * @param tClass
     * @return
     * @throws SecurityException
     * @throws NoSuchMethodException
     */
	private List<IColumn> createCloumnList(final Class<?> tClass) throws SecurityException, NoSuchMethodException {
		List<IColumn> columnL = new ArrayList<IColumn>();
		for (Field f : tClass.getDeclaredFields()) 
		{		
			if (f.isAnnotationPresent(ColumnAnnotation.class)) {
				Column column = new Column();
				ColumnAnnotation annotation = f.getAnnotation(ColumnAnnotation.class);
				column.setHeader(annotation.header());
				column.setWidth(annotation.width());
				column.setImageBundleId(annotation.imageBundleId());
				column.setImageURL(annotation.imangURL());
				column.setSort(annotation.isSort());
				Method m = tClass.getMethod(toGetMethodString(f.getName()));
				setGetValueStrategy(m,column);
				//如果需要排序设置排序的策略 
				if(column.isSort())
				{
					setCompareStrategy(m,column);
				}
				columnL.add(column);
			}		
		}
		return columnL;
	}
	/**
	 * 如果需要排序设置排序的策略 
	 * 备注:这里貌似有点局限性一般看应用程序的格式,添加相关类型的判断(忽略)
	 * @param m
	 * @param column
	 */
	private void setCompareStrategy(final Method m,Column column) {
		column.setColumnCompareStrategy(new IColumnCompareStrategy(){
			public int compare(Object obj1, Object obj2) {
				try {
					Object field1 = m.invoke(obj1);
					Object field2 = m.invoke(obj2);
					
					if(field1 instanceof Date && field2 instanceof Date)
					{
						Date date1 = (Date) field1;
						Date date2 = (Date) field2;
						if(date1.getTime() > date2.getTime())
							return 1;
						else if(date1.getTime() == date2.getTime())
							return 0;
						else
							return -1;
					}
					else if(field1 instanceof Number && field2 instanceof Number)
					{
						Number number1 = (Number) field1;
						Number number2 = (Number) field2;
						if(number1.doubleValue() > number2.doubleValue())
							return 1;
						else if(number1.doubleValue() == number2.doubleValue())
							return 0;
						else
							return -1;
					}
					return (field1.toString()).compareTo((field2.toString()));
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
				return 0;				
			}
		});
	}
	
	/**
	 * 获取数据的策略 
	 * @param m
	 * @param column
	 */
	private void setGetValueStrategy(final Method m, Column column) {        		  
		column.setColumnGetValueStrategy(new IColumnGetValueStrategy(){
			public String getVlaue(Object obj) {
				try {
					Object value = m.invoke(obj);
					if(value != null)
						return value.toString();
					else
						return "";
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
				return "";
			}   				
		});
	}
	/**
	 * 
	 * @param fieldName
	 * @return
	 */
	private String toGetMethodString(String fieldName)
	{
		char first  = Character.toUpperCase(fieldName.charAt(0));
		return "get" + first + fieldName.substring(1);
	}

	/**
	 * 
	 * @return
	 */
	private HashMap<Class<?>, List<IColumn>> getColumnMap() {
		if(columnMap == null)
			columnMap = new HashMap<Class<?>,List<IColumn>>();
		return columnMap;
	}
}

 

package solonote.common.swt.table;

import org.eclipse.swt.graphics.Image;

/**
 * 表中一列的接口
 * @author longgangbai
 *
 */
public interface IColumn {

	/**
	 * 返回指定泛型对象此列的值
	 * @param obj 指定泛型对象
	 * @return 指定泛型对象此列的值
	 */
	public abstract String getValue(Object obj);

	/**
	 * 比较两个对象此列的大小
	 * @param obj1 对象1
	 * @param obj2 对象2
	 * @return 
	 * <li> 对象1 > 对象2 返回正数
	 * <li> 对象1 = 对象2 返回0
	 * <li> 对象1 < 对象2 返回负数
	 */
	public abstract int compare(Object obj1, Object obj2);

	/**
	 * 返回列图标
	 * @return 列图标
	 */
	public abstract Image getImage();

	/**
	 * 返回列标题
	 * @return 列标题
	 */
	public abstract String getHeader();

	/**
	 * 返回列宽
	 * @return 列宽
	 */
	public abstract int getWidth();
	
	/**
	 * 返回是否排序
	 * @return 是否排序
	 */
	public boolean isSort();
}

 

package solonote.common.swt.table;

import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

/**
 * 一个可重用TableViewer
 * @author longgangbai
 *
 */
public class STableViewer extends TableViewer{
	/**
	 * 表的每一列
	 */
	private IColumn[] columns;
	
	/**
	 * 表中列排序的策略
	 */
	private TableSorter tableSorter;
	
	/**
	 * 构造器
	 * @param table 
	 */
	public STableViewer(IColumn[] columns,Table table) {
		super(table);
		this.columns = columns;
		//创建表中的每一列
		createTableColumns();
		setLabelProvider(new TableLabelProvider(columns));
		this.tableSorter = new TableSorter();
		setSorter(tableSorter);
		this.setContentProvider(new ArrayContentProvider());
	}

	/**
	 * 创建表中的每一列
	 */
	private void createTableColumns() {
		Table table = getTable();
		for(IColumn column : columns)
		{
			final TableColumn tableColumn = new TableColumn(table, SWT.NONE);
			tableColumn.setWidth((int)(column.getWidth()));
			tableColumn.setText(column.getHeader());
			tableColumn.setData(column);
			if(column.isSort())
				tableColumn.addSelectionListener(new RowSelectionListener(column));	
		}		
	}
	
	/**
	 * 列点击事件监听器
	 * @author longgangbai
	 *
	 */
	private class RowSelectionListener extends SelectionAdapter {
		
		private IColumn column;
		
		public RowSelectionListener(IColumn column) {
			this.column = column;
		}

		public void widgetSelected(SelectionEvent e) {
			tableSorter.doSort(column);
			Table table = getTable();
			TableColumn tableColumn= (TableColumn) e.widget;
			table.setSortColumn(tableColumn);
			if (tableSorter.isDescend())
				table.setSortDirection(SWT.UP);
			else
				table.setSortDirection(SWT.DOWN);
			refresh();
		}
	}

}

 

package solonote.common.swt.table;

import org.eclipse.swt.widgets.Table;
/**
 * @author longgangbai
 *
 */
public class STableViewerFactroy {
	/**
	 * 通过注解构造IColumn的工厂
	 */
	private ColumnAnnotationFactory columnAnnotationFactory;
	
	/**
	 * 通过指定table和指定DTO Class类型创建一个STableViewer
	 * @param table 指定table
	 * @param tClass 这个表格要显示的内容DTO
	 * @return 指定table创建的STableViewer
	 * @throws Exception 创建过程中产生的异常
	 */
	public STableViewer createSTableViewer(Table table,Class<?> tClass) throws Exception
	{
		IColumn[] columns = columnAnnotationFactory.getCloumnArray(tClass);
		return new STableViewer(columns,table);
	}

	/**
	 * 返回通过注解构造IColumn的工厂
	 * @return 通过注解构造IColumn的工厂
	 */
	public ColumnAnnotationFactory getColumnAnnotationFactory() {
		return columnAnnotationFactory;
	}

	/**
	 * 设置通过注解构造IColumn的工厂
	 * @param columnAnnotationFactory 通过注解构造IColumn的工厂
	 */
	public void setColumnAnnotationFactory(
			ColumnAnnotationFactory columnAnnotationFactory) {
		this.columnAnnotationFactory = columnAnnotationFactory;
	}
}

 

package solonote.common.swt.table;

import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;

/**
 *  表中一行的显示策略
 * @author longgangbai
 *
 */
public class TableLabelProvider extends LabelProvider implements
		ITableLabelProvider {
	/**
	 * 表中的每一列
	 */
	private IColumn[] columns;
		
	/**
	 * 构造器
	 * @param columns
	 */
	public TableLabelProvider(IColumn[] columns) {
		super();
		this.columns = columns;
	}

	/**
	 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
	 */
	public Image getColumnImage(Object element, int columnIndex) {
		return columns[columnIndex].getImage();
	}

	/**
	 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
	 */
	public String getColumnText(Object element, int columnIndex) {
		return columns[columnIndex].getValue(element);
	}

}

 

package solonote.common.swt.table;

import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.widgets.Table;

/**
 * Render 根据注解过的DTO类型创建指定Table的TableViewer
 * @author longgangbai
 *
 */
public class TableRender {
	/**
	 * 创建TableViewer的工厂
	 */
	private static STableViewerFactroy tableFactory;
	
	/**
	 * 根据注解创建Cloumn的工厂
	 */
	private static ColumnAnnotationFactory columnFactory;
	
	/**
	 * 根据注解过的DTO类型创建指定Table的TableViewer
	 * @param table 指定Table
	 * @param tClass 注解过的DTO类型
	 * @return 创建的TableViewer
	 * @throws Exception Render过程中的异常
	 */
	public static TableViewer renderTable(Table table,Class<?> tClass) throws Exception
	{		
		getTableFactory().setColumnAnnotationFactory(getColumnFactory());
		return getTableFactory().createSTableViewer(table, tClass);
	}

	/**
	 * 返回创建TableViewer的工厂
	 * @return 创建TableViewer的工厂
	 */
	public static STableViewerFactroy getTableFactory() {
		if(tableFactory == null)
			tableFactory = new STableViewerFactroy();
		return tableFactory;
	}

	/**
	 * 返回根据注解创建Cloumn的工厂
	 * @return 根据注解创建Cloumn的工厂
	 */
	public static ColumnAnnotationFactory getColumnFactory() {
		if(columnFactory == null)
			columnFactory = new ColumnAnnotationFactory();
		return columnFactory;
	}

	/**
	 * 设置根据注解创建Cloumn的工厂
	 * @param columnFactory 根据注解创建Cloumn的工厂
	 */
	public static void setColumnFactory(ColumnAnnotationFactory columnFactory) {
		TableRender.columnFactory = columnFactory;
	}
}

 

package solonote.common.swt.table;

import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;

/**
 * 表中列排序的策略
 * @author longgangbai
 *
 */
public class TableSorter extends ViewerSorter {

	/**
	 * 表中的一列
	 */
	private IColumn column;
	
	/**
	 * 是否降序
	 */
	private boolean isDescend;
	
	/**
	 * 对指定的列排序
	 * @param column 指定的列
	 */
	public void doSort(IColumn column)
	{
		if(this.column == column)
			isDescend =	 !isDescend;
		else
		{
			this.column = column;
		}			
	}
	
	/**
	 * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
	 */
	public int compare(Viewer viewer,Object obj1,Object obj2)
	{
		if(column == null)
			return 0;
		if(isDescend)
			return column.compare(obj2, obj1);
		else			
			return column.compare(obj1, obj2);
	}

	/**
	 * 返回是否降序
	 * @return 是否降序
	 */
	public boolean isDescend() {
		return isDescend;
	}
}

 

 

 

你可能感兴趣的:(eclipse,Hibernate,F#,UP)