Базовые классы контроллеров расположены в модуле gui базового проекта cuba и не содержат ссылок на классы реализации визуальных компонентов (Swing или Vaadin), что дает возможность использовать их в клиентах обоих типов. Вместо этого базовые классы контроллеров реализуют дополнительный
интерфейс Window.Wrapper
и делегируют выполнение "обернутому" окну.
В то же время конкретные классы контроллеров могут быть расположены как в модуле gui, так и в web или desktop, в зависимости от применяемых в проекте клиентских блоков и специфики экрана. Если контроллер является универсальным, но для разных типов клиента требуется дополнительная функциональность, ее можно определить в так называемых классах-компаньонах.
Класс-компаньон располагается в модуле клиента соответствующего типа (web или desktop) и реализует интерфейс, задаваемый в использующем его контроллере. Класс компаньона задается в элементе companions
XML-дескриптора экрана. Контроллер может получить ссылку на экземпляр компаньона с помощью инжекции или вызовом getCompanion()
, и в нужный момент передать ему управление, например, для дополнительной инициализации визуальных компонентов специфичным
для данного типа клиента способом.
Например, необходимо раздельно для веб и десктоп клиентов проинициализировать таблицу некоторого экрана. Тогда в контроллере экрана, расположенном в модуле gui, определяем интерфейс компаньона и делегируем ему инициализацию таблицы:
public class CustomerBrowse extends AbstractLookup { public interface Companion { void initTable(Table table); } @Inject protected Table table; @Inject protected Companion companion; @Override public void init(Map<String, Object> params) { if (companion != null) { companion.initTable(table); } } }
В модулях web и desktop создаем соответствующие классы реализации компаньона:
public class WebCustomerBrowseCompanion implements CustomerBrowse.Companion { @Override public void initTable(Table table) { com.vaadin.ui.Table webTable = (com.vaadin.ui.Table) WebComponentsHelper.unwrap(table); // do something specific to Vaadin table } }
public class DesktopCustomerBrowseCompanion implements CustomerBrowse.Companion { @Override public void initTable(Table table) { javax.swing.JTable desktopTable = (javax.swing.JTable) DesktopComponentsHelper.unwrap(table); // do something specific to Swing table } }
И регистрируем классы реализации компаньона в XML-дескрипторе экрана:
<window ... class="com.company.sample.gui.customers.CustomerBrowse"> <companions> <web class="com.company.sample.web.customers.WebCustomerBrowseCompanion"/> <desktop class="com.company.sample.desktop.customers.DesktopCustomerBrowseCompanion"/> </companions> <dsContext>...</dsContext> <layout>...</layout> </window>
Так как классы-компаньоны расположены в web и desktop модулях, в них можно использовать метод unwrap()
классов WebComponentsHelper и DesktopComponentsHelper для извлечения из интерфейса Table ссылок на реализующие таблицу Vaadin и Swing компоненты, и работать с ними непосредственно.