Проблема с сортировкой по умолчанию для виртуальной таблицы и ViewerComparator - PullRequest
1 голос
/ 23 марта 2012

В моем приложении Eclipse RCP есть виртуальная таблица. Мы обращаемся к бэкэнду, чтобы получить данные для заполнения в виртуальной таблице.

Нам нужна сортировка по умолчанию для таблицы по одному столбцу. Мы используем ViewerComparator для достижения функциональности сортировки. Моя проблема в том, что я не могу заставить эту сортировку работать, когда таблица загружается с данными в первый раз. Но когда я нажимаю на столбец, все работает нормально, как и ожидалось.

Вот так я установил Comparator в столбец

    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) {

если (e1 == ноль || e2 == ноль) {

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

Когда таблица загружает данные в первый раз, она входит в условие полужирным шрифтом в вышеприведенном коде, поскольку один из объектов равен ВСЕГДА NULL

Примечание: Эта функция работает совершенно нормально, если я использую стандартную таблицу, а не VIRTUAL TABLE. Я не уверен, смогу ли я изменить его, чтобы использовать стандартную таблицу, так как мы также хотим использовать функцию отложенной загрузки.

ContentProvider используется: ObservableListContentProvider

Пожалуйста, сообщите ..

1 Ответ

1 голос
/ 17 июля 2014

Поздний ответ, который, надеюсь, все еще помогает другим. Я столкнулся с точно такой же проблемой при использовании 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, чтобы удалить этот слушатель из старого списка ввода и добавить его в новый.

...