You are hereAria User Guide / Section III: In Depth / Application Styles

Application Styles


By luano - Posted on 14 January 2009

Aria supports multiple application styles, including Single Document Interface (SDI) and Multiple Document Interface (MDI) styles with and without docking of the internal windows.

Using the various application types you can create a variety of applications from the simple to the complex. Most applications will rely on an SDI style of interface for simplicity, but others such as management consoles and tool style applications can make good use of a docking framework to help manage the user interface complexities that arise from hierarchies and structures of the application domain.

Application styles are simple dictated by the startup applet used to launch an application and most of the remaining code and configuration is common to all applications types. In some cases, switching between application styles is also possible, provided that attention is paid to things like page navigation and framesets.

Application styles

Aria supports multiple application styles as metntioned above. These styles are:

Application styles

Style

Description

Basic

With the basic application style you get a single window in which single pages or simple framesets can be displayed. This type of setup corresponds toa Single Document Interface

Desktop

The desktop application style is equivalent to the Multiple Document Interface or MDI, where multiple windows can be used and each has a header, allowing the window to be moved around a desktop panel.

Docking

The docking application style is almost a cross between SDI and MDI applications, whereby multiple windows are allowed, but where those windows are managed either by arranging them in tabbed windows or by docking them into sidebars.

Generally it seems that users prefer SDI type applications , or some form of docking, however some application such as complex management applications may justify use of MDI. The choice of one application style depends on your particular application and changing from one to another is just a matter of choosing the appropriate startup class.

Docking Frames

Docking frames allow multiple windows, with headers, titles and icons to be displayed in various areas of the screen. Multiple windows or targets can be placed in each of these areas. The docked windows can be minimized to sidebars and later restored to their original location. The docked windows may also be dragged from one area to another thereby allowing users to customize the layout of their application.

Docking frames also show a preview of the docked window when the mouse is moved over the sidebar button. Using these `sliding' windows can save valuable screen real estate and help reduce clutter. A user might, for instance, minimize a window to the sidebar when the information contained in that window is only of occassional interest. Then, in order to consult the window all she need do is move the mouse over the sidebar button to view the window contents once more. A simple click will then dismiss the preview.

A docked panel may also be zoomed in on so that it occupies almost all the available screen area (apart from the toolbars, menus and sidebars). To zoom in on a panel just double click the header, then to restore the view just double click the header once more.

Using the docking layout

As mentioned above, to use the docking layout you just need to select the appropriate startup application org.formaria.swing.docking.DockingApp

Startup for the docking application style

  1. java -cp AriaRuntimeCommon.jar org.formaria.swing.docking.DockingApp

The FrameTest sample application can be seen below when used with the Docking application style. The application is shown with half of its windows minimized, two to the south or bottom docking sidebar and one to the east or right handside sidebar

Setting the layout configuration

The basic frameset is specified using the frames file that was used for the basic frames setup earlier (see Framesets.), but for docking layouts we must add some extra information detailing how the screen is to be divided up. For example the following:

Setting up a docking layout

  1. <FrameSet layout="(COLUMN (ROW weight=1.0 left
  2. (COLUMN middleTop content middleBottom) right) bottom)">
  3. <Frame name="left" constraint="left" content="p1"
  4. icon="aria_icon.png" sidebar="west" title="Dock to the left"/>
  5. <Frame name="right" constraint="right" content="p2" icon="aria_icon.png" sidebar="east"/>
  6. <Frame name="middleTop" constraint="middleTop" content="p3" icon="aria_icon.png" sidebar="west"/>
  7. <Frame name="middleBottom" constraint="middleBottom" content="p4" icon="aria_icon.png" sidebar="south"/>
  8. <Frame name="content" constraint="content" content="Welcome" icon="aria_icon.png" sidebar="west"/>
  9. <Frame name="bottom" constraint="bottom" content="p6" icon="aria_icon.png" sidebar="south"/>
  10. </FrameSet>

The docking layout is specified as an attribute of the FrameSet element, and follows the format specified by the SwingLabs MultiSplitLayout layout manager (see http://today.java.net/pub/a/today/2006/03/23/multi-split-pane.html ).

Docking options

Each of the docked frames has a number of properties that yo can use to customize the appearance of the docked frame, and these are:

Docking frame attributes

Attribute

Usage

icon

Specifies the name of an icon to use in the frame's header.

sidebar

The name of the side bar into which this target docks when minimzed. The options are:

west - dock into the west or left hand side sidebar

south - dock into the south or bottom edge sidebar

east - dock into the east or right hand side sidebar

title

The title of the frame.

constraint

The name of the docking area into which this frame or panel normally docks. The constraint should match one of the areas specified by the FramsSet 's config attribute.

minimized

If true , sets the initial state of the panel to be minimized.

Embedded applications

Not all applications are standalone and in some cases an application needs to coexist with legacy functionality or functionality obtained from a third party. Therefore there are situations where an application does not have direct control of its startup or of its frame. For this purpose Aria and Aria applications can be embedded in a standard Swing application as though the Aria application was just a Panel or just another component being used by the application.

The key to embedding a Aria application is the XContentHolder interface which describes the content displayed to the user. The interface is used by the page manager to display the pages that makeup the Aria application.

Modular application

Just as a Aria application can be embedded in a legacy application, one Aria application can be embedded in another. In fact multiple Aria applications can coexist within the one JVM. Applications used in this way can also exist as standalone entities in their own right. Turning this about, applications can therefore be built in a modular way, such that a component or module can also exist and operate as a complete application.

Building applications in a modular way allows you to deliver functionality in a targeted way, depending on things like user roles/needs, security/access rights, connectivity levels, development schedules or even for commercial reasons (e.g. advanced features for power users). With a modular architecture you can be more targeted with your delivery of functionality.

Aria's support for modular applications extends throughout the platform and apart from the loading of the modules you can largely regard the separate modules as being part of the complete application from a development standpoint.

Set startup objects

Multple startup objects can be added simply by adding startup property entries in the form:

Listing the startup objects

  1. StartupObject<N>=Name;className
  2. StartupObject<N>=Name;className;Project

where is a counter starting from 0. In the second example the object is constructed via a constructor that takes an instance of the project as an argument

While this may seem like an insignificant change it opens up the possiblity of having multiple applications running within the same JVM and it means that an application can be built from modular elements, elements that can exist as standalone applications or as integrated modules.

Relaunching applications

Support for the system tray or launch area has been added. When a system tray icon is added the application can choose to stay resident in memory after the main window has been closed by setting the " ExitOnClose " startup property to false. The advantage of doing this is that the data model does not need to be reinitialized if the main window is just being redisplayed. This initialization can be significantly quicker than normal startup as all the classes needed by the JVM are already loaded. If remote data is used the startup gain may be even greater as network access may not be required.

The tray icon provides two menu items, one to open the window and the second to close the window and exit the JVM.

This version of the class uses the SwingLabs version of the tray support and is therefore limited to Swing. If JDK 6 or later is being used then the JVM's tray support could be used for non Swing applications.

The system tray/stay resident option may be particularly valuable when used in conjunction with an embedded webserver, as a remote server could thereby signal the application to wake up and display new data or alerts as when such data becomes available by simply making a request to the client application's server. The same process could also be used to provide a tighter integration between a web page/web application and a Aria application.

To use this support the application must add an instance of the org.formaria.swing.deploy.SystemTrayManager class. A good place to do this is in a LifeCycleListener implementation

Setting up the system tray

  1. public class ProjectListener implements LifeCycleListener
  2. {
  3. private static SystemTrayManager sysTray;
  4. /**
  5.   * Called when the application/applet has been created and initialized.
  6.   * @param project the owner project
  7.   */
  8. public void initialize( Project proj )
  9. {
  10. final Project project = proj;
  11. if ( sysTray == null ) {
  12. sysTray = SystemTrayManager.getInstance( project );
  13.  
  14. // Do remaining initialization and network access
  15. }
  16. }
  17.  
  18. /**
  19.   * Called when the application/applet has been shutdown and is about to exit
  20.   */
  21. public void shutdown()
  22. {
  23. }
  24. }

Embedded webserver

A minimal http server is now embedded at org.formaria.http.HttpServer . When customized this server will allow a server appplication to signal a client via a http request. By customizing the server with a response handler the application can then respond with special actions, such as a wake-up or by requesting updates/new data from the server.

JNLP support

As an alternative to using the embedded webserver an application can use the JNLP API to request that it is a singleton, that is that only one instance of the application should run at a time. The SystemTrayManager takes care of most of the work and it will invoked the Activation interface specified by a project if one is present if an attempt is made to relaunch the JWS application while the instance is still in memory . The activation object is specified as follows sometime following startup:

Setting the activation object

  1. project.setObject( "ActivationObject", this );

Typically the application will restart its user interface once reactivated. Of course care should be taken to do this on the EventDispatchThread.

A typical restart handler2

  1. public void activate()
  2. {
  3. String[] args = (String[])project.getObject( "StartupArgs" );
  4. final String eventType = args.length > ProjectListener.EVENT_TYPE_ARG ?
  5. args[ ProjectListener.EVENT_TYPE_ARG ] : null;
  6. final String eventID = args.length > ProjectListener.EVENT_TYPE_ID ?
  7. args[ ProjectListener.EVENT_TYPE_ID ] : null;
  8.  
  9. // Query the startup event in the background
  10. if (( eventID != null ) &amp;&amp; ( eventID.length() > 0 )) {
  11. SwingWorker worker = new SwingWorker()
  12. {
  13. public Object construct()
  14. {
  15. // Do the work off the EDT
  16. String url = "workspaces/myevent/" + eventID;
  17.  
  18. ProjectListener.queryEvents( project, eventType, url );
  19. return null;
  20. }
  21.  
  22. public void finished()
  23. {
  24. // Now, on the EDT update the tree and show the event.
  25. getBinding( taskList ).get();
  26. showEvent( eventID, eventType );
  27. setSelectedNode( eventID );
  28. }
  29. };
  30. worker.start();
  31. }
  32. }
  33.  

To use this type of functionality the application must make sure that the application does not exit the JVM when the main frame is closed, and this is done with by overloading the XLifeCycleListener's shutdown method - the tray manager takes care of the rest

Prevent JVM Exit

  1. /**
  2.   * Initialize the project's connection
  3.   */
  4. public class ProjectListener implements LifeCycleListener
  5. {
  6. ...
  7.  
  8. /**
  9.   * Called when the application/applet has been shutdown and is about to exit
  10.   */
  11. public void shutdown()
  12. {
  13. }