Следующей задачей будет связывание модели списка файловых систем и панелей проводников. А так же возможности смены выбранной файловой системы для текущего проводника при помощи созданной ранее панели выбора файловых систем.
Требования:
Разработать способ хранения списка файловых систем;
При создании новой панели навигатора создавать привязанный к ней объект, который будет содержать информацию о выбранной файловой системе. Данный объект должен хранить текущий адрес проводника. Если еще ни открыто, ни одного навигатора, то устанавливать заданный по умолчанию адрес;
Один элемент из списка должен быть помечен как текущий (“источник”), остальные соответственно будут “приемниками” при выполнении файловых операций.
Для хранения списка данных объектов наиболее подходящей java коллекцией, будет интерфейс Map, который предназначен для хранения объектов вида “ключ - значение”, а точнее его конкретная реализация с контролем безопасности многопользовательского доступа ConcurentHashMap.
Для хранения дополнительной информации панелей создадим простейший 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); . . . } }