JFace Table Viewerのパフォーマンス向上:VirtualTableの使用

14472 ワード

前編SWTにおけるtableのvirtual tableを使用することで性能が大幅に改善されたことについて言及したが、既存のエンジニアリングでTableViewerを使用して作成されたテーブルを使用してもvirtual tableに変更できるのだろうか.
答えは肯定的で、変更は超簡単で、Table Viewerを作成するときに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より1つ多いSWTだけです.VIRTUAL属性だけです~~
 
しかし、虚表には問題があり、setInputの後、setTextを呼び出してセルを設定すると、セルが存在する行の他のセルのデータが空になります.
つまり、VirtualTable Viewerメソッドコードを次のように変更します(他のコードは動かない).
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");

    }