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");

    }

 

 

 

 

 

你可能感兴趣的:(tableview)