вторник, 27 ноября 2007 г.

Создание представлений на основе Common Navigator. Часть I: Определение представления

Автор оригинальной статьи : Michael D. Elder
Перевод: Евгений Флоров

Я начал принимать вопросы о Common Navigator в eclipse.platform newsgroup и сообщения из сообщества показывали, что недостаточно примеров. С целью помочь сообществу понять Common Navigator framework, я размещу некоторые примеры (в репозитории Eclipse по адресу dev.eclipse.org:/home/eclipse, куда вы можете зайти как "anonymous"; смотрите wiki для пояснений. Я буду документировать эти примеры в этом блоге. Возможно я вставлю созданную здесь документацию в Platform SDK, но я хочу организовать обсуждение, где потенциальные пользователи могли-бы высказать свое мнение максимально простым способом и непосредственно в первоисточник (то есть данный блог).

Детальная документация о точках расширения и API доступна в помощи платформы Eclipse (Help > Help Content) в разделе Platform Plug-in Developer's Guide > Reference > API Reference | Extension Points Reference.
К данной теме имеют отношения org.eclipse.ui.navigator.viewer и org.eclipse.ui.navigator.navigatorContent, а также пакет org.eclipse.ui.navigator. Если вам потребуются дополнительные детали по каким-либо моментам данного документа, пожалуйста воспользуйтесь этими ссылками.

Итак, с чего начнем? Во-первых мы должны сконфигурировать плюгин, который будет содержать представление (view), а именно добавить в его зависимости
org.eclipse.ui.navigator. Затем мы определим view part используя точку расширения org.eclipse.ui.views и укажем класс org.eclipse.ui.navigator.CommonNavigator как нашу реализацию view part, который обеспечит окружение (cradle) для нашего представления. Затем мы определим расширение org.eclipse.ui.navigator.viewer для конфигурирования представления как Common Navigator. В заключение, мы можем определить расширение org.eclipse.ui.navigator.navigatorContent вместе с связываниями (bindings) (org.eclipse.ui.navigator.viewer/viewerContentBinding) для того, чтобы ассоциировать расширения с нашим представлением.

Вы не должны использовать org.eclipse.ui.navigator.CommonNavigator как framework в своих целях; вместо этого вы можете вставлять свой контент используя org.eclipse.ui.navigator.INavigatorContentService виртуально куда угодно - от диалогов до редакторов или определить ваш viewer и view part класс, но в этом примере, мы будем придерживаться основ.

Основная настройка.

Common Navigator Framework появился в Eclipse 3.2. Следовательно, вы должны иметь окружение обновленное до Eclipse 3.2. Тема этого документа не будет касаться вопросов настройки Eclipse для self-hosting разработки. I assume that you have Eclipse 3.2 setup and are either self-hosting against a target of your own choice or the default.

Перед тем, как мы будем делать что-нибудь, мы должны убедиться, что наш plugin сконфигурирован со всеми необходимыми зависимостями. Либо создайте новый Plugin (File> New> Project: Plug-in Development> Plug-in Project: Введите имя и примите все по-умолчанию), или откойте Редактор манифеста plugin'а (выберите "plugin.xml"файл в вашем представлении (Project Explorer, Package Explorer, Navigator, и т.д.) и двойным щелчком или правой кнопкой и выберите Open With> Plug-in Manifest Editor. На закладке Dependencies, нажмите Add... и начинайте печатать org.eclipse.ui.navigator и выберете этот пункт, когда он подстветится или вы его увидите в списке.

Теперь выберите закладку Extensions редактора.

Определение view part

Для использования Common Navigator в вашем представлении, при его определении вы должны зарегистрировать реальный view part. Eclipse view parts определяются точкой расширения org.eclipse.ui.views. View part - контейнер для нашего представления; он имеет именованные закладки, место для меню представления (маленький треугольник в правом верхнем углу view part), и может содержать любой widget, который мы должны показать конечному пользователю. View parts не являются особенностью Common Navigators, мы просто используем их как окружение для хранения нашего представления.

Вы можете определить представлени через закладку Extensions путём выбора Add... и начиная печатать org.eclipse.ui.views до момента, когда вы его увидите в списке. Затем правый щелчёк на элементе, созданном под деревом "All Extensions" и имеющим имя org.eclipse.ui.views и выбрать New > view. Это приведет к созданию элемента в файле plugin.xml.

Когда вы выберете элемент view, то доступные для данного элемента атрибуты должны появиться как поля редактирования и widgets справа. Мы введём следующие значения (без кавычек):

id: "org.eclipse.ui.examples.navigator.view"
name: "Example View"
class: "org.eclipse.ui.navigator.CommonNavigator"
icon: "icons/filenav_nav.gif" (or your own)
allowMultiple: false

Теперь выберите закладку "plugin.xml" редактора. Вы должны увидеть что-нибудь похожее на это.



Вы можете создать категорию как на рисунке, но убедитесь, что указали категорию, с которой должен быть ассоциирован ваш viewer. Это делается определением атрибута "category". В противном случае, ваш viewer появится в категории Other в Show View dialog (Window > Show View > Other...).

Определение конфигурации viewer

Сразу мосле определения view part, нам необходимо определить конфигурацию расширений для нашего view part (org.eclipse.ui.navigator.viewer) которые скажут framework'у некоторые основные моменты, такие как то, что view part является Common Navigator, какая структура всплывающего меню должна быть, дополнительно к свойствам определяющим поведение viewer по-умолчанию.

Откройте опять закладку Extensions и нажмите Add...; когда появится диалог начинайте печатать org.eclipse.ui.navigator.viewer до тех пор, пока вы не увидите этот пункт в списке и выберите его. Клик правой кнопкой на новом элементе org.eclipse.ui.navigator.viewer в дереве "All Extensions" и выберите New > viewer. Этот элемент позволит нам ассоциировать абстрактный Common Navigator viewer с конкретным view part. Абстрактный viewer - это тот, с которым ассоциированы расширения, вне зависимости встроен он в view part или как-либо еще. Так для данного примера, мы будем использовать id, который использовали выше в нашем расширении org.eclipse.ui.views (org.eclipse.ui.examples.navigator.view"). Выберите элемент во view (который будет по-умолчанию обозначен name-of-you-plugin.viewer) и измените viewerId в поле редактирования, которое появится справа на "org.eclipse.ui.examples.navigator.view" без кавычек.

Некоторые комментарии о всплывающих меню.

Каркас Common Navigatorпредлгает два способа позволяющих viewer'ам адаптироватьэто меню.
  • Первый путь - это определение popupMenuId viewer'а для принятия разделителей и идентификаторов маркеров групп для меню. Значения по-умолчанию описаны в точке расширения org.eclipse.ui.navigator.viewer, но для удобства, повторены ниже.
  • С другой стороны, вы можете не определять popupMenuId и вместо этого указать элемент как дочерний для элемента. В этом случае, вы также можете определить ваши разделители и маркеры групп для ваших downstream клиентов.
Если вы предполагаете привязывать содержание или действия предоставляемые Платформой (Resource, Java(tm)), то рекомендуется использовать группировку по-умолчанию.

"group.new" separator="true"
"group.
goto"
"group.open" separator="true"
"group.openWith"
"group.edit" separator="true"
"group.show" separator="true"

"group.reorganize"

"group.port"
"group.generate" separator="true"
"group.search" separator="true"
"group.build" separator="true"
"additions" separator="true"
"group.properties" separator="true"

Некторые пояснения по поводу опций.
Элемент <> под элементом <> позволяет вам указывать строковые пары имя=значение. Существуют опции используемые базовым каркасом (описанные в разделе Примеры для org.eclipse.ui.navigator.viewer), но этот механизм может быть использован для ваших представлений или расширений для обеспечения дополнительного конфигурирования границ расширения представления. Обратитесь к org.eclipse.ui.navigator.INavigatorViewerDescriptor для ознакомления с API чтения свойст указанных в элементе. Вы можете получить описатель представления через org.eclipse.ui.navigator.INavigatorContentService представления Common Navigator viewer.

После того, как вы установили viewerId, вы можете выбрать закладку "plugin.xml" для просмотра определений следующих элементов.


После определения представления, нам необходимо добавить расширения содержания и привязать их к представлению. Я буду описывать этот процесс более детально в следующей части. Для примера мы просто привяжем содержание ресурсов по-умолчанию (определенные модулем org.eclipse.ui.navigator.resources) к нашему представлению.


Вернитесь обратно на закладку Extensions, нажмите правой кнопкой на расширении org.eclipse.ui.navigator.viewer и выберите New > viewerContentBinding. Выберите элемент viewerContentBinding и установите viewerId в то значение идентификатора, которое мы использовали для нашего представления ("org.eclipse.ui.navigator.examples.view").
Нажмите правой кнопкой на новом элементе viewerContentBinding и выберите New > includes. В завершение, нажмите правой кнопкой на новом элементе includes и выберите New > contentExtension. Для атрибута pattern в contentExtension мы укажем "org.eclipse.ui.navigator.resourceContent" без кавычек. Этот идентификатор используется модулем org.eclipse.ui.navigator.resources для идентификации расширения Resource.

На закладке "plugin.xml", мы должны иметь что-то похожее на вот это:

Теперь вы можете запустить верстак (workbench) - (Run... > New Eclipse Application) и посмотреть представление в работе. Мы пока не определили каких-либо действий для него, поэтому вам потребуется использовать либо Resource Navigator, либо Package Explorer для создания проекта, который вы хотите увидеть в представлении. Мы будем добавлять действия Resource и фильтры далее, но на данный момент, обратите внимание на поведение по-умолчанию ассоциированное с представлением: кнопки Collapse All, Link with Editor, Filters (вместе с закладкой Filters ("Available Filters") и Extensions ("Available Content")).

Для привязки фильтров ресурсов, нам необходимо добавить другой элемент contentExtension к нашему includes. Укажите "org.eclipse.ui.navigator.resources.filters.*" как идентификатор. Это подцепит все фильтры определенные org.eclipse.ui.navigator.resources. С другой стороны, вы можете выбрать отдельные фильтры, которые хотите видеть в plugin.xml этого модуля и указать идентификаторы.

Выберите Run... опять и проверьте, что вам теперь доступны несколько фильтров ресурсов в вашей закладке "Available Filters" диалога Filters.

Далее мы будем привязывать действия с ресурсами по-умолчанию. Для привязывания действий нам необходимо добавить viewerActionBinding в корень точки расширения. Нажмите правой кнопкой на org.eclipse.ui.navigator.viewer и выберите New > viewerActionBinding. Убедитесь в правильности viewerId и затем добавьте эелемент includes, который имеет элемент actionExtension. Для атрибута pattern укажите "org.eclipse.ui.navigator.resources.*". Теперь когда вы запустите верстак, вы по-умолчанию увидите New, Import, Export, и Refresh в пустом представлении, а также другие действия соотвествующие Resource Navigator при выделении элементов в представлении.

Ваш plugin.xml в этот момент должен выглядеть так:

"Откуда он знает все правельные идентификаторы? Это просто "магические числа для меня!" Для определения идертификаторов расширений содержания которые вы хотите привязать к вашему представлению, вы можете просмотреть файлы plugin.xml модулей определяющих расширения. Вы можете использовать представления Plug-ins для того, чтобы сделать это проще всего (Window > Show View > Other...: PDE > Plug-ins) или вы можете открыть plugin.xml файл для org.eclipse.ui.navigator.navigatorContent (используя опять представление Plug-ins) и закладку Extension Points, выберите navigatorContent. Затем нажмите Find References для обнаружения всех расширений в вашем workspace определяющих расширения содержания или действий, которые мы можете захотеть использовать в вашем представлении. Расширения содержания определяются элементом navigatorContent, так что используйте атрибут id расширений navigatorContent при привязывании когда вы определяете элементы contentExtension под viewerContentBindings для вышего представления. Расширения действий определяются элементом actionProvider, так, что используйте атрибут id расширений actionProvider при привязывании, когда определяете элементы actionExtension под viewerActionBindings для вашего представления. Имейте ввиду, что actionProvider который вложен в расширение navigatorContent привязывается автоматически, когда охватывающее его расширение содержания привязано к представлению.

Определение фильтров
Последнее, что мы сделаем сегодня - это определение фильтра для нашего представления используя Eclipse Core Expressions. Документация на каркас Core Expressions доступна с модулем org.eclipse.core.expressions. Мы используем проверки свойств (property testers) определенные org.eclipse.core.resources для проверки типа (вида) проекта, и скроем все проекты, которые не имеют этот тип проекта.

Итак, вернитесь на закладку Extensions редактора манифеста модуля, затем нажмите Add... и выберите org.eclipse.ui.navigator.navigatorContent. Затем добавьте новый элемент commonFilter в это расширение (также как до этого: правый щелчек на элементе org.eclipse.ui.navigator.navigatorContent, выбрать New > commonFilter). Измените предлагаемый id на "org.eclipse.ui.examples.navigator.filters.hideNonJavaProjects", и измените имя на "Hide non-Java projects". Вместо указания класса-реализации, мы только определим выражение в виде XML. Нажмите правой кнопкой на элементе commonFilter и выберите New > filterExpression. Здесь мы можем продолжить использование меню по правой кнопке для создания выражения, подобного следующему:

Вы также можете установить атрибут activeByDefault в выражении для определения будет ли фильтр активен в конфигурации по-умолчанию.

В завершение, нам необходимо определить contentExtension как чать нашего viewerContentBinding для данного представления. Убедитесь в использовании id нашего нового фильтра или общего шаблона (например "org.eclipse.ui.examples.navigator.filters.*") для привязывания этого фильтра и всех будущих фильтров, которые мы (или наши подчиненные сушности) определим как соотвествующие этому id. Ваш итоговый plugin.xml должен выглядеть похожим на следующее:


Теперь запустите верстак последний раз. Создайте несколько Simple проектов и несколько Java проектов. Когда фильтр "Hide non-Java Projects" включен, Simple проекты должны пропадать из представления.

4 комментария:

Владимир Коренной комментирует...

Выделенные строки\слова не переведены:
"We will get into the code for the content and label providers shortly" = "Мы разберемся с кодом для провайдеров содержимого и ярлыков позднее".

"Now that we have setup our extension, let's take a look at the code that will actually do the heavy lifting" = "Теперь, когда мы настроили наше расширение, посмотрим на код, который фактически выполнит жесткую привязку".

"Since we're only concerned with these elements" = "Так как мы только начали изучение этих элементов"

"bound" = "привязывать\привязка"

"is bound" = "привязан(о)"

"project nature" = я думаю перевести как "тип проекта", потому что "природа проекта" ка-то странно звучит :)

"downstream contributions" = я думаю что имееются в виду дочерние так сказать "сущности".

Евгений Флоров комментирует...

Исправлено, спасибо.

Анонимный комментирует...

Это что автоматический переводчик? Не гуглом ли переводили?

Евгений Флоров комментирует...

Нет. Но я рад, что тема ещё актуальна :)