Статьи

Еще дальше с Spring RCP (2)

В предыдущих частях этой серии статей о Spring RCP ( Начало работы с Spring RCP , Дальнейшее развитие с Spring RCP и Дальнейшее развитие с Spring RCP (1) ) мы рассмотрели различные темы, от начальных этапов начала работы до предварительные темы, такие как представления, действия, стыковка и диалоги. Здесь мы рассмотрим более сложную тему: как интегрировать существующие платформы стыковки в приложение Spring RCP.

По умолчанию, как указано здесь , поддерживаются две док-системы: VLDocking и FlexDock с помощью пакета spring-richclient-docking:

В первых двух частях этой статьи мы рассмотрим, как их интегрировать, используя хуки, которые Spring RCP делает доступными через перечисленные выше классы. После этого мы знакомимся с проектом https://jide-springrcp.dev.java.net/ Джонни Рэя, а затем экстраполируем некоторые ключевые уроки из этой интеграции, а также из недавней превосходной статьи Питера Карича о Javalobby, в которой содержится код, иллюстрирующий интеграцию MyDoggy. , Затем экстраполяция берет компонент TabbedContainer Тима Будро (который является частью платформы NetBeans, но может, как вы увидите, использоваться за ее пределами) и интегрирует его в качестве среды стыковки для приложения Spring RCP, в качестве очень упрощенной иллюстрации того, как это может быть сделано для любой другой структуры.

Содержание

  • VLDocking

    Я не претендую на звание эксперта Spring RCP, поэтому все, что описано в разделах выше, следует брать с собой с солью. Однако в каждом случае предоставленное решение работает. В каждом случае, тем не менее, вероятно, существуют лучшие способы достижения тех же (или лучших) результатов. Я надеюсь, что те, кто знает эти решения, будут вмешиваться и исправлять ошибки моих путей.

    Примечание. Завершенный пример кода для каждого из вышеуказанных сценариев доступен в виде проекта NetBeans как части плагина Spring RCP Tooling на портале плагинов NetBeans , начиная с версии 1.5 этого плагина и далее. Откройте мастер создания проекта (Ctrl-Shift-N), и вы найдете «Учебное пособие по Spring RCP, часть 4», «Учебное пособие по Spring RCP, часть 5», «Учебное пособие по Spring RCP, часть 6», «Учебное пособие по Spring RCP, часть 7» и « Spring RCP Tutorial Part 8 «, которые являются примерами для VLDocking, FlexDock, JIDE, MyDoggy и TabbedContainer, соответственно.

     

    Интеграция с VLDocking

    Платформа VLDocking во всех возможных смыслах является предпочтительной платформой стыковки для Spring RCP. Это, во-первых, потому, что JAR-файл VLDocking является частью дистрибутива Spring RCP, а во-вторых, потому что необходимые классы для интеграции VLDocking с Spring RCP также являются стандартной частью дистрибутива Spring RCP. Последний пункт в равной степени относится и к FlexDock (который обсуждается в следующем разделе), но, как видно из скриншота в предыдущем разделе, количество классов интеграции, предоставляемых с дистрибутивом Spring RCP, меньше, чем для VLDocking. Вдобавок ко всему, FlexDock, похоже, не подвергается активной разработке, в то время как VLDocking 2.1.8 был выпущен чуть более недели назад.

    Поэтому имеет смысл сначала разобраться с VLDocking. Давайте использовать его для создания макета окна, который выглядит следующим образом:

    В то же время, давайте удостоверимся, что любые изменения макета, сделанные пользователем (например, если пользователь перемещает некоторые виды в разные позиции), будут восстановлены после перезапуска приложения. Как это сделать? Получите макет из файла XML, который является сценарием, поддерживаемым VLDocking.

    Во-первых, в richclient-application-context.xml:

    <bean id="lifecycleAdvisor" class="simple.SimpleLifecycleAdvisor">
    <property name="windowCommandBarDefinitions" value="ui/commands-context.xml" />
    <property name="windowCommandManagerBeanName" value="windowCommandManager" />
    <property name="menubarBeanName" value="menuBar" />
    <property name="toolbarBeanName" value="toolBar" />
    <property name="startingPageId" value="proxyPage" />
    </bean>

    <bean id="proxyPage"
    class="org.springframework.richclient.application.docking.vldocking.VLDockingPageDescriptor">
    <property name="initialLayout">
    <bean class="org.springframework.core.io.ClassPathResource">
    <constructor-arg type="java.lang.String">
    <value>/layouts/vldocking.xml</value>
    </constructor-arg>
    </bean>
    </property>
    </bean>

    <bean id="applicationPageFactory" depends-on="serviceLocator"
    class="org.springframework.richclient.application.docking.vldocking.VLDockingApplicationPageFactory">
    </bean>

     

    Обратите внимание на строку 14 выше, которая предполагает такую ​​структуру проекта:

     

    Затем определите макет в файле «vldocking.xml» следующим образом:

    <?xml version="1.0"?>
    <VLDocking version="2.1">
    <DockingDesktop name="proxyPage">
    <DockingPanel>
    <Split orientation="1" location="0.2506361323155216">
    <Dockable>
    <Key dockName="NewSpringView2"/>
    </Dockable>
    <Split orientation="0" location="0.7484536082474227">
    <TabbedDockable>
    <Dockable>
    <Key dockName="NewSpringView"/>
    </Dockable>
    <Dockable>
    <Key dockName="NewSpringView1"/>
    </Dockable>
    </TabbedDockable>
    <Dockable>
    <Key dockName="NewSpringView3"/>
    </Dockable>
    </Split>
    </Split>
    </DockingPanel>
    <TabGroups>
    <TabGroup>
    <Dockable>
    <Key dockName="NewSpringView"/>
    </Dockable>
    <Dockable>
    <Key dockName="NewSpringView1"/>
    </Dockable>
    </TabGroup>
    </TabGroups>
    </DockingDesktop>
    </VLDocking>

     

    Вам нужно быть экспертом по VLDocking, чтобы создать файл макета выше? Вам нужны специальные инструменты для его создания? Вам нужны какие-то особые знания о приведенном выше синтаксисе XML? Нет. Просто запустите приложение один раз с указанным выше файлом макета, а затем переместите представления в те позиции, в которых вы хотели бы их видеть, например, примерно так:

    Теперь переключитесь в окно Files и посмотрите на файл макета, который находится в папке «build», как показано здесь:

    Откройте этот файл и обратите внимание, что он отличается от файла в вашей собственной структуре источника. Это выглядит так (при условии, что вы переместили представления, как показано выше):

    <?xml version="1.0"?>
    <VLDocking version="2.1">
    <DockingDesktop name="proxyPage">
    <DockingPanel>
    <Split orientation="1" location="0.5012722646310432">
    <Split orientation="0" location="0.5030927835051546">
    <Dockable>
    <Key dockName="NewSpringView"/>
    </Dockable>
    <Dockable>
    <Key dockName="NewSpringView2"/>
    </Dockable>
    </Split>
    <Split orientation="0" location="0.5030927835051546">
    <Dockable>
    <Key dockName="NewSpringView1"/>
    </Dockable>
    <Dockable>
    <Key dockName="NewSpringView3"/>
    </Dockable>
    </Split>
    </Split>
    </DockingPanel>
    <TabGroups>
    </TabGroups>
    </DockingDesktop>
    </VLDocking>

     

    Другими словами, папка «build» будет содержать макет представлений в том месте, где вы закрываете приложение. Таким образом, вы можете скопировать вышеприведенный макет в файл макета в структуре вашего проекта и, в процессе, использовать само приложение в качестве дизайнера своего собственного макета!

    Дальнейшее чтение:

    Интеграция FlexDock

    Давайте теперь воспользуемся платформой стыковки FlexDock . FlexDock, в соответствии с его сайтом, является платформой для стыковки для использования в кроссплатформенных приложениях Swing и предлагает функции, которые вы ожидаете от любой платформы для настольных ПК, такие как макеты с вкладками и разделением, возможность перетаскивания и откидывания, плавающие окна, складные контейнеры и верстка макета. (Хотя я еще не разобрался с сохранением макета … кто-нибудь может помочь?)

    Мы будем использовать его для создания макета окна, который выглядит следующим образом:

    В двух словах, вам необходимо реализовать FlexDock «PerspectiveFactory», который предоставляет исходный макет представления, а затем внедрить его в bean-компонент «ApplicationPageFactory» в файле richclient-application-context.xml. Вот связанные фрагменты из файла richclient-application-context.xml:

    <bean id="lifecycleAdvisor" class="simple.SimpleLifecycleAdvisor">
    <property name="windowCommandBarDefinitions" value="ui/commands-context.xml" />
    <property name="windowCommandManagerBeanName" value="windowCommandManager" />
    <property name="menubarBeanName" value="menuBar" />
    <property name="toolbarBeanName" value="toolBar" />
    </bean>

    <bean id="applicationPageFactory" depends-on="serviceLocator"
    class="org.springframework.richclient.application.docking.flexdock.FlexDockApplicationPageFactory">
    <property name="floatingEnabled" value="true" />
    <property name="defaultPerspective" value="defaultPerspective" />
    <property name="perspectiveFactory">
    <bean class="simple.DemoPerspectiveFactory">
    <property name="dockableIds">
    <list>
    <value>NewSpringView</value>
    <value>NewSpringView1</value>
    <value>NewSpringView2</value>
    <value>NewSpringView3</value>
    </list>
    </property>
    </bean>
    </property>
    </bean>

     

    Примечание. Выше мы не используем свойство «runningPageId». Вместо этого мы позволим «applicationPageFactory» обрабатывать весь макет для нас. Строка 13 относится к этому классу, который я создал в «простом» пакете:

    import java.util.List;

    import org.flexdock.perspective.LayoutSequence;
    import org.flexdock.perspective.Perspective;
    import org.flexdock.perspective.PerspectiveFactory;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.util.Assert;

    public class DemoPerspectiveFactory implements PerspectiveFactory, InitializingBean {

    private List<String> dockableIds;

    public Perspective getPerspective(String perspectiveId) {

    Perspective perspective = new Perspective(perspectiveId, perspectiveId);
    LayoutSequence sequence = perspective.getInitialSequence(true);

    String prevDockableId = null;
    for (String dockableId : this.dockableIds) {
    sequence.add(dockableId, prevDockableId);
    prevDockableId = dockableId;
    }

    return perspective;
    }

    public void afterPropertiesSet() throws Exception {
    Assert.notEmpty(this.dockableIds, "No dockable ids specified");
    }

    public List<String> getDockableIds() {
    return dockableIds;
    }

    public void setDockableIds(List<String> dockableIds) {
    this.dockableIds = dockableIds;
    }

    }

     

    Дальнейшее чтение:

     

    Интеграция JIDE

    Интеграция между Spring RCP и платформой стыковки JIDE доступна по адресу https://jide-springrcp.dev.java.net/ , автор Джонни Рэй. Примером, который вы можете получить оттуда вместе со связанными JAR-файлами (через источники в форме проектов Maven), является приложение Google Search (больше нет ключей API SOAP от Google, поэтому я не смог опробовать функциональность приложения, но это было не совсем так)

    Я поэкспериментировал с вышеприведенным образцом и экстраполировал некоторые общие принципы, в результате чего получил простой результат (посмотрите на вкладки внизу скриншота ниже):

    Некоторые общие рекомендации для тех, кто интересуется этой интеграцией, т. Е. Это самые важные теги JIDE-Spring RCP, которые я работал в своем файле richclient-application-context.xml:

      
    <!--Here the "startingPageId" property is important: -->
    <bean id="lifecycleAdvisor" class="simple.SimpleLifecycleAdvisor">
    <property name="windowCommandBarDefinitions" value="ui/commands-context.xml" />
    <property name="windowCommandManagerBeanName" value="windowCommandManager" />
    <property name="menubarBeanName" value="menuBar" />
    <property name="toolbarBeanName" value="toolBar" />
    <property name="startingPageId" value="mainPage" />
    </bean>

    <!--Here the we define the "startingPageId" bean: -->
    <bean name="mainPage" class="com.jidesoft.spring.richclient.docking.JidePageDescriptor">
    <property name="viewDescriptors">
    <list>
    <value>NewSpringView1</value>
    <value>NewSpringView2</value>
    <value>NewSpringView3</value>
    </list>
    </property>
    </bean>

    <!--Here the we define each of the view beans: -->
    <bean id="NewSpringView1" class="com.jidesoft.spring.richclient.docking.view.JideViewDescriptor">
    <property name="viewClass" value="simple.NewSpringView1" />
    </bean>
    <bean id="NewSpringView2" class="com.jidesoft.spring.richclient.docking.view.JideViewDescriptor">
    <property name="viewClass" value="simple.NewSpringView2" />
    </bean>
    <bean id="NewSpringView3" class="com.jidesoft.spring.richclient.docking.view.JideViewDescriptor">
    <property name="viewClass" value="simple.NewSpringView3" />
    </bean>

    <!--Here the we declare that we want to use the JIDE Application Page Factory: -->
    <bean id="applicationPageFactory" class="com.jidesoft.spring.richclient.docking.JideApplicationPageFactory" />

    <!--Here the we declare that we want to use the JIDE Application Window Factory: -->
    <bean id="applicationWindowFactory" class="com.jidesoft.spring.richclient.docking.JideApplicationWindowFactory" >
    <property name="saveLayoutOnClose" value="true" />
    <property name="doubleClickAction" ref="com.jidesoft.docking.DockingManager.DOUBLE_CLICK_TO_MAXIMIZE" />
    <property name="heavyweightComponentEnabled" value="true" />
    <property name="showWorkspace" value="true" />
    <property name="layoutVersion" value="2" />
    </bean>

    <!--Some related obligatory beans: -->
    <bean id="com.jidesoft.docking.DockingManager.DOUBLE_CLICK_NONE"
    class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"/>

    <bean id="com.jidesoft.docking.DockingManager.DOUBLE_CLICK_TO_FLOAT"
    class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"/>

    <bean id="com.jidesoft.docking.DockingManager.DOUBLE_CLICK_TO_MAXIMIZE"
    class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"/>

     

    Это абсолютные основы. Результат довольно крутой, и я думаю, что Джонни Рэй проделал отличную работу. Взгляните на все свойства, доступные для каждого вида, например:

    Однако, я думаю, это упростило бы ситуацию, если бы он сделал JAR-файлы доступными на своем сайте вместе с уже существующими проектами Maven, содержащими источники.

     

     

     

    MyDoggy Integration

    Питер Карич недавно упомянул о своей интеграции с MyDoggy , а также представил проект NetBeans, содержащий, помимо прочего, код интеграции, а также код, демонстрирующий, как использовать его интеграцию. Я извлек классы интеграции MyDoggy / Spring RCP и создал для них отдельную библиотеку Java:

    Затем я поместил полученный JAR-файл в classpath моего собственного приложения и использовал его, как описано ниже, для создания простого макета, подобного этому:

    Вот соответствующие части MyDoggy в моем richclient-application-context.xml. В первом bean-компоненте обратите внимание, что свойство «initialPageId» указывает на bean-компонент «startPage». В bean-компоненте «startPage» начальный макет определяется во внешнем файле layout.xml или (если этого файла нет или он пуст) путем отображения двух представлений, введенных ссылочными компонентами:

    <bean id="lifecycleAdvisor" class="simple.SimpleLifecycleAdvisor">
    <property name="windowCommandBarDefinitions" value="ui/commands-context.xml" />
    <property name="windowCommandManagerBeanName" value="windowCommandManager" />
    <property name="menubarBeanName" value="menuBar" />
    <property name="toolbarBeanName" value="toolBar" />
    <property name="startingPageId" value="startPage"/>
    </bean>

    <bean id="startPage" class="org.mydoggy.MyDoggyPageDescriptor">
    <!-- EITHER use this file if not empty/absent: -->
    <property name="initialLayout">
    <bean class="org.springframework.core.io.FileSystemResource">
    <constructor-arg type="java.lang.String">
    <value>resources/ctx/layout.xml</value>
    </constructor-arg>
    </bean>
    </property>
    <!-- OR use these initial views: -->
    <property name="viewDescriptors">
    <list>
    <value>NewSpringView1</value>
    <value>NewSpringView2</value>
    </list>
    </property>
    </bean>

    <bean id="applicationPageFactory"
    class="org.mydoggy.MyDoggyApplicationPageFactory">
    </bean>

     

    Как указано в строке 14, есть файл макета в формате XML, который следует формату макета MyDoggy:

    Как и в случае с интеграцией VLDocking, описанной ранее, при перемещении представлений в развернутом приложении создается файл layout.xml. Разница в том, что, хотя в случае VLDocking вновь созданный файл был найден в папке «build», восстановленный XML-файл просто заменяет исходный файл в текущей версии интеграции Питера Карича с MyDoggy.

    Примечание. Просто создайте пустой XML-файл в расположении и с именем, определенным вашим эквивалентом строки 14 в файле richclient-application-context.xml выше. Затем запустите приложение. Представления не будут показаны, потому что файл XML пуст. Затем откройте некоторые виды. Затем закройте приложение. Теперь … вы увидите, что ваш XML-файл заполнен сгенерированным кодом, а это означает, что вам вообще не нужно ничего знать о тегах, составляющих файл. Поэтому вам никогда не нужно прикасаться к файлу, если вы не знаете об этом достаточно и не хотите каким-то образом настроить его вручную.

    В целом, интеграция MyDoggy Питера Карича действительно классная. Мы надеемся, что он (как только он будет доволен этим) создаст страницу проекта точно так же, как на странице Джонни Рэя, чтобы было легче получить MyDoggy JAR для интеграции со Spring RCP.

     

    Роллинг свой собственный

    Существует несколько дополнительных систем стыковки, о которых мы уже говорили, и, скорее всего, будущее принесет еще больше. Для тех, кто хотел бы интегрировать одну или несколько из этих альтернативных платформ стыковки с Spring RCP, вот краткое введение в то, что вам нужно сделать.

    В качестве примера мы будем использовать компонент TabbedContainer просто потому, что он очень прост. Компонент TabbedContainer обсуждался несколько лет назад на Javalobby Скоттом Делапом. Получить его можно несколькими способами, одним из которых является загрузка инфраструктуры JDocking , которая является (старой) ветвью частей платформы NetBeans. Другой способ — получить его от самой платформы NetBeans, частью которой он все еще является, и где он также связан с Javadoc . Однако я бы не рекомендовал использовать его вместо других обсуждавшихся до сих пор, потому что альтернативные стыковочные платформы, представленные ранее, являются более сложными.

    В конце этого раздела у нас будет очень простая компоновка окна путем интеграции компонента TabbedContainer в качестве нашей платформы стыковки:

    Из нескольких классов, которые мы могли бы расширить / реализовать / вызвать, мы сосредоточимся только на тех классах, которые сейчас занимаются вопросами уровня приложения:

    • org.springframework.richclient.application.ApplicationPageFactory
    • org.springframework.richclient.application.ApplicationPage
    • org.springframework.richclient.application.support.AbstractApplicationPage
    • org.springframework.richclient.application.PageDescriptor
    • org.springframework.richclient.application.ApplicationWindow

    В этом разделе будут созданы только два класса из нижеприведенного пакета «стыковка», чтобы предоставить действительно простой, хотя и наглядный пример того, как вы бы поступили так же для любой другой платформы стыковки:

    Проще говоря, для начала вам нужно создать этот bean-компонент в файле richclient-application-context.xml, который ссылается на фабрику, которую вы видите на скриншоте выше:

    <bean id="applicationPageFactory" class="docking.TabbedContainerApplicationPageFactory"/>

     

    … и добавить его с этим содержанием:

    import org.springframework.richclient.application.ApplicationPage;
    import org.springframework.richclient.application.ApplicationPageFactory;
    import org.springframework.richclient.application.ApplicationWindow;
    import org.springframework.richclient.application.PageDescriptor;

    public class TabbedContainerApplicationPageFactory implements ApplicationPageFactory {

    public ApplicationPage createApplicationPage
    (ApplicationWindow window, PageDescriptor descriptor) {
    TabbedContainerApplicationPage page = new TabbedContainerApplicationPage(window);
    return page;
    }
    }

     

    А вот класс «ApplicationPage», который упоминается выше:

    import javax.swing.Icon;
    import javax.swing.JComponent;
    import javax.swing.JPanel;

    import org.jdocking.swing.tabcontrol.DefaultTabDataModel;
    import org.jdocking.swing.tabcontrol.TabData;
    import org.jdocking.swing.tabcontrol.TabDataModel;
    import org.jdocking.swing.tabcontrol.TabbedContainer;

    import org.springframework.richclient.application.ApplicationWindow;
    import org.springframework.richclient.application.PageComponent;
    import org.springframework.richclient.application.support.AbstractApplicationPage;

    public class TabbedContainerApplicationPage extends AbstractApplicationPage {

    private TabbedContainer tabbedContainer;
    private TabDataModel tabDataModel;
    private TabData tabData;
    private ApplicationWindow window;

    TabbedContainerApplicationPage(ApplicationWindow window) {
    this.window = window;
    }

    //Called at startup.
    //In this case our initial view will be an empty JPanel,
    //which we use to initialize the TabData,
    //which in turn is used to initialize the TabDataModel,
    //which then is used in the initialization of the TabbedContainer,
    //which is then added to the Spring RCP window's ContentPane:
    @Override
    protected JComponent createControl() {
    JPanel welcomePanel =
    new JPanel();
    tabData =
    new TabData(welcomePanel, /*icon: */ null, "Welcome!",
    "This is a tooltip");
    tabDataModel =
    new DefaultTabDataModel(new TabData[]{tabData});
    tabbedContainer =
    new TabbedContainer(tabDataModel, TabbedContainer.TYPE_VIEW);
    tabbedContainer.setShowCloseButton(true);
    window.getControl().getContentPane().add(tabbedContainer);
    return welcomePanel;
    }

    //Called whenever a new view is opened:
    @Override
    protected void doAddPageComponent(PageComponent pageComponent) {
    //From the PageComponent, get the view's content:
    JPanel content = (JPanel) pageComponent.getControl();
    //From the PageComponent, get the view's display name:
    String name = pageComponent.getDisplayName();
    //From the PageComponent, get the view's icon:
    Icon icon = pageComponent.getIcon();
    //Initialize a new TabData, with the retrieved items above:
    tabData = new TabData(content, icon, name, "This is a tooltip");
    //Add the TabData to the TabDataModel:
    tabDataModel.addTab(/*position: */1, tabData);
    }

    //Called for each view that is open,
    //when the application closes:
    @Override
    protected void doRemovePageComponent(PageComponent arg0) {
    }

    //Called to give focus to something:
    @Override
    protected boolean giveFocusTo(PageComponent pageComponent) {
    return pageComponent.getControl().requestFocusInWindow();
    }

    }

     

    Один твик в строке 41 выше:

    new TabbedContainer(tabDataModel, TabbedContainer.TYPE_EDITOR);

     

    … и код приведет к несколько иному расположению вместе с элементом управления справа для пролистывания открытых представлений:

    Еще один твик в строке 41 …

    new TabbedContainer(tabDataModel, TabbedContainer.TYPE_TOOLBAR);

     

    … и у вас есть кнопки вместо вкладок для переключения между видами:

    Можно видеть, что, хотя компонент TabbedContainer довольно прост (он не обеспечивает типичную поддержку, общую для платформ стыковки, такую ​​как стыковка / отмена, максимизация / минимизация и т. Д.), Он довольно полезен для представления основных аспектов интеграции стыковки. с весны RCP. Более ранние интеграции (VLDocking, FlexDock, JIDE и MyDoggy) показывают, что вы можете пойти гораздо дальше и предоставить функции на более низких уровнях, т. Е. Выше мы рассмотрели только стыковку на уровне приложений, в то время как мы могли бы, кроме того, предоставить конкретные функции на уровне отдельных окон в приложении, такие как возможность или нет окна быть закрепленным / отстыкованным, развернутым / свернутым и т. д. Уроки, относящиеся к этим аспектам, могут быть экстраполированы из исходного кода других интеграций и будут обсуждаться в другой части этой серии.

     

    Вывод

    Мы рассмотрели интеграцию нескольких систем стыковки с Spring RCP. Spring RCP официально поддерживает VLDocking и FlexDock. Фактически, JAR VLDocking является частью дистрибутива Spring RCP, хотя FlexDock, похоже, больше не находится в активной разработке. Можно сделать вывод, что VLDocking является предпочтительной платформой стыковки, когда речь идет о предоставлении оконной системы для приложений, построенных на основе Spring RCP. Тем не менее, JIDE и MyDoggy хорошо представлены Джонни Рэем и Питером Каричем, и я считаю, что оба находятся в очень хорошем положении для интеграции. Другие фреймворки, в том числе платформа NetBeans через ее TopComponents, также должны быть интегрируемыми (что я надеюсь обсудить в статье в ближайшее время) через классы, которые я представил в последнем разделе этой статьи.

    Spring RCP представляет собой очень универсальный подход: вы можете выбрать любой док-фреймворк, который вам больше подходит, а затем прикрепить его к вашему приложению Spring RCP без особых проблем. Я надеюсь, что эта статья дала относительно твердое введение, с отправными точками для дальнейшего изучения посредством дальнейшего чтения предложений и ссылок в различных разделах.