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