Библиотека сайта rus-linux.net
Фреймворк Jitsi
Глава 10 из книги "Архитектура приложений с открытым исходным кодом", том 1.
Оригинал: "Jitsi", глава 10 из 1 тома книги "The Architecture of Open Source Applications"
Автор: Emil Ivov
Перевод: Н.Ромоданов
10.6. Сервис пользовательского интерфейса
До сих пор мы рассматривали те части Jitsi, которые имели дело с протоколами, отправкой и получением сообщений и осуществлении вызовов. Однако, Jitsi это, прежде всего, приложение, используемое реальными людьми и, поэтому, одним из наиболее важных аспектов является его пользовательский интерфейс. Большую часть времени пользовательский интерфейс использует сервисы, в виде которых представлены все остальные сборки в Jitsi. Однако есть некоторые случаи, когда все происходит наоборот.
Первое, что приходит на ум, это - плагины. Плагинам в Jitsi часто нужно иметь возможность взаимодействовать с пользователем. Это означает, что они должны открывать, закрывать, перемещать или добавлять компоненты в существующие окна и панели в интерфейсе пользователя. Это то место, где в игру вступает наш сервис UIService. Он позволяет управлять основным окном в Jitsi, а также тем, как наши иконки будут позволять пользователям управлять приложением из dock-меню в Mac OS X или из области уведомлений в Windows.
Кроме простого использования списка контактов, плагины также могут выполнять дополнительные действия. Хорошим примером такого плагина является плагин, реализующий в Jitsi поддержку шифрования чата (OTR). Нашей сборке OTR необходимо зарегистрировать несколько графических компонентов в различных частях пользовательского интерфейса. Она добавляет кнопку замка в окно чата и подраздел в меню всех контактов, которое открывается правой кнопкой мыши.
Хорошо то, что он может делать все это с помощью вызова нескольких метода. В активаторе OSGi для сборки OTR, т. е. в OtrActivator, содержатся следующие строки:
Hashtable<String, String> filter = new Hashtable<String, String>(); // Регистрируем элемент меню, открывающегося правой кнопкой. filter(Container.CONTAINER_ID, Container.CONTAINER_CONTACT_RIGHT_BUTTON_MENU.getID()); bundleContext.registerService(PluginComponent.class.getName(), new OtrMetaContactMenu(Container.CONTAINER_CONTACT_RIGHT_BUTTON_MENU), filter); // Регистрируем элемент меню панели меню окна чата. filter.put(Container.CONTAINER_ID, Container.CONTAINER_CHAT_MENU_BAR.getID()); bundleContext.registerService(PluginComponent.class.getName(), new OtrMetaContactMenu(Container.CONTAINER_CHAT_MENU_BAR), filter);
Как вы можете видеть, добавление компонентов в наш графический интерфейс пользователя просто сводится к регистрации сервисов OSGi. С другой стороны, наша реализация UIService выполняет поиск собственной реализации интерфейса PluginComponent. Всякий раз, когда она обнаруживает, что была зарегистрирована новая реализация, она получает ссылку на нее и добавляет ее в контейнер, указанный в фильтре сервиса OSGi.
Вот как это происходит в случае щелчка правой кнопкой мыши по пункту меню. В сборке пользовательского интерфейса имеется класс MetaContactRightButtonMenu, обрабатывающий щелчок правой кнопки мыши и в котором есть следующие строки:
// Поиск компонентов плагина, зарегистрированных через контекст сборки OSGI. ServiceReference[] serRefs = null; String osgiFilter = "(" + Container.CONTAINER_ID + "="+Container.CONTAINER_CONTACT_RIGHT_BUTTON_MENU.getID()+")"; serRefs = GuiActivator.bundleContext.getServiceReferences( PluginComponent.class.getName(), osgiFilter); // Проходим по всем плагинам, которые найдем, и добавляем их в меню. for (int i = 0; i < serRefs.length; i ++) { PluginComponent component = (PluginComponent) GuiActivator .bundleContext.getService(serRefs[i]); component.setCurrentContact(metaContact); if (component.getComponent() == null) continue; this.add((Component)component.getComponent()); }
И это все, что нужно сделать. Большинство окон, которые вы видите в Jitsi, делают то же самое: Они ищут контекст сборки для сервисов, реализующих интерфейс PluginComponent, который имеет фильтр, указывающий, что их следует добавить в соответствующий контейнер. Плагины, как путешественники добирающиеся автостопом, держат таблички с названиями мест, куда они хотят добраться, превращая окна Jitsi в водителей, которые их подбирают.
Продолжение статьи: Усвоенные уроки и Благодарности.