Integrating Into Swing-Based Applications
Java is enjoying a renaissance on the desktop, yet developers are still frequently required to invent methods for dealing with application management tasks within J2SE. One common problem involves the design decision regarding whether an application should adopt a Single Document Interface (SDI) or Multiple Document Interface (MDI) window presentation. This article discusses the issues surrounding
window frames and their environments when using Swing.
SDI vs MDI Presentations
The two class models that support SDI versus MDI presentation environments within J2SE are incompatible with each other for event processing and setup, which makes their consideration important for new applications. Designers cannot push this problem to a later life-cycle phase or product revision because an application's data presentation should cater to the user's expected work environment. This is true for users of Mac or Windows programs who have different expectations for how their GUI will appear and respond. If a developer must make a design compromise, then the application's usability or appeal beyond a select platform will be limited. Careful organization of application logic allows for an approach that supports a dual SDI and MDI presentation within the same application in the context of the J2SE 1.3 and 1.4 Swing libraries.
A Common Frame
The most basic presentation structure available to Swing-based applications is javax.swing.JFrame. JFrame implements a SDI window that presents a user interface by hosting customized javax.swing.JComponent objects. MDI windows are provided to developers through javax.swing.JInternalFrame, although these structures are not actually native windows; rather, JInternalFrame implements a JComponent that understands how to draw itself with a title bar and behave as an embedded frame.
The event models used to track button clicks and other events within these window structures are incompatible as a result of JFrame and JInternalFrame's dissimilar inheritance trees (JFrame is a true java.awt.Window derivative, whereas the latter is an embedded window element). Fortunately, an application's data presentation layout and its associated business logic connections are provided by JComponents supplied to each frame's content pane. Further, the designers of JFrame and JInternalFrame were kind enough to give many of the important initialization and manipulation methods similar signatures (parameter lists and return types). This combination of shared behavior and structure allows developers to apply the Adapter design pattern by declaring a representative interface that includes all of the methods required for manipulating a typical frame with the added safety of deferring the definition of the application's interface to some JComponent object. The nature of Java's inheritance rules makes possible the use of this strategy: any class can extend one other class while simultaneously implementing any number of interfaces. Figure 1 provides an example of how an interface can represent both a JFrame and a JInternalFrame simultaneously.
Similar tasks do not necessarily use methods with the same signature, and some of the functionality in one frame class is not present in the other class due to specialization. Choosing either class as the primary template for the representative interface easily solves these behavioral discrepancies, leaving the alternate derived class able to map missing functionality using a combination of method calls for native frame logic. The result of this logic combination is an implementation that is familiar to Swing developers yet also compatible with a traditional three-tier application design where presentation, business logic, and IO logic layers are kept distinct (see Listing 1).
This common frame foundation does not completely provide the desired dual presentation application, however. Although the interface combines access to both SDI and MDI frame implementations, an application must also concern itself with window creation and management. SDI and MDI presentation components must allow for their seamless exchange at runtime in order to accommodate different platforms. Further, JInternalFrame objects cannot operate without a managing JDesktopPane instance.
The Frame Environment
The Abstract Factory and Factory Method patterns provide excellent design entry points for the extension of the developing framework by defining component relationships to ease frame creation and management for the application. As before, using interfaces allows the framework to substitute environments, resulting in an entire change of the system's presentation strategy with no effect on surrounding logic.
SDI presentation requires the least complex environment because JFrame provides an independent presentation that does not require additional components to enable its display. An MDI environment is more complex because an active JDesktopPane object embedded within a master JFrame is required to enable the rendering and manipulation functionality required by JInternalFrame objects. Apart from these differences, the two environments' needs are essentially the same. Architects can therefore consider two design strategies when creating the concrete classes, either of which works, providing the application will operate within the Swing framework:
Our dual environment framework uses an abstract class to provide the foundation for each of the concrete environments, as shown in Figure 2. This superclass provides concrete derivations with a collection to track each environment's frames, as well as shared functions for general frame maintenance. Use of AbstractList for the frame collection type gives applications the advantage of threadsafe behavior through the assignment of Vector objects, while faster performance can be accomplished by substituting ArrayList instances instead. Platform-specific presentations, such as the proper positioning of the Mac OS's global menu bar, can be effectively defined at this concrete level for general application use.
- The SDI environment can be defined and then a MDI environment can be derived from this, recognizing that MDI is merely a complex SDI presentation.
- An abstract base class from which both the SDI and MDI frames inherit can be defined.
The derived SDI environment's need for only the addition of creation logic to handle SDI frame instantiation makes this component's simplicity apparent. The MDI environment needs to go a step further by providing initialization routines for a master application JFrame and an associated JDesktopPane through which the environment will display the internal frames to users. Developers should be able to define environments for technologies other than Swing in a similar fashion.
The Application Environment
In addition to hosting frames, the system should allow for tasks such as tiling windows and registering predefined frame objects that the application can clone in order to provide common document presentations. For this purpose, the framework defines a frame management interface and abstract base class.
The interface component provides access to the session environment and any existing frames. A middleman frame creation method is provided for both the application's convenience and the opportunity for subclasses to clone and return commonly requested window types, such as a document workspace previously registered with the manager and its environment. The abstract component houses the presentation environment for each new session and can also be defined to select the appropriate environment early in an application's execution. Figure 3 illustrates the overall architecture by which the application can associate a presentation system with the other essential functionality.
Platform-specific rules not explicitly handled by the selected environment are best defined at the management-component level. More complex applications, such as a document-centric system (e.g., a multimedia word processor), should build upon the abstract class to provide the logic for frame interaction and arrangement from the user perspective. This includes business rules for activities such as window layout, layering, and positioning. Developers can extend the management system through the addition of custom window behavior logic and event listeners to provide the application with its own global frame management architecture.
The framework now provides for SDI and MDI windows, their host environments, and a general application manager. Locations exist to add platform-specific logic as required, and environments can be swapped out for one another without any detrimental impact on the program's logic. A remaining requirement is to support menu arrangement, which is different for each presentation environment.
Menus displayed within an SDI application appear in the same menu bar for any given window, regardless of whether the menu relates to the application, the document, or another conceptual division of the user's workspace. By comparison, MDI applications display their global application and help menus in the master window's menu bar, while project and document menus exist within local menu bars of the internal windows. The presentation framework can accommodate these divisions by creating specialized menu managers and containers that provide each presentation environment with all of the required information to ensure the appropriate arrangement of divisions.
An understanding of the existing Swing menu framework is required to properly implement these menu components. A JFrame uses a JMenuBar object to host the window's various menus, which are each represented by JMenu instances. A JMenu can contain multiple menu items in the form of JMenuItem objects, as well as submenus represented by additional JMenu objects. A JFrame's setJMenuBar method is executed with the desired primary JMenuBar instance as the parameter. Any JMenu object will only draw itself in one visible JMenuBar instance at any given time. This means scenarios in which a menu bar would logically apply to several different frames (such as document windows of the same type) require the cloning of the menu bar and its contents. Figure 4 shows how this can be achieved using a template manager and a customizable menu group interface.
The menu manager is aware of associated menu groups and can provide limited manipulation operations on those groups to affect attributes such as visibility. In addition, the manager also understands a predefined arrangement of menu group types that guide the display of associated groups from left to right in the order of their significance to the application and to the user. This ensures a consistent menu arrangement regardless of which frame is being displayed. In a simple example these arrangement values are predefined, but a more powerful type registration mechanism with arrangement-weighting schemes could be supplied for systems requiring extensive flexibility.
Extending JMenuBar provides the application with a Swing-aware management component that ties directly into the framework's presentation architecture. Implementing the Clonable interface allows the clone() method to be used by the presentation environment to produce clean copies of the menu bar and its menus.
The concrete SDI environment clones the manager and distributes this to newly created frames to provide the application global menus, but defers the addition of document-specific menu groups to each frame's custom JComponent. The benefit of this arrangement is that application and help-level menu groups display in consistent arrangements with the same content across different windows. The concrete MDI environment directly associates the menu bar manager only with the application's master frame, but still provides copies of the manager to internal frames to allow the opportunity to provide a consistent project menu group set across all document frames. An alternative approach would involve documents supplying the same functionality through custom JComponent objects associated with internal frames to provide project menu groups alongside document-level menu groups.
A menu group is aware of its associated JMenu objects, but otherwise acts as an environment setup and container class. While visibility operations exist, such as toggling enabled states for all associated menus, the definition of status operations for each JMenu is more generally left to the application. Programmers benefit from the menu group's ability to create convenient templates for creation and initialization, such as an Edit menu for a text editor or the File menu for an application. New menu groups can then be quickly created and attached to a new window's menu bar manager with a minimum of code (see Listing 2).
J2SE provides much of the functionality necessary to create applications for all of the major platforms, but multiplatform presentation has always been a problem. The goal is to create a single framework that represents common methods for different frame types with the ability to host frame instances. This allows developers to focus on business logic while remaining comfortable with the knowledge that their application will be well behaved across all of their customers' computing environments.
This article walked through the design and key implementation considerations for such a framework that can be easily integrated into existing Swing-based applications. A complete implementation of this framework can be found at the author's Web site, http://home.insight.rr.com/thebretts/todd/research/.
Resources and Further Reading Apple Computer, Inc. (2001). Aqua Human Interface Guidelines. Inside Mac OS X. Apple Computer, Inc.
Gamma, Erich, et al. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley.
Sun Microsystems, Inc. Java 2 Platform, Standard Edition, v 1.4.2 API Specification: http://java.sun.com/j2se/1.4.2/docs/api
Sun Microsystems. (2001). Java Look and Feel Design Guidelines, Second Edition. Addison-Wesley.
About The Author
Todd Brett has over 10 years of experience architecting and implementing well-behaved, multiplatform applications in a variety of languages. He holds an MS with an emphasis in object-oriented technologies and technology management from Regis University in Denver.
Vol. 9, Issue 1, p. 44
1 class SDIFrame
2 extends JFrame
3 implements IMultiEnvironFrame
5 // interface methods do not need
6 // to be specified--JFrame
7 // provides these.
1 class MDIFrame
2 extends JInternalFrame
3 implements IMultiEnvironFrame
5 // Interface methods specific to
6 // JFrame are defined using
7 // JInternalFrame method mappings.
9 public void setIconImage(
Image p_icon )
new ImageIcon( p_icon ) );
15 // ...
1 class ApplicationMenuGroup extends
3 // ...
5 // Very simple implementation.
6 public Object clone()
8 ApplicationMenuGroup newClone =
// Could also use copy
10 return newClone;
13 protected void initMenus()
15 JMenu fileMenu =
17 addMenu( fileMenu );
18 // ...