亲爱的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毫秒的时间。