Связка навигатор — панель проводника

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

Требования:


. Разработать способ хранения списка файловых систем.
. При создании новой панели навигатора создавать привязанный к ней объект, который будет содержать информацию о выбранной файловой системе. Данный объект должен хранить текущий адрес проводника. Если еще не открыто ни одного навигатора, устанавливать адрес, заданный по
умолчанию.
. Один элемент из списка должен быть помечен как текущий ("источник"), остальные соответственно будут "приемниками" при выполнении файловых операций.

Для хранения списка данных объектов наиболее подходящей java-коллекцией будет интерфейс Map, который предназначен для хранения объектов вида "ключ-значение", а точнее, его конкретная реализация с контролем безопасности многопользовательского доступа ConcurentHashMap.


Рис. 1. Схема хранения информации о панелях (ExplorerView)

Для хранения дополнительной информации панелей создадим простейший java-бин (класс ExplorerConfig).

public class ExplorerConfig {
private String path = null;

public ExplorerConfig(String path) {
super();
this.path = path;
}

public String getPath() {
return path;
}

public void setPath(String path) {
this.path = path;
}
}

На данный момент будем хранить только текущий адрес панели. Для возможности добавления, изменения и удаления элементов из списка создадим соответствующие методы:

public class Activator extends AbstractUIPlugin {
private Map<String, ExplorerConfig> explorers = null;
. . .
public Activator() {
plugin = this;
// Создаем объект для хранения списка панелей
explorers = new ConcurrentHashMap<String, ExplorerConfig>();
}
. . .
// Сохранение объекта конфигурации в список
public void setExplorerConfig(String key, ExplorerConfig explorerConfig) {
if (explorers != null) {
explorers.put(key, explorerConfig);
}
}

// Удаление объекта конфигурации из списка
public void removeExplorerConfig(String key) {
if (explorers != null) {
explorers.remove(key);
} else {
currentExplorerId = null;
}
}
. . .
// Очищаем список объектов конфигурации при закрытии приложения
public void stop(BundleContext context) throws Exception {
plugin = null;
if (explorers != null) {
explorers.clear();
explorers = null;
}
super.stop(context);
}

Начиная с 3-й в версии eclipse при создании панелей (View) появилась возможность создания нескольких панелей одного и того же типа, что мы и используем при активизации панелей файлового менеджера.

Примечание

Для этого в файле манифеста для данного типа панелей нужно установить свойство allowMultiple="true".

Для идентификации таких панелей добавлен специальный вторичный идентификатор. Это строковый параметр, который можно назначать произвольно. Например, это может быть номер панели, адрес и т.д. Для простоты генерации будем использовать числа. При создании проекции менеджера файлов для указания самой первой, автоматически создаваемой, панели можно указать вторичный идентификатор путем добавления его к основному идентификатору через разделитель ":".

public class FileArrangerPerspective implements IPerspectiveFactory {
. . .
public void createInitialLayout(IPageLayout layout) {
. . .
folder.addView(ExplorerView.ID + ":0");
}
}

При создании панелей проводников с использованием ранее созданного действия NewExplorerViewAction будем добавлять вторичный идентификатор. Он будет генерироваться в основном модуле программы (метод getNextNavigatorId()). Программный код примет вид:

public class NewExplorerViewAction extends Action {
public void run() {
. . .
try {
String secondaryId = Activator.getDefault()
.getNextNavigatorId();
window.getActivePage().showView(viewId, secondaryId,
IWorkbenchPage.VIEW_ACTIVATE);
} catch (PartInitException e) {
. . .
}
. . .
}

Генерация вторичного кода панелей реализуется путем простого автоинкремента номера, причем счетчик будет сбрасываться в нулевое значение при закрытии панелей. Пример реализации генератора:

public class Activator extends AbstractUIPlugin {
. . .
private int explorerNum = 0;
. . .
public String getNextNavigatorId() {
if ((explorers == null)
|| ((explorers != null) && (explorers.isEmpty()))) {
// Сброс счетчика
explorerNum = 0;
}
explorerNum++;
return Integer.toString(explorerNum);
}
. . .

В ранее созданной панели выбора файловых систем создадим обработчики нажатия кнопок:

public class NavigatorView extends ViewPart {
private static final String VFS_PATH = "vfs_path";
. . .
private void createLocalDiscsComposite() {
. . .
for (int i = 0; i < fileRoots.length; i++) {
. . .
button.setData(VFS_PATH, fileRoots[i].toString());
addSelectionListener(button);
}
. . .
}
. . .
private void addSelectionListener(Button button) {
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (e.widget instanceof Button) {
String filePath = (String) ((Button) e.widget)
.getData(VFS_PATH);
if (Activator.getDefault().getCurrentExplorerId() != null) {
String secondaryId = Activator.getDefault()
.getCurrentExplorerId();
IViewPart view = null;
try {
view = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getActivePage()
.showView(ExplorerView.ID, secondaryId,
IWorkbenchPage.VIEW_ACTIVATE);
if (view instanceof ExplorerView) {
((ExplorerView) view).setInput(filePath);
}
. . .

SWT-виджеты (Widget) позволяют связывать с компонентами некоторые данные. Эти данные (объекты) можно сохранять и извлекать по ключевому значению. В нашем случае будем привязывать к кнопкам адрес пути файловой системы. Для идентификации данного атрибута введен статический идентификатор VFS_PATH. При нажатии на кнопку обработчик нажатия ищет текущую панель файлового навигатора и устанавливает ей адрес файловой системы, который привязан к данной кнопке. Следующей задачей является определение текущей выбранной панели (View), а точнее, последней панели проводника, к которой осуществлялся доступ. Возможное решение данной задачи заключается в создании слушателя, который регистрирует все обращения к панелям и сохраняет идентификатор текущей панели в главный модуль (Activator) нашего приложения. Если смотреть схему жизни Eclipse RCP приложения, то вполне можно воспользоваться методом ApplicationActionBarAdvisor .makeActions(IWorkbenchWindow window) для регистрации данного слушателя:

public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
. . .
private IWorkbenchWindow window;
. . .
private IPartListener explorersListener =
new IPartListener() {
public void partActivated(IWorkbenchPart part) {
if (part instanceof ExplorerView)
Activator.getDefault().setCurrentExplorerId(
((ExplorerView) part).getExplorerViewId());
}
. . .
};

protected void makeActions(IWorkbenchWindow window) {
this.window = window;
window.getPartService().addPartListener(explorersListener);
. . .
}

public void dispose() {
//Удаляем слушателя при завершении работы
window.getPartService().removePartListener(explorersListener);
. . .
}
}

Режим Fast View

В среде Eclipse есть режим сворачивания панелей (View) в специальную панельку FastViewBar, за счет чего можно освободить рабочее пространство и "разворачивать" "свернутые" панели по необходимости путем выбора соответствующей иконки в панели FastViewBar. Для того чтобы добавить данную панель в приложение, нужно просто сделать видимым FastViewBar:

public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
. . .
public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor( IWorkbenchWindowConfigurer configurer) {
configurer.setShowFastViewBars(true);
return new ApplicationWorkbenchWindowAdvisor(configurer);
}
. . .
}
Данная панель может размещаться в разных частях окна у края по периметру. Доступны следующие константы IWorkbenchPreferenceConstants: . LEFT — слева;
. RIGHT — справа;
. BOTTOM — внизу.

Примечание: В версии eclipse 3.2 данную панель можно установить и в верхней части окна вручную.
Программно указать положение панели FastViewBar можно следующим способом:

public class Application implements IPlatformRunnable {
. . .
public Object run(Object args) throws Exception {
. . .
PlatformUI.getPreferenceStore().putValue(
IWorkbenchPreferenceConstants.INITIAL_FAST_VIEW_BAR_LOCATION,
IWorkbenchPreferenceConstants.LEFT);
. . .
}

Чтобы создать панель в режиме FastView, надо при инициализации проекции (Perspective) добавить ее методом addFastView(..). Но с точки зрения юзабилити это может привести к проблемам с поиском данной панели у неподготовленных пользователей. Инициализировать данный режим целесообразно на основе настроек инсталлятора. Т.е. при инсталляции продукта подготовленные пользователи должны активизировать соответствующие флаги в диалоге параметров установки.

public class FileArrangerPerspective implements IPerspectiveFactory {
public void createInitialLayout(IPageLayout layout) {
. . .
layout.addFastView(NavigatorView.ID,0.25f);
}
}

При активной панели FastViewBar в контекстном меню панелей появляется переключатель режима отображения данной панели.


Рис. 2. Контекстное меню переключения режима Fast View

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


Рис. 3. Расположенная слева панель FastViewBar

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

Сайт проекта "Аранжировщик файлов": сайт
Руководство по интерфейсу пользователя приложений на основе eclipse: сайт
Практические рекомендации интерфейсу пользователя приложений на основе eclipse: сайт

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



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

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