8. Сортировка и фильтрация данных | ||
---|---|---|
Пред. | Глава 4. Основа проекта | След. |
Как было запланировано в предварительном документе дизайна, в дереве объектов файловой системы по умолчанию должны показываться только каталоги. Данную задачу можно решить как на уровне запроса к объектам, так и фильтрацией элементов. Рассмотрим возможность автоматической фильтрации, что позволит в дальнейшем гибко управлять форматом вывода объектов.
Для удобства визуального тестирования данной функциональности добавим простую реализацию методов получения изображений в провайдерах. На данном этапе ограничимся только изображениями каталогов и файлов (в дальнейшем будет добавлен анализ типов файлов и вывод соответствующих им иконок).
В соответствии с принятой конвенцией платформы eclipse, для доступа к изображениям из внешних модулей, идентификаторы таких изображений должны быть доступны через специально созданный интерфейс ISharedImages. Некоторые модули платформы eclipse содержат реализующие данный интерфейс модули, например org.eclipse.ui.workbench, org.eclipse.jdt.ui и org.eclipse.team.ui. Воспользуемся изображениями из org.eclipse.ui.ISharedImages. Провайдер меток для дерева файловых объектов примет вид:
public class VfsTreeLabelProvider extends LabelProvider { . . . public Image getColumnImage(Object element, int columnIndex) { if ((element != null)&&(element instanceof FileObject)){ try { // Выделяем изображения для каталогов и файлов if (((FileObject) element).getType().equals(FileType.FOLDER)) { return PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FOLDER); }else{ return PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FILE); } } catch (FileSystemException e) { } } return null; }
Провайдер меток для таблиц реализуется аналогично:
public class VfsTableLabelProvider implements ITableLabelProvider { . . . public Image getColumnImage(Object element, int columnIndex) { if ((columnIndex == 0)&&(element != null) &&(element instanceof FileObject)){ try { // Выделяем изображения для каталогов и файлов if (((FileObject) element).getType().equals(FileType.FOLDER)) { return PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FOLDER); }else{ return PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_OBJ_FILE); } } catch (FileSystemException e) { } } return null; }
Запускаем наше приложение и любуемся изображением папок и файлов. Сразу же бросается в глаза необычная последовательность очередности отображения объектов. Для того чтобы привести все к привычному виду, нужно не просто отсортировать объекты по некоторому полю, но еще и сгруппировать каталоги в начало списка.
В предыдущих версиях eclipse для сортировки отображаемых въюверами данных, надо было создать объект сортировщика, который должен быть наследником класса ViewerSorter и назначить его вьюверу, например:
public class VfsFileSorter extends ViewerSorter { public int category(Object element) { if (element instanceof FileObject) { try { // Сортировка каталогов в начало списка if (((FileObject) element).getType() == FileType.FOLDER) { return 0; } else { return 1; } } catch (FileSystemException e) { . . . } } return 0; } } public class ExplorerView extends ViewPart { . . . private void initialize() { . . . vfsExplorerComposite.getTableViewer().setSorter(new VfsFileSorter()); } . . . }
Начиная с версии eclipse 3.2 произведены изменения в API. Теперь ViewerSorter является наследником класса ViewerComparator. И в классы вьюверов добавлены методы:
public ViewerComparator getComparator()
public void setComparator(ViewerComparator comparator)
Данные изменения внесены для возможности использования пакета библиотек ICU4J, которые содержат множество функций для работы с данными в юникоде.
Метод инициализации будет теперь иметь вид:
public class ExplorerView extends ViewPart {
. . .
private void initialize() {
. . .
vfsExplorerComposite.getTableViewer().setComparator(new VfsFileSorter());
}
. . .
}
Процесс сортировки является двухфазным, вначале ресурсы сравниваются по категориям, а потом уже происходит сортировка по контенту. Это позволяет нам добавить возможность разделить сортировку каталогов и файлов. В вышеприведенном примере мы делим их на две категории и папки автоматически сортируются первыми, так как номер категории у них меньше. Сортировкой по разным атрибутам займемся позже.
Настал черед фильтрации дерева папок. Для фильтрации данных провайдером контента требуется создать наследний jface ViewerFilter. Реализация фильтра не составляет проблем:
public class VfsOnlyFoldersViewerFilter extends ViewerFilter { public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof FileObject) { try { return ((FileObject) element).getType().equals(FileType.FOLDER); } catch (FileSystemException e) { . . . } } return false; } }
FAQ “How do I use images defined by other plug-ins?” http://wiki.eclipse.org/index.php/FAQ_How_do_I_use_images_defined_by_other_plug-ins%3F
FAQ “How do I create an image registry for my plug-in?” http://wiki.eclipse.org/index.php/FAQ_How_do_I_create_an_image_registry_for_my_plug-in%3F
Библиотека ICU4J http://wiki.eclipse.org/index.php/ICU4J
Описание бага по адаптации библиотеки ICU4J https://www.eclipse.org/bugs/show_bug.cgi?id=135284