VLDocking with history
The following steps add a functionality to a Spring-RCP project, that resembles to the Eclipse perspectives.
Add VLDocking as a dependency
Add the following dependency to the pom.xml:
<dependency> <groupId>org.springframework.richclient</groupId> <artifactId>spring-richclient-vldocking</artifactId> <version>${springrich.version}</version> </dependency>
Add ShowPageMenu command
Modify the definition of the window menu in the commands-context.xml, so that it looks like the following:
<bean id="windowMenu" class="org.springframework.richclient.command.CommandGroupFactoryBean"> <property name="members"> <list> <bean class="org.springframework.richclient.command.support.NewWindowCommand"/> <value>separator</value> <bean class="org.springframework.richclient.command.support.ShowViewMenu"/> <bean class="org.springframework.richclient.command.support.ShowPageMenu"/> </list> </property> </bean>
The last line adds a new menu entry, that lists all ApplicationPages, the following definitions are also necessary in your messages.properties file (adapt the page ids to your page names):
showMenuPage.label=Open perspective pageId1.label=page1 pageId2.label=page2
Modify views
For VLDocking, views need a different descriptor, exemplified on the initialView:
<bean id="initialView" class="org.springframework.richclient.application.vldocking.VLDockingViewDescriptor"> [...] <property name="closeEnabled" value="true"/> <property name="autoHideEnabled" value="true"/> <property name="floatEnabled" value="true"/> </bean>
The three added properties at the end configure the VLDocking behaviour. In contrary to the defaults, closing, auto-hiding (hide a tab at the window border, like a FastView in Eclipse) and float (MDI-like behaviour) shall be allowed.
Define an ApplicationPage
Now we define a default page. On creation of the page the application tries to read the layout from the file given in the property “initialLayout”. If this doesn't work (e.g. the file does not exist), all views listed in the property “viewDescriptors” will be shown.
<bean id="defaultPage" class="org.springframework.richclient.application.vldocking.VLDockingPageDescriptor"> <property name="viewDescriptors"> <list> <value>initialView</value> </list> </property> <property name="initialLayout"> <bean class="org.springframework.core.io.FileSystemResource"> <constructor-arg type="java.lang.String"> <value>${user.home}/.appdir/layout/defaultPage.xml</value> </constructor-arg> </bean> </property> </bean>
For each new page, another entry has to be added. All pages do get listed in the window-menu within the ShowPageMenu-submenu. To use one of these pages as starting page for your application, just place its ID in the property “startingPageId” of the lifecycleAdvisor.
Automagically save the Layouts
One thing is still missing: The user doesn't have a configuration file for the page layouts in his home directory. For this purpose we register a PageListener on each new window, which saves the layout automatically to the file given in the configuration, if the window gets closed.
/** * Called after the actual window control has been created. * * @param window The window being processed */ public void onWindowCreated( ApplicationWindow window ) { if( logger.isInfoEnabled() ) { logger.info("onWindowCreated( windowNumber=" + window.getNumber() + " )"); } // dockable pages shall listen to close events, for saving their layout if (window.getPage() instanceof VLDockingApplicationPage) { window.addPageListener(new PageListener() { public void pageOpened(ApplicationPage page) { // nothing to do here } public void pageClosed(ApplicationPage page) { VLDockingApplicationPage vlDockingApplicationPage = (VLDockingApplicationPage) page; saveDockingContext(vlDockingApplicationPage); } }); } } /** * Saves the docking layout of a docking page fo the application * * @param appWindow The application window * (needed to hook in for the docking context) */ private void saveDockingContext(VLDockingApplicationPage dockingPage) { DockingContext dockingContext = dockingPage.getDockingContext(); // Page descriptor needed for config path VLDockingPageDescriptor vlDockingPageDescriptor = (VLDockingPageDescriptor) Application.instance().getApplicationContext().getBean(dockingPage.getId()); // Write docking context to file BufferedOutputStream buffOs = null; try { File desktopLayoutFile = vlDockingPageDescriptor.getInitialLayout().getFile(); checkForConfigPath(desktopLayoutFile); buffOs = new BufferedOutputStream(new FileOutputStream(desktopLayoutFile)); dockingContext.writeXML(buffOs); buffOs.close(); logger.debug("Wrote docking context to config file " + desktopLayoutFile); } catch (IOException e) { logger.warn("Error writing VLDocking config", e); } finally { try { buffOs.close(); } catch (Exception e) { } } } /** * Creates the config directory, if it doesn't exist already * * @param configFile The file for which to create the path */ private void checkForConfigPath(File configFile) { String desktopLayoutFilePath = configFile.getAbsolutePath(); String configDirPath = desktopLayoutFilePath.substring( 0, desktopLayoutFilePath.lastIndexOf(System.getProperty("file.separator"))); File configDir = new File(configDirPath); // create config dir if it does not exist if (!configDir.exists()) { configDir.mkdirs(); logger.debug("Newly created config directory"); } }