论坛首页 综合技术论坛

自己的通用的表格

浏览 1916 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-12-28  

建立了一个自己的通用的表格:

a)Comp为Table的父亲,在这个上面建table,class是要显示的实体类,ignoreList中,如果和class的filed名字一样就不建立这个列。
b)列隐藏伸展
c)显示默认就对应类的Field的toString
d)上下自动滚动。
e)Ctrl+鼠标滚动列。
f)当点击Table的其他位置的时候,就是没有Item的位置的时候,取消所以的选择。
g)列的Properties就是列的Class的Field。(还不知道Properties有用否)

代码:

public class MyTable {
	private static String 		RESTORE_COL_WIDTH 	= "restoredWidth";
	
	private TableViewer			v;
	private Table				t;
	private MenuManager 		tableContextMenu;
	private List<String> 		ignoreList;
	private List<String>		propertis;
	
	private Map<String,TableViewerColumn> columMap = new HashMap<String,TableViewerColumn>();

	/*
	 * for auto scroll
	 */
	private Runnable 	Heartbeat;
	private boolean 	Tracking;
	private int 		ScrollSpeed = 400;

	public MyTable(Composite comp, Class<?> clazz) {
		createTable(comp,clazz);
	}
	public MyTable(Composite comp, Class<?> clazz, List<String> ignoreList) {
		this.ignoreList = ignoreList;
		createTable(comp,clazz);
	}
	
	private void createTable(Composite comp, Class<?> clazz) {
		v = new TableViewer(comp, SWT.FULL_SELECTION | SWT.MULTI);
		t = v.getTable();
		t.setLinesVisible(true);
		t.setHeaderVisible(true);
		v.setContentProvider(new MyContentProvider());

		getPropertis(clazz);
		v.setColumnProperties(propertis.toArray(new String[0]));

		createColumn();
		setTableMenu();
		
		addVerticalAutoScroll();
		addCtrlScroll();
		addDesWhenNull();

		v.setInput(new TableData());
	}
	
	private void addDesWhenNull() {
		/*
		 * deselectAll when mouse click a space in table.
		 */
		t.addMouseListener(new MouseAdapter() {
			public void mouseDown(MouseEvent e) {
				if(t.getItem(new Point(e.x,e.y)) == null ) {
					t.deselectAll();
				}
			}
		});
	}
	private void addCtrlScroll() {
		t.addMouseWheelListener(new MouseWheelListener() {
			public void mouseScrolled(MouseEvent e) {
				if (e.stateMask == SWT.CTRL) {
					/*
					 * using getClientArea().width, hBar.getSelection(), e.count to calc
					 * which column to show.
					 * t.showColumn();
					 */
					
					ScrollBar hBar = t.getHorizontalBar();
					if(hBar != null) {
						TableColumn col = getShowColumn(hBar,e.count);
						if(col != null)
							t.showColumn(col);
					}
				}
			}

			private TableColumn getShowColumn(ScrollBar hBar, int count) {
				TableColumn col;
				TableColumn[] cols = t.getColumns();
				int totalWidth 	= t.getBounds().width;
				int hBarLeft 	= hBar.getSelection();
				int hBarRight 	= hBar.getMaximum() - hBar.getThumb() - hBar.getSelection();
				
				if(count > 0) {
					int colsWidth = 0 - hBarRight;
					for(int i=cols.length-1; i > -1; i--) {
						col = cols[i];
						colsWidth += col.getWidth();
						if(colsWidth > totalWidth)
							return col;
					}
				} else {
					int colsWidth = 0 - hBarLeft;
					for(int i=0; i < cols.length; i++) {
						col = cols[i];
						colsWidth += col.getWidth();
						if(colsWidth > totalWidth)
							return col;
					}
				}
				return null;
			}
		});
	}
	private void addVerticalAutoScroll() {
		/*
		 * swt.snippets.Snippet221
		 */
		
		Heartbeat = new Runnable() {
			public void run() {
				if(!Tracking || t.isDisposed()) return;
				Point cursor = Display.getCurrent().getCursorLocation();
				cursor = Display.getCurrent().map(null, t, cursor);
				Scroll(t, cursor);
				Display.getCurrent().timerExec(ScrollSpeed, Heartbeat);
			}

			private void Scroll(Table t, Point cursor) {
				TableItem item = t.getItem(cursor);
				if (item == null) return;
				int index = t.indexOf(item);
				if(index == 0 || index == t.getItemCount()-1)
					return;
				Rectangle area = t.getClientArea();
				int headerHeight = t.getHeaderHeight();
				int itemHeight= t.getItemHeight();
				if (cursor.y < area.y + headerHeight + 2 * itemHeight) {
					// mouse in the first or second item.
					index --;
				}
				if (cursor.y > area.y + area.height - 2 * itemHeight) {
					// mouse in the last first or second item.
					index ++;
				}
				if(index>-1 && index<t.getItemCount())
					t.showItem(t.getItem(index));
			}

		};
		Listener listener = new Listener() {
			public void handleEvent(Event event) {
				switch (event.type) {
				case SWT.MouseEnter:
					Tracking = true;
					Display.getCurrent().timerExec(0, Heartbeat);
					break;
				case SWT.MouseExit:
					Tracking = false;
					break;
				}
			}
		};
		t.addListener(SWT.MouseEnter, listener); 
		t.addListener(SWT.MouseExit, listener);
	}
	
	private void setTableMenu() {
		final MenuManager headerMenu = new MenuManager();
		addAction2HeaderMenu(headerMenu);

		t.addListener(SWT.MenuDetect, new Listener() {
			public void handleEvent(Event event) {
				Point pt = Display.getCurrent().map(null, t, new Point(event.x, event.y));
				Rectangle clientArea = t.getClientArea();
				boolean header = clientArea.y <= pt.y && pt.y < (clientArea.y + t.getHeaderHeight());
				if(header) {
					t.setMenu(headerMenu.createContextMenu(t));
				} else {
					if(tableContextMenu != null)
						t.setMenu(tableContextMenu.createContextMenu(t));
				}
			}
		});
	}

	private void addAction2HeaderMenu(MenuManager menu) {
		Action action;
		for(int i = 0; i < t.getColumnCount(); i++ ) {
			final TableColumn column = t.getColumn(i);
			action = new Action(t.getColumn(i).getText(),SWT.CHECK) {
				public void run() {
					if(!isChecked()) {
						ShrinkThread t = new ShrinkThread(column.getWidth(),column);
						t.run();
					} else {
						ExpandThread t = new ExpandThread(((Integer)column.getData(RESTORE_COL_WIDTH)).intValue(),column);
						t.run();
					}
				}
			};
			action.setChecked(true);
			menu.add(action);
		}
	}

	private void createColumn() {
		for(String property : propertis) {
			TableViewerColumn column = new TableViewerColumn(v, SWT.NONE);
			column.getColumn().setWidth(200);
			column.getColumn().setText(property);
			column.getColumn().setMoveable(true);
			
			column.setLabelProvider(new MyColumnLabelProvider(property));
			
			columMap.put(property, column);
		}
	}
	
	public List<String> getPropertis() {
		return propertis;
	}
	private void getPropertis(Class<?> clazz) {
		propertis = new ArrayList<String>();
		String name;
		for(Field f : clazz.getDeclaredFields()) {
			name = f.getName();
			if(!ignoreList.contains(name))
				propertis.add(f.getName());
		}
	}
	
	public void add(Object o) {
		((TableData)v.getInput()).add(o);
	}
	public void remove(Object o) {
		((TableData)v.getInput()).remove(o);
	}
	public void removeAll() {
		v.setInput(new TableData());
	}
	public void setColumnWidth(int width) {
		for(TableColumn col : v.getTable().getColumns())
			col.setWidth(width);
	}
	public void setColumnWidth(int[] widths) {
		int min = Math.min(widths.length, t.getColumnCount());
		for(int i=0; i<min; i++) {
			t.getColumn(i).setWidth(widths[i]);
		}
	}
	public void setColumnName(String[] names) {
		int min = Math.min(names.length, t.getColumnCount());
		for(int i=0; i<min; i++) {
			t.getColumn(i).setText(names[i]);
		}
	}
	public TableViewerColumn getTableViewerColumn(String property) {
		return columMap.get(property);
	}
	public void setColumnLabelProvider(String property,ColumnLabelProvider columnLabelProvider) {
		columMap.get(property).setLabelProvider(columnLabelProvider);
	}
	public void setContextMenu(MenuManager menu) {
		tableContextMenu = menu;
	}
	public TableViewer getTableViewer() {
		return v;
	}
	/**
	 * column shrink
	 */
	private class ShrinkThread extends Thread {

		private int width = 0;
		private TableColumn column;
		public ShrinkThread(int width, TableColumn column) {
			super();
			this.width = width;
			this.column = column;
		}
		public void run() {
			column.getDisplay().syncExec(new Runnable() {
				public void run() {
					column.setData(RESTORE_COL_WIDTH, new Integer(width));
				}
			});
			for(int i = width; i >= 0; i--) {
				final int index = i;
				column.getDisplay().syncExec(new Runnable() {
					public void run() {
						column.setWidth(index);
					}
				});
			}
			column.setResizable(false);
		}
	};

	/**
	 * column Expand
	 */
	private class ExpandThread extends Thread {
		private int width = 0;
		private TableColumn column;
		public ExpandThread(int width, TableColumn column) {
			super();
			this.width = width;
			this.column = column;
		}
		public void run() {
			for(int i = 0; i <= width; i++) {
				final int index = i;
				column.getDisplay().syncExec(new Runnable() {
					public void run() {
						column.setWidth(index);
					}
				});
			}
			column.setResizable(true);
		}
	}

	private class MyContentProvider implements IStructuredContentProvider ,PropertyChangeListener{
		private TableViewer viewer;
		
		public Object[] getElements(Object inputElement) {
			if(inputElement instanceof TableData)
				return ((TableData)inputElement).elements();
			return null;
		}
		public void dispose() {}
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			this.viewer = (TableViewer) viewer;
			
			if (oldInput instanceof TableData)
				((TableData) oldInput).removePropertyChangeListener(this);
			if (newInput instanceof TableData) {
				((TableData) newInput).addPropertyChangeListener(this);
			}
		}
		
		public void propertyChange(PropertyChangeEvent event) {
			if (TableData.ADD_ELEMENT.equals(event.getPropertyName()))
				viewer.add(event.getNewValue());
			if (TableData.REMOVE_ELEMENT.equals(event.getPropertyName()))
				viewer.remove(event.getNewValue());
		}
	}
	private class MyColumnLabelProvider extends ColumnLabelProvider {
		private String FieldName;

		public MyColumnLabelProvider(String columnText) {
			super();
			this.FieldName = columnText;
		}

		public String getText(Object element) {
			Object o = getClassFieldContent(element, FieldName);
			return o == null ?"":o.toString();
		}

		private Object getClassFieldContent(Object obj, String fieldName) {
			Object o = null;
			for(Field f : obj.getClass().getDeclaredFields()) {
				if(f.getName().equals(fieldName)) {
					f.setAccessible(true);
					try {
						o = f.get(obj);
					} catch (IllegalArgumentException e) {
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					}
				}
			}
			return o;
		}
	}
}

abstract class ColumnViewerSorter extends ViewerComparator {
	public static final int ASC = 1;
	public static final int NONE = 0;
	public static final int DESC = -1;

	private int direction = 0;
	private TableViewerColumn column;
	private ColumnViewer viewer;

	private String property;

	public ColumnViewerSorter(ColumnViewer viewer, TableViewerColumn column, String property) {
		this.column = column;
		this.viewer = viewer;
		this.property = property;
		this.column.getColumn().addSelectionListener(new SelectionAdapter() {

			public void widgetSelected(SelectionEvent e) {
				if( ColumnViewerSorter.this.viewer.getComparator() != null ) {
					if( ColumnViewerSorter.this.viewer.getComparator() == ColumnViewerSorter.this ) {
						int tdirection = ColumnViewerSorter.this.direction;
						if( tdirection == ASC ) {
							setSorter(ColumnViewerSorter.this, DESC);
						} else if( tdirection == DESC ) {
							setSorter(ColumnViewerSorter.this, NONE);
						}
					} else {
						setSorter(ColumnViewerSorter.this, ASC);
					}
				} else {
					setSorter(ColumnViewerSorter.this, ASC);
				}
			}
		});
	}

	public void setSorter(ColumnViewerSorter sorter, int direction) {
		if( direction == NONE ) {
			column.getColumn().getParent().setSortColumn(null);
			column.getColumn().getParent().setSortDirection(SWT.NONE);
			viewer.setComparator(null);
		} else {
			column.getColumn().getParent().setSortColumn(column.getColumn());
			sorter.direction = direction;
			if( direction == ASC ) {
				column.getColumn().getParent().setSortDirection(SWT.DOWN);
			} else {
				column.getColumn().getParent().setSortDirection(SWT.UP);
			}
			if( viewer.getComparator() == sorter ) {
				viewer.refresh();
			} else {
				viewer.setComparator(sorter);
			}
		}
	}
	public int compare(Viewer viewer, Object e1, Object e2) {
		return direction * doCompare(e1, e2, property);
	}
	protected abstract int doCompare(Object e1, Object e2, String property);
}

 

 

表格数据类代码:

public class TableData {
	public static final String ADD_ELEMENT 		= "add Element";
	public static final String REMOVE_ELEMENT 	= "remove Element";

	private PropertyChangeSupport delegate;
	private Vector<Object> content;

	public TableData() {
		content = new Vector<Object>();
		delegate = new PropertyChangeSupport(this);
	}

	public void addPropertyChangeListener(PropertyChangeListener listener) {
		delegate.addPropertyChangeListener(listener);
	}

	public void firePropertyChange(PropertyChangeEvent event) {
		delegate.firePropertyChange(event);
	}

	public void removePropertyChangeListener(PropertyChangeListener listener) {
		delegate.removePropertyChangeListener(listener);
	}

	public void add(Object element) {
		if(content.contains(element))
			return;
		if(content.add(element))
			firePropertyChange(new PropertyChangeEvent(this, ADD_ELEMENT, null,	element));
	}

	public void remove(Object element) {
		if (content.remove(element))
			firePropertyChange(new PropertyChangeEvent(this, REMOVE_ELEMENT, null, element));
	}

	public Object[] elements() {
		return content.toArray();
	}

	public void printInfo() {
		for(Object o : content)
			System.out.println(o);
	}

}

 

 

测试代码:

public class MyTableTst {
	private static Shell shell;
	
	public MyTableTst(Shell shell) {
		MyTable table = new MyTable(shell,MyModel.class,Arrays.asList(new String[]{"serialVersionUID","xx_dialog2"}));
	
		/* 
		 * add and remove object
		 */
		Object o = new MyModel(2);
		table.add(o);
		table.add(new MyModel(4));
		table.add(new MyModel(55));
		for(int i=0; i<30; i++)
			table.add(new MyModel(4));
		o = new MyModel(3);
		table.add(o);
		table.remove(o);
		
		/*
		 * set column width and text
		 */
		table.setColumnWidth(300);
//		table.setColumnWidth(new int[]{100,100,150,160,100});
		table.setColumnName(new String[]{"text","id","boolean","b","e"});
		
		/*
		 * set context menu
		 */
		table.setContextMenu(CreateContextMenu(table.getTableViewer()));
		
		/*
		 * reset column label provider
		 */
		for(String property : table.getPropertis()) {
			table.setColumnLabelProvider(property,new ChangedColumnLabelProvider(property));
		}
		table.getTableViewer().refresh();
		
		/*
		 * set sort to the table
		 */
		for(String property : table.getPropertis()) {
			new ColumnViewerSorter(table.getTableViewer(),table.getTableViewerColumn(property),property) {
				protected int doCompare(Object e1, Object e2, String property) {
					if(e1 instanceof MyModel)
						return ((MyModel)e1).doCompare((MyModel)e2, property);
					return 0;
				}
			};
		}
		
		/*
		 * add filter
		 */
		table.getTableViewer().addFilter(new ViewerFilter() {
			public boolean select(Viewer viewer, Object parentElement, Object element) {
				/*
				 * viewer 			- TableViewer
				 * parentElement 	- TableData
				 * element 			- MyModel
				 */
				if(element instanceof MyModel)
					return ((MyModel)element).filter();
				return true;
			}
		});
		
		/*
		 * add EditingSupport
		 */
		TableViewerColumn column = table.getTableViewerColumn("xx_Text_String");
		column.setEditingSupport(new AbstractEditingSupport(table.getTableViewer()) {
			protected Object getValue(Object element) {
				return ((MyModel) element).xx_Text_String;
			}
			protected void doSetValue(Object element, Object value) {
				((MyModel) element).xx_Text_String = value.toString();
			}
		});
	}
	
	private MenuManager CreateContextMenu(TableViewer v) {
		MenuManager menu = new MenuManager();
		menu.add(CeActionFactory.getDelAction(v));
		return menu;
	}

	public static void main(String[] args) {
		Display display = new Display ();
		shell = new Shell(display);
		shell.setLayout(new FillLayout());
		new MyTableTst(shell);
		shell.open ();

		while (!shell.isDisposed ()) {
			if (!display.readAndDispatch ()) display.sleep ();
		}
		display.dispose ();
	}

	protected abstract class AbstractEditingSupport extends EditingSupport {
		private TextCellEditor editor;
		public AbstractEditingSupport(TableViewer viewer) {
			super(viewer);
			this.editor = new TextCellEditor(viewer.getTable());
		}
		protected boolean canEdit(Object element) {
			return true;
		}
		protected CellEditor getCellEditor(Object element) {
			return editor;
		}
		protected void setValue(Object element, Object value) {
			doSetValue(element, value);
			getViewer().update(element, null);
		}
		protected abstract void doSetValue(Object element, Object value);
	}
}

class MyModel {
	protected	int 			xx_Text_int			= 1;
	protected 	long 			longT 				= 1111111111L;
	protected	boolean 		xx_Boolean			= true;
	protected	boolean 		Ignorable_Boolean	= true;
	public 		String 			xx_Text_String		= "a string";
	protected 	List<String> 	list_dialog1 		= Arrays.asList(new String[]{"list1","list2"}); //端口或者引脚 Clock sources ports or pins
	protected 	String 			xx_dialog2 			= "dialog2"; 
	protected 	String 			xx_Combo_list1 		= ""; 

	public MyModel() {}
	public MyModel(int i) {
		xx_Text_int = i;
	}
	
	/*
	 * false - filter.
	 * true  - display.
	 */
	public boolean filter() {
		if(xx_Text_int == 5)
			return false;
		return true;
	}

	public int doCompare(MyModel model, String field) {
		if(field.equals("xx_Text_int"))
			return ((Integer)this.xx_Text_int).compareTo((Integer)model.xx_Text_int);
		if(field.equals("longT"))
			return ((Long)this.longT).compareTo((Long)model.longT);
		if(field.equals("xx_Boolean"))
			return ((Boolean)this.xx_Boolean).compareTo((Boolean)model.xx_Boolean);
		if(field.equals("Ignorable_Boolean"))
			return ((Boolean)this.Ignorable_Boolean).compareTo((Boolean)model.Ignorable_Boolean);
		if(field.equals("xx_Text_String"))
			return this.xx_Text_String.compareTo(model.xx_Text_String);
		if(field.equals("list_dialog1"))
			return ((Integer)this.list_dialog1.size()).compareTo((Integer)model.list_dialog1.size());
		if(field.equals("xx_dialog2"))
			return this.xx_dialog2.compareTo(model.xx_dialog2);
		if(field.equals("xx_Combo_list1"))
			return this.xx_Combo_list1.compareTo(model.xx_Combo_list1);
		return 0;
	}
}

class ChangedColumnLabelProvider extends ColumnLabelProvider {
	private String columnText;

	public ChangedColumnLabelProvider(String columnText) {
		super();
		this.columnText = columnText;
	}

	public Image getImage(Object element) {
		return Display.getCurrent().getSystemImage(SWT.ICON_WARNING);
	}

	public Font getFont(Object element) {
		return JFaceResources.getFont(JFaceResources.HEADER_FONT);
	}

	public Color getBackground(Object element) {
		return Display.getCurrent().getSystemColor(SWT.COLOR_GRAY);
	}

	public Color getForeground(Object element) {
		return Display.getCurrent().getSystemColor(SWT.COLOR_GREEN);
	}

	public String getText(Object element) {
		Object o = getClassFieldContent(element, columnText);
		return o == null ?"":o.toString();
	}

	private Object getClassFieldContent(Object obj, String fieldName) {
		Object o = null;
		for(Field f : obj.getClass().getDeclaredFields()) {
			if(f.getName().equals(fieldName)) {
				f.setAccessible(true);
				try {
					o = f.get(obj);
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
			}
		}
		return o;
	}

	public void dispose(ColumnViewer viewer, ViewerColumn column) {
		super.dispose(viewer, column);
	}
}

class CeActionFactory {
	public static Action getDelAction(final TableViewer v) {
		Action action = new Action("Del") {
			public void run() {
				v.getTable().remove(v.getTable().getSelectionIndices());
			}
		};
		action.setImageDescriptor(ImageDescriptor.createFromImage(
				Display.getCurrent().getSystemImage(SWT.ICON_ERROR)));
		return action;
	}
}

 

 

测试了功能:

a)可设置列的默认宽,可设置每一列的宽。可改变列的名字。
b)可设置Table上下文的菜单。
c)可以添加,删除,删除所有。
d)可以接受更改columnLabelProvide。
e)编辑,是不是用editorsupport更方便,看看。
f)Sort扩展。
g)Filter。

 

论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics