前一篇提到了SWT中的table的通过使用virtual table性能得到很大的改善,那么如果既存的工程中使用的是TableViewer来创建的表,也能改成virtual table吗?
答案是肯定的,而且改起来超级简单,只需要在创建TableViewer的时候,加一个SWT.VIRTUAL属性即可~~
直接上示例代码:
package swt.table; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TableColumn; /** * A simple TableViewer to demonstrate the usage of a standard content provider * with a virtual table * */ public class VirtualTableViewer { private static int tableItems = 30000; // ContentProvider private class MyContentProvider implements IStructuredContentProvider { private MyModel[] elements; public Object[] getElements(Object inputElement) { return elements; } public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { this.elements = (MyModel[]) newInput; } } // LabelProvider private class MyLabelProvider implements ITableLabelProvider { public Image getColumnImage(Object element, int columnIndex) { return null; } public String getColumnText(Object element, int columnIndex) { if (element instanceof MyModel) { MyModel model = (MyModel) element; if (columnIndex == 0) { return String.valueOf(model.getCounter()); } else { return model.getName(); } } return null; } public void addListener(ILabelProviderListener listener) { } public void dispose() { } public boolean isLabelProperty(Object element, String property) { return false; } public void removeListener(ILabelProviderListener listener) { } } // model public class MyModel { public int counter; public String name; public MyModel(int counter) { this.counter = counter; this.name = "model" + counter; } public int getCounter() { return counter; } public String getName() { return name; } public String toString() { return "Item " + this.counter; } } public VirtualTableViewer(Shell shell) { // ※ SWT.VIRTUAL TableViewer tableViewer = new TableViewer(shell, SWT.H_SCROLL | SWT.V_SCROLL | SWT.VIRTUAL); // set table title TableColumn column = new TableColumn(tableViewer.getTable(), SWT.NULL); column.setText("Column1"); column.pack(); TableColumn column2 = new TableColumn(tableViewer.getTable(), SWT.NULL); column2.setText("Column2"); column2.pack(); tableViewer.setLabelProvider(new MyLabelProvider()); tableViewer.setContentProvider(new MyContentProvider()); tableViewer.setUseHashlookup(true); MyModel[] model = createModel(); tableViewer.setInput(model); tableViewer.getTable().setLinesVisible(true); tableViewer.getTable().setHeaderVisible(true); tableViewer.getTable().setBounds(10, 10, 280, 350); } private MyModel[] createModel() { MyModel[] elements = new MyModel[tableItems]; for (int i = 0; i < tableItems; i++) { elements[i] = new MyModel(i); } return elements; } /** * @param args */ public static void main(String[] args) { long start = System.currentTimeMillis(); Display display = new Display(); Shell shell = new Shell(display); shell.setText("Virtual TableViewer Demo"); new VirtualTableViewer(shell); shell.pack(); shell.open(); long end = System.currentTimeMillis(); System.out.println("All cost:" + (end - start)); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } }
注意到了?
TableViewer tableViewer = new TableViewer(shell, SWT.H_SCROLL | SWT.V_SCROLL | SWT.VIRTUAL);
仅仅是比平常创建TableViewer多一个SWT.VIRTUAL属性而已~~
不过虚表都有一个问题,在setInput之后,再调用setText来设置某个单元格的时候,单元格所在的行的其他单元格的数据就会被清空掉,
就是说把VirtualTableViewer方法代码改成下面这个样子(其他代码不动):
public VirtualTableViewer(Shell shell) { // SWT.VIRTUAL TableViewer tableViewer = new TableViewer(shell, SWT.H_SCROLL | SWT.V_SCROLL | SWT.VIRTUAL); // set table title TableColumn column = new TableColumn(tableViewer.getTable(), SWT.NULL); column.setText("Column1"); column.pack(); TableColumn column2 = new TableColumn(tableViewer.getTable(), SWT.NULL); column2.setText("Column2"); column2.pack(); tableViewer.setLabelProvider(new MyLabelProvider()); tableViewer.setContentProvider(new MyContentProvider()); tableViewer.setUseHashlookup(true); MyModel[] model = createModel(); tableViewer.setInput(model); tableViewer.getTable().setLinesVisible(true); tableViewer.getTable().setHeaderVisible(true); tableViewer.getTable().setBounds(10, 10, 280, 350); // 加了下面这一行改变单元格的值,整行其他单元格的值都没了。 // 去掉SWT.VIRTUAL属性,则不会出现这个问题 tableViewer.getTable().getItem(0).setText("test"); }