Добавление в интерфейс мультиплексора

Многие составные компоненты применяют понятие активного дочернего объекта. С текущим активным дочерним объектом может потребоваться связать зависимость.

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

Далее такая процедура называется добавлением мультиплексора в интерфейс INameable.

В общем случае применим следующий шаблон мультиплексора: Поскольку это достаточно общий шаблон, для его поддержки предоставлен класс Multiplexer. Клиенты, предоставляющие новые типы интерфейсов с помощью точки расширения org.eclipse.core.component.types, могут также указать версию интерфейса с поддержкой мультиплексора. Такая версия работает следующим образом: Клиентам, в которых применяется мультиплексор, не требуется информация об объединении отдельных интерфейсов. К мультиплексору прикрепляется INameable, как в случае компонента, мультиплексор в свою очередь прикрепляется к каждому дочернему объекту, как в случае INameable. Следующий пример иллюстрирует данный подход. Строки, в которых применяется мультиплексор, выделены красным. Очистку мультиплексоров следует выполнять явным образом.

public class MultiplexNameView implements IDisposable {
    private Multiplexer mplex;
   
    private ISite view1;
    private ISite view2;
   
    private Listener focusListener = new Listener() {
        /* (не документация по Java)
         * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
         */
        public void handleEvent(Event e) {
            if (e.widget == view1.getControl()) {
                mplex.setActivePart(view1);
            } else if (e.widget == view2.getControl()) {
                mplex.setActivePart(view2);
            }        
        }
       
    };
   
    /**
     * Конструктор компонента. Не следует вызывать непосредственно.
     */
    public MultiplexNameView(Composite parent, IPartFactory factory, INameable name) throws CoreException {
       
        // Создание мультиплексора. Перенаправление INameable мультиплексору
        mplex = new Multiplexer(new ContainerContext().addInstance(INameable.class, name));
       
        // Создание навигатора ресурсов. Предоставление навигатору INameable с мультиплексором; для остальных интерфейсов
        // применяются значения по умолчанию.
        ContainerContext viewContext1 = new ContainerContext()
            .delegateTo(INameable.class, mplex);
        view1 = factory.createView(
                IPageLayout.ID_RES_NAV, parent, viewContext1, null);
        view1.getControl().addListener(SWT.Activate, focusListener);
       
        // Создание панели свойств. Предоставление панели свойств INameable с мультиплексором; для остальных компонентов
        // применяются значения по умолчанию.
        ContainerContext viewContext2 = new ContainerContext()
            .delegateTo(INameable.class, mplex);
        view2 = factory.createView(IPageLayout.ID_PROP_SHEET, parent, viewContext2, null);
        view2.getControl().addListener(SWT.Activate, focusListener);
       
        // Навигатор изначально активен
        mplex.setActivePart(view1);
       
        parent.setLayout(new FillLayout());       
    }
   
    /* (не документация по Java)
     * @see org.eclipse.core.component.IDisposable#dispose()
     */
    public void dispose() {
        mplex.dispose();
    }
}