在项目你可能为多个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;
}
}