Verdantium towards a Java-enabled compound document model (poster session)
Authors: Thornton Green
Venue: Addendum to the 2000 proceedings of the conference on Object-oriented programming, systems, languages, and applications (Addendum) (2000)

Java Beans provides a robust mechanism for combining software components. However, to a large extent Java Beans components are currently not being combined to create documents in an environment such as a word processor or illustration program. This is not due to a weakness in the Beans property model, but rather to limitations in how Java Beans' user interfaces are currently implemented. Verdantium is a prototype Java-based API (for JDK 1.2.2 and above) for document embedding that takes a novel approach to implementing software components. This environment retains the property-based semantics from Java Beans, but implements different approaches for on-screen presentation, visual embedding, document printing, and persistence. Fully functional applications (i.e., word processors, illustration programs, equation editors, etc.) can be implemented as individual software components that can either run independently or be embedded in other applications using the same API. Verdantium's presentation API works on top of Java JFC/Swing and is implemented using the Model-View-Controller (MVC) philosophy. That is to say, the user interface for a certain kind of document is kept separate from its application logic. The VerdantiumComponent is a Java interface implemented by the model class, with the GUI stored in a separate object (though one may optionally integrate the two). By contrast, Java Beans that are displayed in the Bean Box are subclasses of a view class, with no inherent support given to the underlying model. One important aspect of using this interface is that an implementation of VerdantiumComponent does not need to subclass a descendent of java.awt.Component. For instance if the component's GUI is a scrolling pane, one does not have to subclass JScrollPane. Instead, the user interface of the VerdantiumComponent is the Swing JComponent returned by the VerdantiumComponent's getGUI() method. Because Verdantium components do not need to subclass java.awt.Component, subclassing can be used instead to enhance design and code reuse. For instance, a scrolling component can be implemented as a straightforward subclass of a simpler drawing component that renders onto a pane. The subclass overrides the getGUI() method so that it returns a JScrollPane containing the user interface of the superclass VerdantiumComponent. That is to say, the subclass wraps a JScrollPane around what the superclass originally returned from its own getGUI() method. Note that the JScrollPane returned by the subclass and the rendering pane returned by the superclass are two objects that can come from completely different class hierarchies (as long as they both have JComponent as a common root). In order to provide appropriate support for embedded documents and take full advantage of JFC/Swing functionality, Verdantium uses an embedding implementation based on subclassing Swing's existing JDesktopPane and JInternalFrame. The subclass of JInternalFrame modifies the internal frame's MDI user interface so that it displays itself in a fashion more consistent with an embedding frame in a typical container application. This provides a flexible and robust means for moving and resizing embedded components. Unlike typical MDI windows, Verdantium embedding frames have a transparent content area, allowing multiple components with transparent backgrounds to overlay each other in a container application. Verdantium also uses a different semantics, compared to most other document frameworks, for the display of embedding frames. Instead of displaying frames on a per-component basis, Verdantium uses a global mode that turns them all on, or turns them all off. Currently, the primary printing functionality for visual Java Beans is through the use of the java.awt.Component print() method, which does not support printing on multiple pages. Verdantium retains the use of this method, but adds an additional API for multi-page printing using the java.awt.print. Printable interface. This allows a &ldquo;multi-page&rdquo; component such as a text editor to be printed by another component in a standard way. Verdantium also provides the option for a component to take greater control over the printing process, allowing the component to do things such as display customized print dialogs. A component running as a standalone application often needs to be printed in a different manner from one than has been visually embedded in some other component. Verdantium addresses this by allowing a component to both implement the multi-page printing interface and have its UI support the java.awt.Component print() method. For instance, a visually embedded component might be printed by its parent using the print() method. Meanwhile, a standalone component displaying the same content might print itself on multiple pages. Typical pre-Java document applications can load or save data of more than one flavor from persistent storage. For instance, Microsoft Word can save its data to either plain text, RTF, or to its own Microsoft Word format. Java Beans persistence APIs currently provide no means for a bean to load and/or save its state in multiple flavors. To compensate for this, the ability to load or save in multiple data flavors is provided as a standard part of a Verdantium Component. Such a data flavor can either refer to an object in a serialized object stream or to a set of raw stream data in a legacy format. This allows a Verdantium component to load data formats such as plain text that are currently outside the Java Beans persistence model. In order to determine which component can load a particular legacy format, the file's extension is mapped to a MIME type, and then the mapped MIME type is compared with the MIME types each component supports to determine which one(s) can handle the load request. In addition to legacy file formats, Verdantium also provides a mechanism for a component to save itself to a property list of serializable objects (where each such object can be externalized in terms of another property list of objects). This allows an object to serialize itself by writing a series of name-value pairs (more precisely name-object pairs), while retaining the ability to utilize Java's existing serialization. In addition, the use of property names is advantageous when attempting to maintain different versions of the same persistence format over time. A single reader can scan for property names from several formats, and maintain compatibility with each.