JFace TableViewer性能改善 -- 使用VirtualTable


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

 

 

 

 

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com