前一篇提到了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"); }