Плагин Eclipse добавляет фильтр в TableViewer в IRunnableWithProgress

Я хочу добавить фильтр в файл TableViewer. Таблица может быть большой, поэтому это может занять некоторое время. Пока фильтр добавлен, я хочу показать индикатор выполнения, чтобы пользователь был проинформирован о выполнении задачи. Я не могу получить доступ к TableViewer непосредственно в классе IRunnableWithProgress, поэтому я использую Runnable с Display.getDefault().syncExec.

Проблема в том, что Progressbar не отображается, а весь пользовательский интерфейс не отвечает.

public class SearchFilter extends IViewerFilter {

    public SearchFilter(String filterName){
        super(filterName);
    }

    //Filtert die Tabelle nach eingabe des Suchfelds

    @Override
    public boolean select(Viewer viewer, Object parentElement, Object element) {

        //wird für jedes Element in der Tabelle(Paket) aufgerufen

        PacketDecoder packet = (PacketDecoder) element;
        String tmpData = packet.getDecodedData().toLowerCase();

        //falls Paket nicht decodierbar ist
        if(tmpData == null || tmpData.equals(""))
            return false;

        if(tmpData.contains(searchText.toLowerCase()))
            return true;

        return false;
    }
}

class EnterListener implements TraverseListener {

    @Override
    public void keyTraversed(TraverseEvent e) {

        if (e.detail == SWT.TRAVERSE_RETURN) {

if(searchText !=null && searchText.equals(text.getText()))
                return;

            searchText = text.getText();

            ProgressMonitorDialog progDialog = new ProgressMonitorDialog(parent.getShell());
            SearchProgress progress = new SearchProgress();
            try {
                progDialog.run(true, false, progress);
            } catch (InvocationTargetException ex) {
                // TODO Auto-generated catch block
                ex.printStackTrace();
            } catch (InterruptedException ex) {
                // TODO Auto-generated catch block
                ex.printStackTrace();
            }
        }
    }
}

class SearchProgress implements IRunnableWithProgress{

    @Override
    public void run(IProgressMonitor monitor)
            throws InvocationTargetException, InterruptedException {

        monitor.beginTask("entferne Filter...", IProgressMonitor.UNKNOWN);
        Display.getDefault().syncExec(new Runnable() {
            public void run() {

                searchFilter.setUsable(true);
                //Falls searchFilter zuvor nicht gefunden
                //searchFilter setzen
                if(!foundFilter) viewer.addFilter(searchFilter);
                else viewer.refresh();
            }
        });
        monitor.done();
    }
}

person lolung    schedule 02.07.2014    source источник


Ответы (1)


Display.syncExec запускает код в потоке пользовательского интерфейса, но диалогу выполнения требуется, чтобы код запускался в фоновом потоке, поэтому это не сработает.

Для большой таблицы вы должны использовать флаг SWT.VIRTUAL для таблицы и использовать поставщика контента, который реализует ILazyContentProvider.

Однако виртуальная таблица с ILazyContentProvider не поддерживает фильтры или сортировку, поэтому вам придется делать это самостоятельно в поставщике контента.

Существует существующий класс DeferredContentProvider, который пытается обеспечить фильтрацию и сортировку для виртуальной таблицы, но см. этот вопрос для ссылок на проблемы с этим сорт.

person greg-449    schedule 02.07.2014
comment
поэтому я рассмотрел это. Фильтрация с помощью DeferredContentProvider не такая гибкая, как с самим tableViewer. Я одновременно использую серверный фильтр, который можно легко добавить в таблицу с помощью addFilter, что делает ленивую загрузку еще более разумной с большими таблицами. это расстраивает. Я не вижу другого выхода, кроме как использовать ILazyContentProvider и управлять фильтрацией самостоятельно :( - person lolung; 02.07.2014