ObservableListContentProvider

ObservableListContentProvider

我的Eclipse RCP应用程序中有一个虚拟表。我们调用后端以检索要在虚拟表中填充的数据。

我们希望在表格的默认列上进行单列排序。我们使用ViewerComparator来实现排序功能。我的问题是,当表第一次加载数据时,我无法进行这种排序。但是,当我单击该列时,一切正常。

这就是我将比较器设置为列的方式

    TableViewerColumn tvc = viewer.addColumn(100, SWT.LEFT, "Name");
    viewer.setColumnComparator(tvc,
            new Comparator<Person>() {
                @Override
                public int compare(Person o1,Person o2) {
                    double firstValue = Double.parseDouble(o1
                            .getAge());
                    double secondValue = Double.parseDouble(o2
                            .getAge());
                    return firstValue > secondValue ? 1 : -1;
                }
            });


自定义查看器中的setColumnComparator方法

public void setColumnComparator(TableViewerColumn tvc, Comparator<T> cmp){
    final MyViewerComparator c = new MyViewerComparator(cmp);
    final TableColumn tc = tvc.getColumn();

    setComparator(c);
    getTable().setSortDirection(c.getDirection());
    getTable().setSortColumn(tc);
    refresh();

    tc.addSelectionListener(new SelectionAdapter() {
        @Override
        public void widgetSelected(SelectionEvent e) {
                        <same code as above>
        }
    });


MyViewerComparator

class MyViewerComparator extends ViewerComparator{
    Comparator<T> cmp;
    boolean desc = true;
    MyViewerComparator(Comparator<T> cmp){
        this.cmp = cmp;
    }
    int getDirection(){
        return desc?SWT.UP:SWT.DOWN;
    }

    void flipDirection(){
        desc = !desc;
    }

    @Override
    public int compare(Viewer viewer, Object e1, Object e2) {



  if(e1 == null || e2 == null){


            return 0;
        }
        int rc = cmp.compare((T)e1, (T)e2);
        if(desc)
            return -rc;
        return rc;
    }
}


当表第一次加载数据时,它进入上述代码中的Bolded条件内部,因为其中一个对象始终为NULL

注意:如果我使用标准表而不是虚拟表,则此功能可以正常工作。我不确定是否可以将其更改为使用标准表,因为我们也需要延迟加载功能。

使用的ContentProvider是:ObservableListContentProvider

请指教..

最佳答案

希望可以对其他人有所帮助的最新答案。将SWT.VIRTUAL与ObservableListContentProvider结合使用时遇到完全相同的问题。

SWT.VIRTUAL的原始意图是,不需要提取内容中的所有元素以仅显示部分内容。需要实现一个自定义的内容提供者,该提供者仅需返回当前需要在屏幕上显示的元素。您还必须告诉表存在的元素总数。在这种用例中,无法使用ViewerComparator以常规方式对表进行排序,因为并非所有元素都已知。但是,SWT.VIRTUAL也可以用作性能优化,以呈现具有许多元素的表。这对于不可观察的ArrayContentProvider似乎可以正常工作。

但是,当使用ObservableListContentProvider时,出现的问题与您完全相同。它以某种方式设法变得聪明,仅更新实际已更改的元素。在实现的最深处,虚拟表出了点问题,我不知道到底是什么。但是我有一个解决方案:根本不使用ObservableListContentProvider,而只是刷新表查看器。您可以例如使用普通的ArrayContentProvider并将以下侦听器添加到查看器的IObservableList内容中:

new IListChangeListener() {
                @Override
                public void handleListChange(ListChangeEvent event) {
                    viewer.refresh();
                }
            };


实际上,我实际上实现了自己的“ SimpleObservableListContentProvider”,该操作确实做到了这一点,但还通过实现inputChanged方法从旧的输入列表中删除此侦听器并将其添加到新的输入列表中,来切换表的输入。

10-07 15:35