亲爱的Stackoverflowians,您好!

几个月前,我正在处理ILazyTreeContentProvider,最后按照Eclipse RCP - ILazyTreeContentProvider implementation is unexpectedly eager对其进行了修复

但是我使用ILazyContentProvider面临着完全相同的问题,尽管遵循了与树类似的步骤,但我还是茫然。
在此表中,我每秒要在表中添加大约1000个元素,并每100毫秒通过setItemCount()在查看器上触发刷新。

窗口的大小小于100行,因此,每次我在查看器上调用setItemCount()时,updateElement()方法都不应从第一个索引开始。

不幸的是,确实如此。每次从0更新到最后一个索引。

这是代码:

package manyelementscontentprovider;

import java.util.List;
import java.util.Vector;
import org.eclipse.jface.viewers.ILazyContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class LargeDataSetTable {
    private class MyContentProvider implements ILazyContentProvider {
        private TableViewer viewer;
        public List<MyEntity> elements;
        private int lastIndex=0;
        public MyContentProvider(TableViewer viewer) {
            this.viewer = viewer;
        }

        public void dispose() {

        }

        @SuppressWarnings("unchecked")
        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            this.elements = (List<MyEntity>) newInput;
        }
        @Override
        public void updateElement(int index) {
            System.out.println(index);
            if (!viewer.isBusy())
                viewer.replace(elements.get(index), index);
        }

    }

    public static class MyEntity {
        public int counter;
        public MyEntity(int counter) {
            this.counter = counter;
        }

        public String toString() {
            return "Item " + this.counter;
        }
    }

    List<MyEntity> model;

    private int counter;
    private Display display;
    private TableViewer v;
    public LargeDataSetTable(Shell shell, Display display) {
        model = createModel();
        this.display=display;
        v= new TableViewer(shell, SWT.VIRTUAL);
        v.setLabelProvider(new LabelProvider());
        v.setContentProvider(new MyContentProvider(v));
        v.setInput(null);
        v.setUseHashlookup(true);
        counter = 0;

        v.setInput(model);
        v.setItemCount(model.size());

        v.getTable().setLinesVisible(true);
    }
    private void startSomeShit() {
        final Runnable gooeiUpdate = new Runnable() {

            @Override
            public void run() {
                long timeA = System.currentTimeMillis();
                v.setItemCount(counter);
                v.setSelection( new StructuredSelection( model.get(counter-1) ), true );
                v.setSelection(null);
                long timeB = System.currentTimeMillis();
                System.out.println("Paint lasted:"+(timeB-timeA));
            }

        };

        Runnable addThingsToModel = new Runnable() {

            public void run() {
                long currentTime=System.currentTimeMillis();
                long howManyGotIn =0;
                while (counter<4000000) {
                    for (int i = 0; i< 10; i++){
                        final MyEntity m = new MyEntity(counter);
                        model.add(m);
                        counter++;
                    }

                    if (System.currentTimeMillis()-currentTime>100) {
                        howManyGotIn=counter - howManyGotIn;
                        display.syncExec(gooeiUpdate);
                        currentTime=System.currentTimeMillis();
                        System.out.println("How many got in = "+howManyGotIn);
                        howManyGotIn=counter;
                    }

                    try {
                        Thread.sleep(0,25);
                    } catch(InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread th = new Thread(addThingsToModel);
        th.start();
    }
    private List<MyEntity> createModel() {
        List<MyEntity> list = new Vector<MyEntity>(4000000);
        return list;
    }
    public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
        LargeDataSetTable viewerCica = new LargeDataSetTable(shell,display);
        shell.open();
        viewerCica.startSomeShit();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }
}

任何建议,意见和选择都非常感谢。你们好棒!

最佳答案

的Javadoc

TableViewer.setSelection(ISelection selection, boolean reveal)
陈述以下内容:

设置此查看器的新选择并使其可见。对于ILazyContentProvider,此方法的TableViewer实现效率低下,因为查找是通过索引而不是元素完成的,并且在更坏的情况下可能需要填充整个表。
如果希望在使用ILazyContentProvider时更有效地设置选择,请使用Table#setSelection(int []索引)和Table#showSelection()。

因此,您可以编写如下内容:
v.getTable().setSelection(counter - 1);
v.getTable().showSelection();
使用这种方法,绘制操作平均需要10毫秒的时间。

10-06 10:17