BERDAFLEX Software Systems
Главная > Eclipse > Книги > Eclipse RCP. Файловый менеджер

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

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

Требования:

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

Рисунок 4.34. Схема хранения информации о панелях (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);
  . . .
  }
}
Rambler's Top100 Рейтинг@Mail.ru