Сортировка и фильтрация данных

Как было запланировано в предварительном документе дизайна, в дереве объектов файловой системы по умолчанию должны показываться только каталоги. Данную задачу можно решить как на уровне запроса к объектам, так и с помощью фильтрации элементов. Рассмотрим возможность автоматической фильтрации, что позволит в дальнейшем гибко управлять форматом вывода объектов.

Визуализация типов объектов

Для удобства визуального тестирования данной функциональности добавим простую реализацию методов получения изображений в провайдерах. На данном этапе ограничимся только изображениями каталогов и файлов (в дальнейшем будет добавлен анализ типов файлов и вывод соответствующих им иконок). В соответствии с принятой конвенцией платформы 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;
}

Запускаем наше приложение и любуемся изображением папок и файлов. Сразу же бросается в глаза необычная последовательность очередности отображения объектов. Для того чтобы привести все к привычному виду, нужно не просто отсортировать объекты по некоторому полю, но еще и сгруппировать каталоги в начало списка.

Рис. 1. Вывод изображений папок и файлов

Сортировка выводимых данных

В предыдущих версиях 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;
}
}

Рис. 2. Вывод отфильтрованных и отсортированных папок и файлов

Рекомендуемые ресурсы

. Сайт проекта "Аранжировщик файлов": сайт
. FAQ "How do I use images defined by other plug-ins?": сайт
. FAQ "How do I create an image registry for my plug-in?": сайт
. Библиотека ICU4J: сайт
. Описание бага по адаптации библиотеки ICU4J: сайт

Сергей Бердачук, сайт



Компьютерная газета. Статья была опубликована в номере 41 за 2006 год в рубрике программирование

©1997-2024 Компьютерная газета