I've also noticed that someone (NOT me) created a work of computer art called Verdantium:
http://wrecks.deviantart.com/art/3i-verdantium-36268967
The fractals do seem to remind one of multiple layers of embedded components...
Showing posts with label Verdantium. Show all posts
Showing posts with label Verdantium. Show all posts
Wednesday, November 7, 2007
Very Old Poster Abstract Is Still Around
I was searching the web, and I noticed that an old Verdantium-related poster session link from far back in the past still works:
http://portal.acm.org/citation.cfm?id=367845.367953
It's amazing the link still works after this long. And the poster cross-references with the topic "Computing Milieux." Fascinating.
http://portal.acm.org/citation.cfm?id=367845.367953
It's amazing the link still works after this long. And the poster cross-references with the topic "Computing Milieux." Fascinating.
Friday, September 14, 2007
There is a lot of overlap between Verdantium and the proposed JSR-296 Specification
Verdantium and JSR-296:
http://jcp.org/en/jsr/results?id=3801
are trying to solve similar problems. JSR-296 is trying to provide a framework for Swing applications running as standalone entities from a main() method. Verdantium provides a framework for application COMPONENTS-- classes that can run as standalone applications (they have a main() method) but are also flexible enough to be visually embedded inside other applications.
There is a lot that JSR-296 could learn from looking at the current Verdantium implementation on Sourceforge and/or this blog. The scope of Verdantium is in many ways larger than what JSR-296 is proposing. For instance, Verdantium has lifecycle states related to embedded components participating in multi-level undo that do not exist in the current proposal for JSR-296.
While there is still time, perhaps it would be in the best interest of the future of the Java platform if Verdantium and JSR-296 interacted and shared information in some useful way. I'm looking at joining the JCP, and hopefully people associated with JSR-296 might look at this post and/or my code on Sourceforge for ideas.
To be continued in a subsequent post...
http://jcp.org/en/jsr/results?id=3801
are trying to solve similar problems. JSR-296 is trying to provide a framework for Swing applications running as standalone entities from a main() method. Verdantium provides a framework for application COMPONENTS-- classes that can run as standalone applications (they have a main() method) but are also flexible enough to be visually embedded inside other applications.
There is a lot that JSR-296 could learn from looking at the current Verdantium implementation on Sourceforge and/or this blog. The scope of Verdantium is in many ways larger than what JSR-296 is proposing. For instance, Verdantium has lifecycle states related to embedded components participating in multi-level undo that do not exist in the current proposal for JSR-296.
While there is still time, perhaps it would be in the best interest of the future of the Java platform if Verdantium and JSR-296 interacted and shared information in some useful way. I'm looking at joining the JCP, and hopefully people associated with JSR-296 might look at this post and/or my code on Sourceforge for ideas.
To be continued in a subsequent post...
Sunday, September 9, 2007
Extending Java Beans to support a Compound Document Model: Project Verdantium
This is a paper that I wrote years ago for the OOPSLA conference as a representative of Arizona State University. It was rejected for publication mainly due to some of the comments it made about XML. My more recent comments/observations are in brackets: "[ text ]".
Extending Java Beans to support a Compound Document Model: Project Verdantium
Thornton Green
Arizona State University
ABSTRACT
Client-side visual Java Beans are poorly suited to the implementation of document-level software components such as text editors. This reduces the applicability of visually displayed Beans, limiting the client-side API primarily to a means for interchanging widgets between different integrated development environments (IDEs). By using an alternate API (Verdantium) for the embedding of beans in a visual context, clients-side code can implement a full compound document display model while leaving server-side APIs (Enterprise Java Beans) and the fundamental bean property model unchanged. 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. [Java Beans hasn't changed much since this was written; all of this is still true today]
Keywords
Component software, compound-documents, embedding, Java Beans.
1. INTRODUCTION
When Sun introduced the original container application for visually embedded Java Beans [5, 14, 16 18], the Bean Box, it included as sample components a couple of buttons, a molecule viewer, and some other components with a similar level of sophistication. Since then, little has changed. The APIs introduced by the Bean Box have been used as a way to build applications from simpler widgets in a development environment, but have not led to the widespread sharing of visual components between Java applications outside of the software development world. The term “widget” refers to a subclass of java.awt.Component (or its equivalent in another framework). This paper sometimes uses “widget” instead of “component” so that the term “component” can be used in the context of component software.
To understand the problem, one must first answer the question, “what is a Java Bean?” There are three different senses in which the term “Java Beans” tends to be used:
* As a programming standard for specifying “get” methods, “set” methods, property change events, etc [18]. The resulting components can be visually manipulated regardless of whether the have GUIs. For instance, a ComboBoxModel can be manipulated in Symantec Visual Café [22].
* As a server-side API for interacting with transaction environments and legacy code (Enterprise Java Beans) [16].
* As an API (on the client side) for subclasses of java.awt.Component to be read by the Bean Box (or similar program) from a jar file.
It is the latter of the three that creates problems for document embedding. Container applications that emulate the functionality of the BeanBox are difficult to write. Further, pure Java implementations of bean containers have inherent display problems. Many visual beans are “heavyweight” widgets, making it difficult for the pure Java container app. to superimpose a resize widget over the top of the bean.
Support for native or legacy file formats is lacking in the visual beans’ persistence standards. A class written for the Bean Box can serialize itself by implementing one of two interfaces, Serializable or Externalizable. Neither of which can support foreign file formats, unless they are object-based. This means that for example a text editor bean would need a second entirely separate persistence mechanism in order to load or save plain text files saved on the local disk. There is also no built-in mechanism for two beans to support the same persistence format. For instance, a PDF distiller bean can not serialize itself in such a way that the serialized format will be read by the free PDF reader bean when opened. Instead, the identity of the object’s class (in this case the PDF distiller bean) is “hard-coded” into the persistent data. When the file is loaded from persistent storage, the hard-coded class is used to read the object data. [Sun effectively deprecated Externalizable for XML object persistence, and uses a new system for XML. Nevertheless, the above is still true for non-XML formats.]
The way that beans are embedded into a container also presents a number of less fundamental problems that nevertheless present a series of practical difficulties. One of them is the use of subclassing of AWT components (i.e. widgets) to create beans. One of the original articles on the JDK 1.1 event model, [17], states “subclassing should be reserved for circumstances where [AWT] components are being extended in some functional or visual way.” Java Beans do not adhere to this principle. To make a bean that can be displayed in the Bean Box, the developer must subclass a widget regardless of whether she intends to extend the base widget in a functional or visual way. To quote this same page again, subclassing of AWT components “does not lend itself well to maintaining a clean separation between the application model and the GUI because application code must be integrated directly into the subclassed components at some level.” To be fair, the latter quote is referring more to using subclassing to handle events. However, it would also seem to apply to subclassing widgets in order to use them as visual beans. Any methods that talk to an interface implemented by the bean or to the bean’s “get/set” methods must necessarily go through the subclass of the widget, and can not be routed directly to the application code.
Because the APIs for visually displayed beans were created with the assumption that heavyweight widgets could be used, there is no unified API support for beans that are visually transparent. This makes it difficult for a text label bean to overlay (with a transparent background) the display content of a graphics bean with predictable results. Unfortunately, even the most basic presentation software requires this capability from its components. For instance, imagine how ugly a Microsoft Powerpoint presentation with a gradient-filled background would look if all the text labels had individual opaque rectangular backgrounds of a single color. As a practical matter, transparency support is necessary for getting useful results from visual components in a variety of situations.
Multi-page printing also presents a problem from a practical perspective. A Java Bean has one method, print(), with which to print itself into a graphics context. Unlike the APIs generally available to applications, the print() method does not support multi-page printing because it is a widget-level operation as opposed to a document-level operation. This gives the writer of the bean two choices: restrict the bean to something that only prints single pages, or implement a custom set of printing routines entirely separate from the Beans APIs.
The ability to read previous versions of the serialized state of a bean can be difficult to accomplish. The Serializable and Externalizable interfaces attach versioning information to the persistent state of a class based upon the bytecode information of the classes being serialized. If the bytecode of the class changes even slightly, older serialized files are no longer compatible. This can be remedied to an extent by defining the serialVersionUID field of each class. This will make the class able to read serialized information made by any other version of the class using the same serialVersionUID. However, this does not in itself solve the versioning problem. The class must still read a set of objects from a linear stream, attempt to ascertain which version of the software these objects refer to, and employ some type of filter to derive meaningful data from the object stream. Filtering data from a linear stream of objects can be difficult because in general there are no tags indicating what instance member name each object of the stream belongs to. As a result, it may be very difficult to derive the proper meaning from the object stream when two previous versions of the class had similar but not identical formats, and several instance members of the same class. [XML persistence using Serializable no longer seems to be using serialVersionUID.]
2. THE SOLUTION
Verdantium, a prototype API based on a set of software components the author developed to support his Ph. D. dissertation [10], extends client-side beans by implementing a compound-document model for visual components. The idea behind this model is to be able to construct complex documents by having a series of software components (beans) working together to represent the document’s various parts. For instance, a word processor and its equation editor can be separate beans that cooperate to allow the user to insert equations into a paper that she is editing. Instead of having very large monolithic applications as illustrated in Figure 1, a series of smaller beans cooperate to replicate the functionality typically seen in large applications. The construction of documents using components is more flexible because components for editing different parts of a document can be added and/or interchanged.
Figure 1 An example of modern software with all of its toolbars turned on. Taken from a screenshot of a 800 x 600 display. Note the amount of functionality that has been packaged in a single monolithic application.
Verdantium’s document model 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 [7]. Beans that are displayed in the Bean Box are subclasses of a view class, with no inherent support given to the underlying model. The VerdantiumComponent by contrast is a Java interface implemented by the model class, with the GUI stored in a separate object (though one may optionally integrate the two). The major design principles supporting the use of an interface are flexibility and pluggability as noted in [4]. Components based on interfaces are more flexible because they can extend any chosen base class, and they are pluggable in the sense that one implementation of an interface can be replaced by another that uses the same methods. One important aspect of the flexibility of using an interface is that the VerdantiumComponent does not need to subclass a widget. Instead, the user interface of the VerdantiumComponent is the Swing JComponent returned by the VerdantiumComponent’s getGUI() method.
package verdantium;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.*;
public interface VerdantiumComponent extends
EtherEventHandler
{
public JComponent getGUI();
public void handleDestroy();
public DataFlavor[]
getPersistentOutputDataFlavorsSupported( );
public void loadPersistentData( DataFlavor flavor ,
Transferable trans );
public Transferable savePersistentData(
DataFlavor flavor );
}
Figure 2 The definition of a VerdantiumComponent.
The defintion of a VerdantiumComponent is as given in Figure 2, where EtherEventHandler is a Verdantium-defined interface for handling scriptable events. The simplest Verdantium components do not need to handle any such events, and can simply provide a stub implementation of EtherEventHandler’s only method. In addition, a VerdantiumComponent capable of being used in a compound document must have a null constructor, and implement one required method not shown in the listing above. The method’s signature is as follows:
public static DataFlavor[]
getPersistentInputDataFlavorsSupported( )
This method is called at runtime using the Java Reflection API. By studying the interface definition above, one can see that every VerdantiumComponent must do three basic things. It must present a Swing GUI, it must be able to handle its own destruction, and it must be able to support a persistence architecture based on AWT’s Transferable and DataFlavor concepts. Different components implement the same interface, but provide different behaviors. In other words, the interface provides the basis for implementing a Strategy pattern with respect to multi-flavor persistence and GUI presentation [9].
The mandatory use of Swing widgets to implement Verdantium GUIs greatly simplifies the implementation of the overall framework. Heavyweight widgets make certain kinds of controls difficult to implement because the heavyweight widgets tend to display in front of any widget that does not have a peer [This has generally been true since JDK 1.1, but Sun announced during a session at JavaOne 2007 that they wanted to change this. For essentially all current JDK implementations this is still they way Java Z-Orders heavyweight instances of jaav.awt.Component]. Because Swing widgets are entirely lightweight, there are fewer problems to contend with when attempting to design controls that resize or translate the widgets. For example, Swing already provides JDesktopPane and JInternalFrame classes that implement Multiple-Document Interface (MDI) resize controls on other Swing widgets in a robust manner.
2.1 Persistence Support
To support persistent storage, a VerdantiumComponent reads and writes Transferable objects in multiple data flavors. The use of the Transferable object in the loading and storing of persistent states can be thought of as similar to the Memento pattern in [9]. The Transferable object is the Memento, the VerdantiumComponent is the originator, and the persistence system is the Caretaker. The main differences are that the VerdantiumComponent does not have to deal with a constraint solver in the same sense as the systems that served as the motivation for the Memento pattern, and that the VerdantiumComponent contains support for through data flavors for creating Transferable data in multiple formats.
The data flavors that a component can support fall into two general types. The first type is object data intended to be read from or written to a Java object stream. This allows the component to use the standard Java Beans persistence mechanism with Serializable objects. However, there is an important semantic difference between Verdantium’s object serialization and that in client-side beans. Client-side beans tend to serialize data from the widgets they inherit from, including the full view hierarchy. This has two problems. First, Swing widgets tend to store a very large amount of data to persistent storage. Much of this information is of little real use to the overall application. Second, Swing’s persistence format is still under revision as of Java 2. Verdantium components avoid these problems because they serialize the model, not the view. For instance a text editor component serializes the text of the document, not the details of the view hierarchy. There is a drawback in that the Verdantium component has to do more work to load a file than its bean counterpart. Sometimes a component written in Verdantium has to take a representation of a document and map it to an appropriate set of widgets and layout managers, or vice versa . However, the author feels that the benefits outweigh the drawbacks. [In recent versions of Verdantium the format for this has shifted from binary object streams (i.e. class ObjectOutputStream) to XML object streams. Newer versions of Verdantium also contain logic that map most implementations of Externalizable to XML. The author feels that Externalizable is much simpler, more elegant and more object-oriented than Sun's XML callback mechanism, and hence it makes sense to use the XML callback mechanism to bridge Externalizable into the XML format.]
The second general type of data flavor that Verdantium supports is raw data from a file stream. For instance, a text editor can read a standard plain text document as a set of bytes that have been loaded from an input stream. The Verdantium system has the responsibility of mapping the input file to an appropriate MIME type, and then sending this MIME type to the Verdantium component in the form of a DataFlavor object. The surrounding Verdantium system can determine if a component can read a particular file type by calling the getPersistentInputDataFlavorsSupported( ) method and then ascertaining whether the MIME type of the file is a match for one of the MIME types returned.
One drawback of this approach is that loading of persistent data fails if the Verdantium system maps a file to the wrong MIME type. This is similar to what happens in Microsoft Windows if a file extension is mapped to the wrong application. Some care must be taken to make sure that the mappings are complete and correct. Also, the particular mapping scheme that should be used seems to be highly platform-dependent. For instance Windows and Unix distinguish file types by using file extensions, while the Mac OS uses a special four-letter code stored separately from the file name [This has changed now that Mac OS X runs as a Unix variant]. How to unify the mapping schemes of all platforms under a single bytecode implementation is unclear at this time. The current version of the system runs on the Windows platform.
If a particular component is missing, Verdantium can query all other registered components and determine which component(s) can respond to an input file of a particular data flavor. To provide faster indexing, it also uses a series of hash tables to map data flavors to components, and to map file extensions to MIME types. This querying system provides an ability to interchange visual components that is not found in client-side Java Beans. One component can replace another if there is an appropriate mapping of MIME types. This gives developers greater flexibility in deploying components. Consider how Adobe Acrobat has been successful because Acrobat Reader, a free product, is able to read files of the same MIME type as the sold-for-profit Acrobat and Acrobat Distiller. Verdantium can replicate this kind of relationship more readily than client-side Java Beans.
2.2 Verdantium’s User Interface for Embedding
In order to provide appropriate support for embedded documents and take full advantage of JFC/Swing functionality, Verdantium uses a very different user interface than that exemplified by the Bean Box. One of basic problems in any compound document system is that of how the user interface distinguishes between the operations that can be performed on embedded documents. These operations fall into three basic types:
* Resizing the embedded document in the container.
* Translating the embedded document to different positions in the container.
* Editing the embedded document’s content (e.g. drawing onto an embedded paint program using the mouse).
Almost all embedding systems perform the resizing and translating of embedded documents by placing a border around the document that can be dragged with the mouse. Borders have some advantages. Large borders are easy for the user to find and drag with the mouse. They can also have distinct on-screen controls for translating as opposed to resizing. However, borders also have serious drawbacks. The display of borders moves the container document away from a WYSIWYG appearance. Borders also tend to obscure part of the document’s content. This can frustrate people attempting create complex documents because the display of borders while resizing can interfere with the user’s ability to determine whether the embedded component is the “right size” to fit neatly into its surrounding content.
Apple’s OpenDoc [1, 2, 8, 12] system uses two approaches to address this design problem: only place a border around the currently selected component, and use a really thin border. OpenDoc attempted to make resizing versus editing an embedded document as modeless as possible. That is to say, one doesn’t have to select a particular mode from a palette or a pull-down menu in order to switch from resizing to editing or vice versa. However, Apple the lack of modes also meant that there was no way to completely turn the border off. So to compensate for the fact that the selected component will always have a border (with the drawbacks that entails), OpenDoc displays a border that is about four pixels in width for translating the component. The drawbacks of this approach are that the border is very difficult for naïve users to select with the mouse, and is so small that even intermediate users who are not already familiar with OpenDoc would likely not recognize the border as a translation control.
Several container applications such as the BeanBox, Microsoft Office [13], and Symantec Visual Cafe [22] keep the concept that only the selected component has a border displayed for translating and resizing, but use a larger border with individual controls for different kinds of resize operations. The larger borders fix the selection and recognition problems, but make it more difficult to see a document in the context of the surrounding space. Also, the fact that one has to select an embedded component before resizing it creates inherent problems. Suppose the embedded component is a button. Does clicking on the button mean that a button-press event should be sent, or does it mean that the user wants to resize it? So many common components rely on single-click operations that using mouse-click selections to control the display of borders is not entirely practical outside of IDEs, which have separate “Design” and “Execute” modes that determine whether the embedded components respond to the mouse.
Verdantium takes a very different approach to the problem of how to distinguish resizing and translating from the editing of content. The Verdantium approach is based on the MDI window concept, which many users are already familiar with from their use of popular office applications. Translating a document equates to dragging the title bar of the MDI window, and resizing the document is performed by dragging the MDI’s resize control. The MDI control in the typical form found in other software is large enough that users can easily drag it and is familiar enough that users understand what to use it for, but it displays too large a border to work well in a variety of situations. To fix this problem, Verdantium requires that users accept a somewhat modal interface with the associated learning curve. The property editor palettes for the Verdantium container applications provide push-button controls for determining whether or not the MDI frames are displayed around the embedded components. The frames display differently depending on the mode of the pushbutton control (see Figures 3, 4, and 5). At the risk of sounding ridiculous, the author decided to use very simple names for each of the modes (such as “Move Mode”) to avoid names that throw too many long words at the naïve user (such as “Translate Mode”).
Figure 3 Simple components displayed in “Move Mode.”
Figure 4 Simple components displayed in “Resize Mode.”
Figure 5 Simple components displayed in “Edit Mode.”
Verdantium’s container app. MDI frames have one more important difference versus typical MDI implementations: Verdantium frames have transparent backgrounds (see Figure 6). This allows for Verdantium components to be used as semi-transparent overlays in a container application (thanks to Swing’s transparency support). There are a number of compound document scenarios where this is an extremely important capability. For example, the transparency support provides the means to lay text over graphics (see Figure 7). One drawback of this transparency implementation is that the Verdantium code tends to delve deeply into Swing’s Pluggable Look And Feel (PLAF) code in order to produce a subclass of JInternalFrame with the proper border and transparency characteristics. At least for the time being, this results in the container frame being hard-wired for a particular look-and-feel. The Java Look-And-Feel (JLF) is being used for the current implementation [this has since been extended to include Windows and Mac LAFs].
Figure 6 MDI container app. frames in Verdantium have transparent backgrounds, and take advantage of Swing’s transparency support. This allows the document creator to overlay non-rectangular shapes. A component can avoid the use of transparency by drawing an opaque background.
Figure 7 An example of why support for transparency is useful. In this illustration, a graphics component is displaying a curve, and an embedded text component that is rendering text over the top of the graphics. Note how the text is inside the curve, but the resize rectangle of the text component extends outside at the top corners.
2.3 Document-Level Printing Support
Unlike Java Beans, which only provides widget-level printing, Verdantium provides a document-level printing interface called BookPrintable. BookPrintable gives the component total control over the printing process from the time the user selects the “Print” command on the component to the time that the component decides the print operation has concluded. Verdantium also keeps the widget-level printing functionality from AWT / Java Beans. This means that there can be as many as two separate execution paths by which a Verdantium component may be printed (a document path and a widget path). The reason for this is that embedded components need to have a different printing protocol from the component that gets the original request. That is to say, there is a “master” component and there are “slave” components in the printing process, and the slaves (the ones embedded somewhere in the master’s document) do not get all of the privileges of the master. The master gets to select how many pages to print, and what will show up in each page at a document level. The slaves’ responsibility is to respond to calls to their GUIs’ print() method in a reasonable way. In most cases, the default implementations of the print() method supplied by AWT already work well enough to support the slave side of the relationship. The use of multiple paths of execution for printing allows a Verdantium component to properly support printing as either a stand-alone application or an embedded component.
2.4 Versioning
Support for persistent versioning is very important for applications software. Almost all applications have legacy file formats from previous versions of the software, and being able to interrogate these legacy formats in a useful manner helps to convince customers to spend money on regular upgrades. Versioning of serialized objects is also a tremendously difficult problem. Verdantium provides the ability for an Externalizable object to save itself in a more versionable way using an object-oriented version of a property list. The class’ implementation of the writeObject() method of the Externalizable interface creates this property list object, writes a series of objects to the property list with different property names, and then sends the property list down the stream to be serialized. The advantage of the property list is flexibility in dealing with versioning issues. For instance, an object reading persistent information from a property list can query the list to see if certain property names have objects associated with them. Also, different versions of a class can write data to different property names regardless of how or whether the schema of the class changed. The property list can then be interrogated on the read side to determine which set of property names is contained in the list. Another key advantage of the property list is that objects do not have to be read in the same order in which they are written. For instance the writeObject() may write the property for the number of items in a list after the list items because the list was read using an iterator. However, the readObject() method for the same class read the number of items first, and then loop through the property name of each list item using a simple for-next statement. The ability to arbitrarily order the reading of items from the property list greatly aides the ability to perform non-trivial versioning because the schema for the latest version of the class may not be well-suited to reading data in the order saved using previous versions of the class.
It may be useful in a future version of Verdantium to modify the existing property list system to serialize in terms of XML [20, 24]. XML would provide an ASCII representation of the object property files that could be analyzed using a standard text editor. This is a topic for future research. [This has been implemented in more recent versions. Serializing property lists to XML provides the best of both worlds. The file format is standard XML, but the object read/write system has the flexibility of object properties.]
2.5 Creating Actual Components
All of Verdantium’s capabilities would be useless if they made Verdantium components and Verdantium container applications impossible to write. In contrast to the complexity required to replicate the Bean Box, a great deal of work has been put into streamlining the number of lines of code required to construct simple Verdantium components. The Verdantium HelloWorld component currently requires 140 lines of code, including comments (not counting the optional class providing online help). The DemoContainerApp, an example class that demonstrates how to write a simple container application, currently requires 440 lines of code with comments (not counting code for an optional class devoted solely to providing online help).
3. Verdantium as a Document Model
Verdantium was created with the idea that a client-side component should be able to support all the functionality that a typical GUI application does so that the components can have wider applicability. The VerdantiumComponent revises and extends the Beans component model to support these features. Perhaps the most important of these extensions is the expanded support for persistence. Components in Verdantium can read and write files of any MIME type through a Transferable interface, or save and load Serialized objects to persistent storage. Assuming that the Verdantium system can map each file to an appropriate MIME flavor and load the raw data stream into a Transferable object, the component can support any number of file types simultaneously. Multiple components can share the same file type, allowing more flexibility in how they can be distributed. Finally, Verdantium makes it easier for Externalizable objects to be compatible with future versions of the software using alternate persistence formats.
Verdantium supports multi-page printing at the component level, allowing applications such as word processors and illustration programs to be written as components. The AWT widgets’ print() method is also supported for imaging embedded components to a particular rectangular region of the printed page. Some might argue that giving the component total control over multi-page printing makes it incompatible with use in a Java applet. However, multi-page printing can not be allowed in any form from an applet because an errant applet can request an arbitrarily large number of pages. Hence, the applet’s security manager simply would not allow a print request to be fully processed. Moreover, the browser can still perform widget-level printing of the applet through the standard interface. [This point is moot now that newer versions of IE have made it very difficult to write an HTML block that executes the Java Plug-In across all browsers (e.g. removing support for Netscape plugins). Applets are probably dead, and Verdantium is now really a framework for Java applications, and components pulled in from the network through the Verdantium Discovery system. Verdantium Discovery is probably a lot more reliable than using Applets anyway.]
Verdantium components can be used to build compound documents. Complete container applications can be written as Verdantium components in significantly less than 1000 lines of code, and structured using a robust MVC architecture. Because Verdantium code is based on Swing and the container functionality is based on JDesktopPane, the resulting GUIs are both stable and easy to use. Hopefully this will lead to a larger number of container implementations to be included with general-purpose applications such as illustration programs. Embedded components can fully utilize Swing’s support for transparency, allowing embedded components to act as transparent overlays.
One might argue that Verdantium is not compatible with many IDEs because of the techniques they use for building GUIs visually. The visual builders of many IDEs express GUI code in terms of the subclassing of java.awt.Container (or some subclass thereof), which is precisely what Verdantium was designed to avoid. In this case, there are two approaches that one might use. First, allow the model class and the view class to merge. That is to say, have the generated view class implement VerdantiumComponent. This isn’t a perfect solution, but it can work. The second is to express the entire GUI in terms of UI panes, and have each VerdantiumComponent create an instance of the appropriate IDE-generated UI pane class as a member and then return it using the getGUI() method. The disadvantage of this approach is that it may produce a series of independent pane classes where none may be necessary.
4. RELATED WORK
In many ways the environment that is architecturally the most similar to Verdantium is Apple’s now-defunct OpenDoc [1, 2, 8, 12] project. OpenDoc was a cross-platform compound-document model implemented using IBM’s System Object Model (SOM). OpenDoc components were typically written in a language such as C or C++ with a binding that allowed them to be compatible with SOM’s more sophisticated object model. The need to communicate with a separate object model through an API created extra work for the programmer and made components more difficult to write. Also, typical OpenDoc components on the Macintosh platform did not use a set of layout managers to automate GUI interactions as is often done with JFC/Swing or X-Motif widgets. For instance instead of using the equivalent of a JScrollPane to manage the GUI of a document, many OpenDoc components would have code to respond to each individual scroll bar action. This further contributed to the complexity of constructing workable OpenDoc implementations.
Among OpenDoc’s notable features were its cross-component scripting architecture, its support for embedded components, and its ability to have a component read and write files to arbitrary formats while still supporting embedding. One problem with OpenDoc was a lack of memory-protection to keep errant objects from overwriting each other. In particular, on the Mac platform there was no memory protection at all. On other platforms, components were protected from each other, but the objects that comprise a component could still compromise each other in that component’s memory space. Contrast this with the Java VM, where objects are not allowed to clobber each others’ memory. OpenDoc’s lack of memory protection meant that a single ill-behaved component could crash other components in a document, seriously affecting the robustness of the architecture. OpenDoc is no longer supported by its original vendors, and very little development of new OpenDoc components has been done in the past two years.
Java Beans [5, 14 16, 18], the standard component architecture for Java, is more robust than OpenDoc in the sense that the Java VM prevents ill-behaved objects from clobbering each other. Moreover, Java Beans are easier to write in many ways because the Beans object model is the same as that for the Java language. The use of Java layout managers automates many of the more complex tasks related to the GUI, allowing the developer to focus on those events that actually affect the domain logic of the component. The problems with client-side beans were discussed earlier in the paper. For the sake of brevity, they are not repeated here.
Object Linking and Embedding (OLE) is Microsoft’s environment for creating compound documents in the form of custom controls with a WYSIWYG appearance [11]. OLE uses Microsoft’s COM object model to provide an interface mechanism for components to communicate. Like OpenDoc’s SOM model, COM components are written in a language like C or C++ with wrappers that allow them to work in the COM model. OLE components also require a host application to support their display. Microsoft Office applications use OLE as a means to interoperate. ActiveX, a close cousin of OLE, provides an architecture for controls to be displayed on the web.
Aldus developed the Vamp environment as a compound-document implementation designed to streamline the development and maintenance of software components within the company, and to aid in the porting of code between the Macintosh and Windows platforms [6]. The architecture of Vamp was based on Model-View-Controller with the use of event-driven state machines to alter component states. Vamp allowed large programming teams at Aldus to be divided into smaller groups working on individual components. Reenskaug and Skaar [15] developed a documentation environment with a number of compound-document capabilities, and with the additional ability to collapse part of a document. Embedded components included class and method definitions. Netscape worked on a compound document extension to Java Beans two years ago [23]. However, little information has been released about this project.
Faustini’s Visual Java, an early ancestor of the Bean Box, provided a purely visual environment for building GUIs in a container application as mentioned in [21]. Not only were the GUIs visually built, but the algorithms tied to the GUI actions were also built from visual components. Visual Java used a data model based on the programming language Lucid expressed using an operator net concept. Each operator in the net was capable of running on independent threads of execution and could potentially operate in either a deterministic or nondeterministic fashion. The name “Visual Java” is now used for a different product. The closest environment to Faustini’s Visual Java today is Java Studio [19].
Improved persistence models for Java Beans have recently become a topic of much interest. One persistence standard seeing increasing use is XML [20, 24]. XML is an HTML-based language for representing object-oriented data [This sentence was one of the major reasons why the paper got rejected. Should I have written "HTML-like" instead of "HTML-based"? Should I have written "SGML-based" instead of "HTML-based"? Both HTML and XML owe their lineage to SGML. SGML is a meta-language that doesn't describe a particular format (i.e. how to define tags). HTML defines a format for part of SGML. XML also defines a format for part of SGML, and defines the tag format (e.g. use of angle brackets for tags) the same as HTML. As a result, XML loads directly into many browsers designed for HTML, but the browsers simply don't recognize the content of the tags. So XML was IMHO based on many tag format concepts from HTML, but the paper got rejected anyway.]. Objects are represented in XML by a set of tags that describe the states of each of the objects’ members. The XML format also provides a means to support versioning. A program can accomplish this by parsing the XML data to interrogate its format, and then converting the old format to match that required by the current software. One of the advantages of XML is that it is not dependent on a particular object model. XML data can be read and written by systems outside the Java architecture such as relational databases. Because XML is HTML-based, XML parsers can not read or write formats such as non-HTML plain text files or images. [As noted before, Verdantium now persists objects in XML].
XML can be used in a variety of applications. An example of XML’s flexibility is the Simple Object Access Protocol (SOAP) which uses XML as the basis of a wire format for remote method invocation using HTTP [3]. The Java implementation of SOAP has some architectural similarities to Verdantium in the sense that they both use Java interfaces as opposed to base classes to represent the fundamental object types of the system. The element types in SOAP are implemented using an interface hierarchy to provide the methods supported by each type of SOAP data. Instead of the properties list metaphor used by Verdantium, SOAP represents data as a linked collection of structured types: arrays, simple types, compound records, and object references. [It could be said that XML describes "nouns and verbs" but it doesn't describe any kind of "vocabulary". As a result, Verdantium has classes that scan the format of the XML file, and then determine which component should load it. In a sense, it answers the question, "which component speaks in this vocabulary?"]
5. ACKNOWLEDGMENTS
The author would like to thank all the people who made helpful suggestions about the architecutre: Dr. Edward Ashcroft, Dr. Timothy Lindquist, Dr. David O. Hestenes, Dr. David Halliday, Al Butkus, Pat Reany, and Dwain Desbien. I would also like to thank Dr. Tony Faustini, without whom I may never have discovered the Java language.
6. REFERENCES
[1] Apple Computer. Inside Macintosh OpenDoc Cookbook, Addison-Wesley, Menlo Park, CA (1996).
[2] Apple Computer. Inside Macintosh OpenDoc Programmer’s Guide, Addison-Wesley, Menlo Park, CA (1996).
[3] Chappell, D., “Simple Object Access Protocol (SOAP) and Firewalls,” Web Page, http://msdn.microsoft.com/xml/ general/soap_white_paper.asp
[4] Coad, P., and P. Mayfield, Java Design, Printice Hall, Upper Saddle River, NJ (1999).
[5] Feghhi, J. Web Developer's Guide to Java Beans, Coriolis Group Books, New York, NY (1997).
[6] Ferrel, P. J., and R. F. Meyer, “Vamp: The Aldus Application Framework,” Proc. ACM OOPSLA, 185-189 (October, 1989).
[7] Fowler, M., Refactoring, Addison-Wesley, Menlo Park, CA (1999).
[8] Fuller, J., and A. Meadow. Essential OpenDoc, Addison-Wesley, Menlo Park, CA (1996).
[9] Gamma, E., R. Helm, R. Johnson, and J. Vlissides, Design Patterns, Addison-Wesley, Menlo Park, CA (1995).
[10] Green, T., “Research Issues of Geometry-Based Visual Languages and Some Solutions,” Ph. D. Dissertation, Arizona State University, Tempe, AZ (1999).
[11] Li, S., and P. Economopoulos, Professional Visual C++ 5 ActiveX/COM Control Programming, Wrox Press, Chicago, IL (1997).
[12] MacBride, A., and J. Susser. Byte Guide to OpenDoc, McGraw-Hill, New York, NY (1996).
[13] Microsoft. “Microsoft Office”, Computer Software, Redmond, WA.
[14] Morrison, M. Presenting Java Beans, Sams, Indianapolis, IN (1997).
[15] Reenskaug, T., and A. L. Skaar, “An Environment for Literate Smalltalk Programming,” Proc. ACM OOPSLA, 337-345 (October, 1989).
[16] Sun Microsystems, “Enterprise JavaBeans Technology,” Web Page, http://java.sun.com/products/ejb/
[17] Sun Microsystems, “Java AWT: Delegation Event Model,” Web Page, http://java.sun.com/products/jdk/1.1/docs/guide/ awt/designspec/events.html
[18] Sun Microsystems, “Java Beans, Part 1,” Web Page, http://developer.java.sun.com/developer/onlineTraining/ Beans/Beans1/simple-definition.html
[19] Sun Microsystems, “Java Studio,” Web Page, http://developer.java.sun.com/developer/Books/ Graphics2/index.html
[20] Sun Microsystems, “Java Technology and XML,” Web Page, http://java.sun.com/xml/index.html
[21] Sun Microsystems, “Keynote Presentation,” Web Page, http://java.sun.com/javaone/javaone96/McNealy.html
[22] Symantec, “Visual Café,” Computer Software, Cupertino, CA.
[23] Vizard, M., “Pull over, Sun; Big Blue’s gonna drive,” InfoWorld, 19(8), 3-4 (Feb, 1997).
[24] W3C, “Extensible Markup Language (XML) 1.0,” Web Page, http://www.w3.org/TR/1998/REC-xml-19980210
Extending Java Beans to support a Compound Document Model: Project Verdantium
Thornton Green
Arizona State University
ABSTRACT
Client-side visual Java Beans are poorly suited to the implementation of document-level software components such as text editors. This reduces the applicability of visually displayed Beans, limiting the client-side API primarily to a means for interchanging widgets between different integrated development environments (IDEs). By using an alternate API (Verdantium) for the embedding of beans in a visual context, clients-side code can implement a full compound document display model while leaving server-side APIs (Enterprise Java Beans) and the fundamental bean property model unchanged. 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. [Java Beans hasn't changed much since this was written; all of this is still true today]
Keywords
Component software, compound-documents, embedding, Java Beans.
1. INTRODUCTION
When Sun introduced the original container application for visually embedded Java Beans [5, 14, 16 18], the Bean Box, it included as sample components a couple of buttons, a molecule viewer, and some other components with a similar level of sophistication. Since then, little has changed. The APIs introduced by the Bean Box have been used as a way to build applications from simpler widgets in a development environment, but have not led to the widespread sharing of visual components between Java applications outside of the software development world. The term “widget” refers to a subclass of java.awt.Component (or its equivalent in another framework). This paper sometimes uses “widget” instead of “component” so that the term “component” can be used in the context of component software.
To understand the problem, one must first answer the question, “what is a Java Bean?” There are three different senses in which the term “Java Beans” tends to be used:
* As a programming standard for specifying “get” methods, “set” methods, property change events, etc [18]. The resulting components can be visually manipulated regardless of whether the have GUIs. For instance, a ComboBoxModel can be manipulated in Symantec Visual Café [22].
* As a server-side API for interacting with transaction environments and legacy code (Enterprise Java Beans) [16].
* As an API (on the client side) for subclasses of java.awt.Component to be read by the Bean Box (or similar program) from a jar file.
It is the latter of the three that creates problems for document embedding. Container applications that emulate the functionality of the BeanBox are difficult to write. Further, pure Java implementations of bean containers have inherent display problems. Many visual beans are “heavyweight” widgets, making it difficult for the pure Java container app. to superimpose a resize widget over the top of the bean.
Support for native or legacy file formats is lacking in the visual beans’ persistence standards. A class written for the Bean Box can serialize itself by implementing one of two interfaces, Serializable or Externalizable. Neither of which can support foreign file formats, unless they are object-based. This means that for example a text editor bean would need a second entirely separate persistence mechanism in order to load or save plain text files saved on the local disk. There is also no built-in mechanism for two beans to support the same persistence format. For instance, a PDF distiller bean can not serialize itself in such a way that the serialized format will be read by the free PDF reader bean when opened. Instead, the identity of the object’s class (in this case the PDF distiller bean) is “hard-coded” into the persistent data. When the file is loaded from persistent storage, the hard-coded class is used to read the object data. [Sun effectively deprecated Externalizable for XML object persistence, and uses a new system for XML. Nevertheless, the above is still true for non-XML formats.]
The way that beans are embedded into a container also presents a number of less fundamental problems that nevertheless present a series of practical difficulties. One of them is the use of subclassing of AWT components (i.e. widgets) to create beans. One of the original articles on the JDK 1.1 event model, [17], states “subclassing should be reserved for circumstances where [AWT] components are being extended in some functional or visual way.” Java Beans do not adhere to this principle. To make a bean that can be displayed in the Bean Box, the developer must subclass a widget regardless of whether she intends to extend the base widget in a functional or visual way. To quote this same page again, subclassing of AWT components “does not lend itself well to maintaining a clean separation between the application model and the GUI because application code must be integrated directly into the subclassed components at some level.” To be fair, the latter quote is referring more to using subclassing to handle events. However, it would also seem to apply to subclassing widgets in order to use them as visual beans. Any methods that talk to an interface implemented by the bean or to the bean’s “get/set” methods must necessarily go through the subclass of the widget, and can not be routed directly to the application code.
Because the APIs for visually displayed beans were created with the assumption that heavyweight widgets could be used, there is no unified API support for beans that are visually transparent. This makes it difficult for a text label bean to overlay (with a transparent background) the display content of a graphics bean with predictable results. Unfortunately, even the most basic presentation software requires this capability from its components. For instance, imagine how ugly a Microsoft Powerpoint presentation with a gradient-filled background would look if all the text labels had individual opaque rectangular backgrounds of a single color. As a practical matter, transparency support is necessary for getting useful results from visual components in a variety of situations.
Multi-page printing also presents a problem from a practical perspective. A Java Bean has one method, print(), with which to print itself into a graphics context. Unlike the APIs generally available to applications, the print() method does not support multi-page printing because it is a widget-level operation as opposed to a document-level operation. This gives the writer of the bean two choices: restrict the bean to something that only prints single pages, or implement a custom set of printing routines entirely separate from the Beans APIs.
The ability to read previous versions of the serialized state of a bean can be difficult to accomplish. The Serializable and Externalizable interfaces attach versioning information to the persistent state of a class based upon the bytecode information of the classes being serialized. If the bytecode of the class changes even slightly, older serialized files are no longer compatible. This can be remedied to an extent by defining the serialVersionUID field of each class. This will make the class able to read serialized information made by any other version of the class using the same serialVersionUID. However, this does not in itself solve the versioning problem. The class must still read a set of objects from a linear stream, attempt to ascertain which version of the software these objects refer to, and employ some type of filter to derive meaningful data from the object stream. Filtering data from a linear stream of objects can be difficult because in general there are no tags indicating what instance member name each object of the stream belongs to. As a result, it may be very difficult to derive the proper meaning from the object stream when two previous versions of the class had similar but not identical formats, and several instance members of the same class. [XML persistence using Serializable no longer seems to be using serialVersionUID.]
2. THE SOLUTION
Verdantium, a prototype API based on a set of software components the author developed to support his Ph. D. dissertation [10], extends client-side beans by implementing a compound-document model for visual components. The idea behind this model is to be able to construct complex documents by having a series of software components (beans) working together to represent the document’s various parts. For instance, a word processor and its equation editor can be separate beans that cooperate to allow the user to insert equations into a paper that she is editing. Instead of having very large monolithic applications as illustrated in Figure 1, a series of smaller beans cooperate to replicate the functionality typically seen in large applications. The construction of documents using components is more flexible because components for editing different parts of a document can be added and/or interchanged.
Figure 1 An example of modern software with all of its toolbars turned on. Taken from a screenshot of a 800 x 600 display. Note the amount of functionality that has been packaged in a single monolithic application.
Verdantium’s document model 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 [7]. Beans that are displayed in the Bean Box are subclasses of a view class, with no inherent support given to the underlying model. The VerdantiumComponent by contrast is a Java interface implemented by the model class, with the GUI stored in a separate object (though one may optionally integrate the two). The major design principles supporting the use of an interface are flexibility and pluggability as noted in [4]. Components based on interfaces are more flexible because they can extend any chosen base class, and they are pluggable in the sense that one implementation of an interface can be replaced by another that uses the same methods. One important aspect of the flexibility of using an interface is that the VerdantiumComponent does not need to subclass a widget. Instead, the user interface of the VerdantiumComponent is the Swing JComponent returned by the VerdantiumComponent’s getGUI() method.
package verdantium;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.*;
public interface VerdantiumComponent extends
EtherEventHandler
{
public JComponent getGUI();
public void handleDestroy();
public DataFlavor[]
getPersistentOutputDataFlavorsSupported( );
public void loadPersistentData( DataFlavor flavor ,
Transferable trans );
public Transferable savePersistentData(
DataFlavor flavor );
}
Figure 2 The definition of a VerdantiumComponent.
The defintion of a VerdantiumComponent is as given in Figure 2, where EtherEventHandler is a Verdantium-defined interface for handling scriptable events. The simplest Verdantium components do not need to handle any such events, and can simply provide a stub implementation of EtherEventHandler’s only method. In addition, a VerdantiumComponent capable of being used in a compound document must have a null constructor, and implement one required method not shown in the listing above. The method’s signature is as follows:
public static DataFlavor[]
getPersistentInputDataFlavorsSupported( )
This method is called at runtime using the Java Reflection API. By studying the interface definition above, one can see that every VerdantiumComponent must do three basic things. It must present a Swing GUI, it must be able to handle its own destruction, and it must be able to support a persistence architecture based on AWT’s Transferable and DataFlavor concepts. Different components implement the same interface, but provide different behaviors. In other words, the interface provides the basis for implementing a Strategy pattern with respect to multi-flavor persistence and GUI presentation [9].
The mandatory use of Swing widgets to implement Verdantium GUIs greatly simplifies the implementation of the overall framework. Heavyweight widgets make certain kinds of controls difficult to implement because the heavyweight widgets tend to display in front of any widget that does not have a peer [This has generally been true since JDK 1.1, but Sun announced during a session at JavaOne 2007 that they wanted to change this. For essentially all current JDK implementations this is still they way Java Z-Orders heavyweight instances of jaav.awt.Component]. Because Swing widgets are entirely lightweight, there are fewer problems to contend with when attempting to design controls that resize or translate the widgets. For example, Swing already provides JDesktopPane and JInternalFrame classes that implement Multiple-Document Interface (MDI) resize controls on other Swing widgets in a robust manner.
2.1 Persistence Support
To support persistent storage, a VerdantiumComponent reads and writes Transferable objects in multiple data flavors. The use of the Transferable object in the loading and storing of persistent states can be thought of as similar to the Memento pattern in [9]. The Transferable object is the Memento, the VerdantiumComponent is the originator, and the persistence system is the Caretaker. The main differences are that the VerdantiumComponent does not have to deal with a constraint solver in the same sense as the systems that served as the motivation for the Memento pattern, and that the VerdantiumComponent contains support for through data flavors for creating Transferable data in multiple formats.
The data flavors that a component can support fall into two general types. The first type is object data intended to be read from or written to a Java object stream. This allows the component to use the standard Java Beans persistence mechanism with Serializable objects. However, there is an important semantic difference between Verdantium’s object serialization and that in client-side beans. Client-side beans tend to serialize data from the widgets they inherit from, including the full view hierarchy. This has two problems. First, Swing widgets tend to store a very large amount of data to persistent storage. Much of this information is of little real use to the overall application. Second, Swing’s persistence format is still under revision as of Java 2. Verdantium components avoid these problems because they serialize the model, not the view. For instance a text editor component serializes the text of the document, not the details of the view hierarchy. There is a drawback in that the Verdantium component has to do more work to load a file than its bean counterpart. Sometimes a component written in Verdantium has to take a representation of a document and map it to an appropriate set of widgets and layout managers, or vice versa . However, the author feels that the benefits outweigh the drawbacks. [In recent versions of Verdantium the format for this has shifted from binary object streams (i.e. class ObjectOutputStream) to XML object streams. Newer versions of Verdantium also contain logic that map most implementations of Externalizable to XML. The author feels that Externalizable is much simpler, more elegant and more object-oriented than Sun's XML callback mechanism, and hence it makes sense to use the XML callback mechanism to bridge Externalizable into the XML format.]
The second general type of data flavor that Verdantium supports is raw data from a file stream. For instance, a text editor can read a standard plain text document as a set of bytes that have been loaded from an input stream. The Verdantium system has the responsibility of mapping the input file to an appropriate MIME type, and then sending this MIME type to the Verdantium component in the form of a DataFlavor object. The surrounding Verdantium system can determine if a component can read a particular file type by calling the getPersistentInputDataFlavorsSupported( ) method and then ascertaining whether the MIME type of the file is a match for one of the MIME types returned.
One drawback of this approach is that loading of persistent data fails if the Verdantium system maps a file to the wrong MIME type. This is similar to what happens in Microsoft Windows if a file extension is mapped to the wrong application. Some care must be taken to make sure that the mappings are complete and correct. Also, the particular mapping scheme that should be used seems to be highly platform-dependent. For instance Windows and Unix distinguish file types by using file extensions, while the Mac OS uses a special four-letter code stored separately from the file name [This has changed now that Mac OS X runs as a Unix variant]. How to unify the mapping schemes of all platforms under a single bytecode implementation is unclear at this time. The current version of the system runs on the Windows platform.
If a particular component is missing, Verdantium can query all other registered components and determine which component(s) can respond to an input file of a particular data flavor. To provide faster indexing, it also uses a series of hash tables to map data flavors to components, and to map file extensions to MIME types. This querying system provides an ability to interchange visual components that is not found in client-side Java Beans. One component can replace another if there is an appropriate mapping of MIME types. This gives developers greater flexibility in deploying components. Consider how Adobe Acrobat has been successful because Acrobat Reader, a free product, is able to read files of the same MIME type as the sold-for-profit Acrobat and Acrobat Distiller. Verdantium can replicate this kind of relationship more readily than client-side Java Beans.
2.2 Verdantium’s User Interface for Embedding
In order to provide appropriate support for embedded documents and take full advantage of JFC/Swing functionality, Verdantium uses a very different user interface than that exemplified by the Bean Box. One of basic problems in any compound document system is that of how the user interface distinguishes between the operations that can be performed on embedded documents. These operations fall into three basic types:
* Resizing the embedded document in the container.
* Translating the embedded document to different positions in the container.
* Editing the embedded document’s content (e.g. drawing onto an embedded paint program using the mouse).
Almost all embedding systems perform the resizing and translating of embedded documents by placing a border around the document that can be dragged with the mouse. Borders have some advantages. Large borders are easy for the user to find and drag with the mouse. They can also have distinct on-screen controls for translating as opposed to resizing. However, borders also have serious drawbacks. The display of borders moves the container document away from a WYSIWYG appearance. Borders also tend to obscure part of the document’s content. This can frustrate people attempting create complex documents because the display of borders while resizing can interfere with the user’s ability to determine whether the embedded component is the “right size” to fit neatly into its surrounding content.
Apple’s OpenDoc [1, 2, 8, 12] system uses two approaches to address this design problem: only place a border around the currently selected component, and use a really thin border. OpenDoc attempted to make resizing versus editing an embedded document as modeless as possible. That is to say, one doesn’t have to select a particular mode from a palette or a pull-down menu in order to switch from resizing to editing or vice versa. However, Apple the lack of modes also meant that there was no way to completely turn the border off. So to compensate for the fact that the selected component will always have a border (with the drawbacks that entails), OpenDoc displays a border that is about four pixels in width for translating the component. The drawbacks of this approach are that the border is very difficult for naïve users to select with the mouse, and is so small that even intermediate users who are not already familiar with OpenDoc would likely not recognize the border as a translation control.
Several container applications such as the BeanBox, Microsoft Office [13], and Symantec Visual Cafe [22] keep the concept that only the selected component has a border displayed for translating and resizing, but use a larger border with individual controls for different kinds of resize operations. The larger borders fix the selection and recognition problems, but make it more difficult to see a document in the context of the surrounding space. Also, the fact that one has to select an embedded component before resizing it creates inherent problems. Suppose the embedded component is a button. Does clicking on the button mean that a button-press event should be sent, or does it mean that the user wants to resize it? So many common components rely on single-click operations that using mouse-click selections to control the display of borders is not entirely practical outside of IDEs, which have separate “Design” and “Execute” modes that determine whether the embedded components respond to the mouse.
Verdantium takes a very different approach to the problem of how to distinguish resizing and translating from the editing of content. The Verdantium approach is based on the MDI window concept, which many users are already familiar with from their use of popular office applications. Translating a document equates to dragging the title bar of the MDI window, and resizing the document is performed by dragging the MDI’s resize control. The MDI control in the typical form found in other software is large enough that users can easily drag it and is familiar enough that users understand what to use it for, but it displays too large a border to work well in a variety of situations. To fix this problem, Verdantium requires that users accept a somewhat modal interface with the associated learning curve. The property editor palettes for the Verdantium container applications provide push-button controls for determining whether or not the MDI frames are displayed around the embedded components. The frames display differently depending on the mode of the pushbutton control (see Figures 3, 4, and 5). At the risk of sounding ridiculous, the author decided to use very simple names for each of the modes (such as “Move Mode”) to avoid names that throw too many long words at the naïve user (such as “Translate Mode”).
Figure 3 Simple components displayed in “Move Mode.”
Figure 4 Simple components displayed in “Resize Mode.”
Figure 5 Simple components displayed in “Edit Mode.”
Verdantium’s container app. MDI frames have one more important difference versus typical MDI implementations: Verdantium frames have transparent backgrounds (see Figure 6). This allows for Verdantium components to be used as semi-transparent overlays in a container application (thanks to Swing’s transparency support). There are a number of compound document scenarios where this is an extremely important capability. For example, the transparency support provides the means to lay text over graphics (see Figure 7). One drawback of this transparency implementation is that the Verdantium code tends to delve deeply into Swing’s Pluggable Look And Feel (PLAF) code in order to produce a subclass of JInternalFrame with the proper border and transparency characteristics. At least for the time being, this results in the container frame being hard-wired for a particular look-and-feel. The Java Look-And-Feel (JLF) is being used for the current implementation [this has since been extended to include Windows and Mac LAFs].
Figure 6 MDI container app. frames in Verdantium have transparent backgrounds, and take advantage of Swing’s transparency support. This allows the document creator to overlay non-rectangular shapes. A component can avoid the use of transparency by drawing an opaque background.
Figure 7 An example of why support for transparency is useful. In this illustration, a graphics component is displaying a curve, and an embedded text component that is rendering text over the top of the graphics. Note how the text is inside the curve, but the resize rectangle of the text component extends outside at the top corners.
2.3 Document-Level Printing Support
Unlike Java Beans, which only provides widget-level printing, Verdantium provides a document-level printing interface called BookPrintable. BookPrintable gives the component total control over the printing process from the time the user selects the “Print” command on the component to the time that the component decides the print operation has concluded. Verdantium also keeps the widget-level printing functionality from AWT / Java Beans. This means that there can be as many as two separate execution paths by which a Verdantium component may be printed (a document path and a widget path). The reason for this is that embedded components need to have a different printing protocol from the component that gets the original request. That is to say, there is a “master” component and there are “slave” components in the printing process, and the slaves (the ones embedded somewhere in the master’s document) do not get all of the privileges of the master. The master gets to select how many pages to print, and what will show up in each page at a document level. The slaves’ responsibility is to respond to calls to their GUIs’ print() method in a reasonable way. In most cases, the default implementations of the print() method supplied by AWT already work well enough to support the slave side of the relationship. The use of multiple paths of execution for printing allows a Verdantium component to properly support printing as either a stand-alone application or an embedded component.
2.4 Versioning
Support for persistent versioning is very important for applications software. Almost all applications have legacy file formats from previous versions of the software, and being able to interrogate these legacy formats in a useful manner helps to convince customers to spend money on regular upgrades. Versioning of serialized objects is also a tremendously difficult problem. Verdantium provides the ability for an Externalizable object to save itself in a more versionable way using an object-oriented version of a property list. The class’ implementation of the writeObject() method of the Externalizable interface creates this property list object, writes a series of objects to the property list with different property names, and then sends the property list down the stream to be serialized. The advantage of the property list is flexibility in dealing with versioning issues. For instance, an object reading persistent information from a property list can query the list to see if certain property names have objects associated with them. Also, different versions of a class can write data to different property names regardless of how or whether the schema of the class changed. The property list can then be interrogated on the read side to determine which set of property names is contained in the list. Another key advantage of the property list is that objects do not have to be read in the same order in which they are written. For instance the writeObject() may write the property for the number of items in a list after the list items because the list was read using an iterator. However, the readObject() method for the same class read the number of items first, and then loop through the property name of each list item using a simple for-next statement. The ability to arbitrarily order the reading of items from the property list greatly aides the ability to perform non-trivial versioning because the schema for the latest version of the class may not be well-suited to reading data in the order saved using previous versions of the class.
It may be useful in a future version of Verdantium to modify the existing property list system to serialize in terms of XML [20, 24]. XML would provide an ASCII representation of the object property files that could be analyzed using a standard text editor. This is a topic for future research. [This has been implemented in more recent versions. Serializing property lists to XML provides the best of both worlds. The file format is standard XML, but the object read/write system has the flexibility of object properties.]
2.5 Creating Actual Components
All of Verdantium’s capabilities would be useless if they made Verdantium components and Verdantium container applications impossible to write. In contrast to the complexity required to replicate the Bean Box, a great deal of work has been put into streamlining the number of lines of code required to construct simple Verdantium components. The Verdantium HelloWorld component currently requires 140 lines of code, including comments (not counting the optional class providing online help). The DemoContainerApp, an example class that demonstrates how to write a simple container application, currently requires 440 lines of code with comments (not counting code for an optional class devoted solely to providing online help).
3. Verdantium as a Document Model
Verdantium was created with the idea that a client-side component should be able to support all the functionality that a typical GUI application does so that the components can have wider applicability. The VerdantiumComponent revises and extends the Beans component model to support these features. Perhaps the most important of these extensions is the expanded support for persistence. Components in Verdantium can read and write files of any MIME type through a Transferable interface, or save and load Serialized objects to persistent storage. Assuming that the Verdantium system can map each file to an appropriate MIME flavor and load the raw data stream into a Transferable object, the component can support any number of file types simultaneously. Multiple components can share the same file type, allowing more flexibility in how they can be distributed. Finally, Verdantium makes it easier for Externalizable objects to be compatible with future versions of the software using alternate persistence formats.
Verdantium supports multi-page printing at the component level, allowing applications such as word processors and illustration programs to be written as components. The AWT widgets’ print() method is also supported for imaging embedded components to a particular rectangular region of the printed page. Some might argue that giving the component total control over multi-page printing makes it incompatible with use in a Java applet. However, multi-page printing can not be allowed in any form from an applet because an errant applet can request an arbitrarily large number of pages. Hence, the applet’s security manager simply would not allow a print request to be fully processed. Moreover, the browser can still perform widget-level printing of the applet through the standard interface. [This point is moot now that newer versions of IE have made it very difficult to write an HTML block that executes the Java Plug-In across all browsers (e.g. removing support for Netscape plugins). Applets are probably dead, and Verdantium is now really a framework for Java applications, and components pulled in from the network through the Verdantium Discovery system. Verdantium Discovery is probably a lot more reliable than using Applets anyway.]
Verdantium components can be used to build compound documents. Complete container applications can be written as Verdantium components in significantly less than 1000 lines of code, and structured using a robust MVC architecture. Because Verdantium code is based on Swing and the container functionality is based on JDesktopPane, the resulting GUIs are both stable and easy to use. Hopefully this will lead to a larger number of container implementations to be included with general-purpose applications such as illustration programs. Embedded components can fully utilize Swing’s support for transparency, allowing embedded components to act as transparent overlays.
One might argue that Verdantium is not compatible with many IDEs because of the techniques they use for building GUIs visually. The visual builders of many IDEs express GUI code in terms of the subclassing of java.awt.Container (or some subclass thereof), which is precisely what Verdantium was designed to avoid. In this case, there are two approaches that one might use. First, allow the model class and the view class to merge. That is to say, have the generated view class implement VerdantiumComponent. This isn’t a perfect solution, but it can work. The second is to express the entire GUI in terms of UI panes, and have each VerdantiumComponent create an instance of the appropriate IDE-generated UI pane class as a member and then return it using the getGUI() method. The disadvantage of this approach is that it may produce a series of independent pane classes where none may be necessary.
4. RELATED WORK
In many ways the environment that is architecturally the most similar to Verdantium is Apple’s now-defunct OpenDoc [1, 2, 8, 12] project. OpenDoc was a cross-platform compound-document model implemented using IBM’s System Object Model (SOM). OpenDoc components were typically written in a language such as C or C++ with a binding that allowed them to be compatible with SOM’s more sophisticated object model. The need to communicate with a separate object model through an API created extra work for the programmer and made components more difficult to write. Also, typical OpenDoc components on the Macintosh platform did not use a set of layout managers to automate GUI interactions as is often done with JFC/Swing or X-Motif widgets. For instance instead of using the equivalent of a JScrollPane to manage the GUI of a document, many OpenDoc components would have code to respond to each individual scroll bar action. This further contributed to the complexity of constructing workable OpenDoc implementations.
Among OpenDoc’s notable features were its cross-component scripting architecture, its support for embedded components, and its ability to have a component read and write files to arbitrary formats while still supporting embedding. One problem with OpenDoc was a lack of memory-protection to keep errant objects from overwriting each other. In particular, on the Mac platform there was no memory protection at all. On other platforms, components were protected from each other, but the objects that comprise a component could still compromise each other in that component’s memory space. Contrast this with the Java VM, where objects are not allowed to clobber each others’ memory. OpenDoc’s lack of memory protection meant that a single ill-behaved component could crash other components in a document, seriously affecting the robustness of the architecture. OpenDoc is no longer supported by its original vendors, and very little development of new OpenDoc components has been done in the past two years.
Java Beans [5, 14 16, 18], the standard component architecture for Java, is more robust than OpenDoc in the sense that the Java VM prevents ill-behaved objects from clobbering each other. Moreover, Java Beans are easier to write in many ways because the Beans object model is the same as that for the Java language. The use of Java layout managers automates many of the more complex tasks related to the GUI, allowing the developer to focus on those events that actually affect the domain logic of the component. The problems with client-side beans were discussed earlier in the paper. For the sake of brevity, they are not repeated here.
Object Linking and Embedding (OLE) is Microsoft’s environment for creating compound documents in the form of custom controls with a WYSIWYG appearance [11]. OLE uses Microsoft’s COM object model to provide an interface mechanism for components to communicate. Like OpenDoc’s SOM model, COM components are written in a language like C or C++ with wrappers that allow them to work in the COM model. OLE components also require a host application to support their display. Microsoft Office applications use OLE as a means to interoperate. ActiveX, a close cousin of OLE, provides an architecture for controls to be displayed on the web.
Aldus developed the Vamp environment as a compound-document implementation designed to streamline the development and maintenance of software components within the company, and to aid in the porting of code between the Macintosh and Windows platforms [6]. The architecture of Vamp was based on Model-View-Controller with the use of event-driven state machines to alter component states. Vamp allowed large programming teams at Aldus to be divided into smaller groups working on individual components. Reenskaug and Skaar [15] developed a documentation environment with a number of compound-document capabilities, and with the additional ability to collapse part of a document. Embedded components included class and method definitions. Netscape worked on a compound document extension to Java Beans two years ago [23]. However, little information has been released about this project.
Faustini’s Visual Java, an early ancestor of the Bean Box, provided a purely visual environment for building GUIs in a container application as mentioned in [21]. Not only were the GUIs visually built, but the algorithms tied to the GUI actions were also built from visual components. Visual Java used a data model based on the programming language Lucid expressed using an operator net concept. Each operator in the net was capable of running on independent threads of execution and could potentially operate in either a deterministic or nondeterministic fashion. The name “Visual Java” is now used for a different product. The closest environment to Faustini’s Visual Java today is Java Studio [19].
Improved persistence models for Java Beans have recently become a topic of much interest. One persistence standard seeing increasing use is XML [20, 24]. XML is an HTML-based language for representing object-oriented data [This sentence was one of the major reasons why the paper got rejected. Should I have written "HTML-like" instead of "HTML-based"? Should I have written "SGML-based" instead of "HTML-based"? Both HTML and XML owe their lineage to SGML. SGML is a meta-language that doesn't describe a particular format (i.e. how to define tags). HTML defines a format for part of SGML. XML also defines a format for part of SGML, and defines the tag format (e.g. use of angle brackets for tags) the same as HTML. As a result, XML loads directly into many browsers designed for HTML, but the browsers simply don't recognize the content of the tags. So XML was IMHO based on many tag format concepts from HTML, but the paper got rejected anyway.]. Objects are represented in XML by a set of tags that describe the states of each of the objects’ members. The XML format also provides a means to support versioning. A program can accomplish this by parsing the XML data to interrogate its format, and then converting the old format to match that required by the current software. One of the advantages of XML is that it is not dependent on a particular object model. XML data can be read and written by systems outside the Java architecture such as relational databases. Because XML is HTML-based, XML parsers can not read or write formats such as non-HTML plain text files or images. [As noted before, Verdantium now persists objects in XML].
XML can be used in a variety of applications. An example of XML’s flexibility is the Simple Object Access Protocol (SOAP) which uses XML as the basis of a wire format for remote method invocation using HTTP [3]. The Java implementation of SOAP has some architectural similarities to Verdantium in the sense that they both use Java interfaces as opposed to base classes to represent the fundamental object types of the system. The element types in SOAP are implemented using an interface hierarchy to provide the methods supported by each type of SOAP data. Instead of the properties list metaphor used by Verdantium, SOAP represents data as a linked collection of structured types: arrays, simple types, compound records, and object references. [It could be said that XML describes "nouns and verbs" but it doesn't describe any kind of "vocabulary". As a result, Verdantium has classes that scan the format of the XML file, and then determine which component should load it. In a sense, it answers the question, "which component speaks in this vocabulary?"]
5. ACKNOWLEDGMENTS
The author would like to thank all the people who made helpful suggestions about the architecutre: Dr. Edward Ashcroft, Dr. Timothy Lindquist, Dr. David O. Hestenes, Dr. David Halliday, Al Butkus, Pat Reany, and Dwain Desbien. I would also like to thank Dr. Tony Faustini, without whom I may never have discovered the Java language.
6. REFERENCES
[1] Apple Computer. Inside Macintosh OpenDoc Cookbook, Addison-Wesley, Menlo Park, CA (1996).
[2] Apple Computer. Inside Macintosh OpenDoc Programmer’s Guide, Addison-Wesley, Menlo Park, CA (1996).
[3] Chappell, D., “Simple Object Access Protocol (SOAP) and Firewalls,” Web Page, http://msdn.microsoft.com/xml/ general/soap_white_paper.asp
[4] Coad, P., and P. Mayfield, Java Design, Printice Hall, Upper Saddle River, NJ (1999).
[5] Feghhi, J. Web Developer's Guide to Java Beans, Coriolis Group Books, New York, NY (1997).
[6] Ferrel, P. J., and R. F. Meyer, “Vamp: The Aldus Application Framework,” Proc. ACM OOPSLA, 185-189 (October, 1989).
[7] Fowler, M., Refactoring, Addison-Wesley, Menlo Park, CA (1999).
[8] Fuller, J., and A. Meadow. Essential OpenDoc, Addison-Wesley, Menlo Park, CA (1996).
[9] Gamma, E., R. Helm, R. Johnson, and J. Vlissides, Design Patterns, Addison-Wesley, Menlo Park, CA (1995).
[10] Green, T., “Research Issues of Geometry-Based Visual Languages and Some Solutions,” Ph. D. Dissertation, Arizona State University, Tempe, AZ (1999).
[11] Li, S., and P. Economopoulos, Professional Visual C++ 5 ActiveX/COM Control Programming, Wrox Press, Chicago, IL (1997).
[12] MacBride, A., and J. Susser. Byte Guide to OpenDoc, McGraw-Hill, New York, NY (1996).
[13] Microsoft. “Microsoft Office”, Computer Software, Redmond, WA.
[14] Morrison, M. Presenting Java Beans, Sams, Indianapolis, IN (1997).
[15] Reenskaug, T., and A. L. Skaar, “An Environment for Literate Smalltalk Programming,” Proc. ACM OOPSLA, 337-345 (October, 1989).
[16] Sun Microsystems, “Enterprise JavaBeans Technology,” Web Page, http://java.sun.com/products/ejb/
[17] Sun Microsystems, “Java AWT: Delegation Event Model,” Web Page, http://java.sun.com/products/jdk/1.1/docs/guide/ awt/designspec/events.html
[18] Sun Microsystems, “Java Beans, Part 1,” Web Page, http://developer.java.sun.com/developer/onlineTraining/ Beans/Beans1/simple-definition.html
[19] Sun Microsystems, “Java Studio,” Web Page, http://developer.java.sun.com/developer/Books/ Graphics2/index.html
[20] Sun Microsystems, “Java Technology and XML,” Web Page, http://java.sun.com/xml/index.html
[21] Sun Microsystems, “Keynote Presentation,” Web Page, http://java.sun.com/javaone/javaone96/McNealy.html
[22] Symantec, “Visual Café,” Computer Software, Cupertino, CA.
[23] Vizard, M., “Pull over, Sun; Big Blue’s gonna drive,” InfoWorld, 19(8), 3-4 (Feb, 1997).
[24] W3C, “Extensible Markup Language (XML) 1.0,” Web Page, http://www.w3.org/TR/1998/REC-xml-19980210
Thursday, September 6, 2007
New Verdantium Version -- 0906
I did a lot of work over labor day, particularly on the JUndo Runtime. Here is what's in the latest version:
JUndo Runtime-- Fixed a series of issues in the runtime, particularly memory reclamation. Much of the original finalizzation code has been fixed, and turned back on. This is to say, the code that actually reclaims milieux after a garbage collection run has been turned on again. The JUndo Runtime actually gets faster after it has garbage-collected milieux, so this should provide large performance improvements for some operations. In addition, a number of C++-isms have been removed from the code.
I think this is a huge change in the grand scheme of things. It makes the undo system much more efficient, particularly for very large programs. This was one of the last serious bugs I have observed in the runtime, and fixing it brings the runtime much closer to moving to a pre-alpha or alpha state. It also gives people who read code an idea of how the runtime is supposed to manage memory when fully implemented. In most programs, the vast majority of milieux are garbage-collected, and hance only the remaining milieux should contribute to the performance of milieux lookups by the runtime. This goes a long way toward demonstrating how JUndo classes can be efficient.
Verdantium-- A series of new features has been added to the DrawApp drawing application such as the ability to erase individual rendering primitives. I focused on DrawApp operations that are relatively easy to do, but relatively difficult for non-temporal systems to undo. I think the new DrawApp code makes a very strong case for temporal undo, particularly with the new refinements to the JUndo Runtime described above.
Poseidon Sourceforge Package of Verdantium-- Poseidon shows how to create a small, useful component that can be embedded in other components (or run standalone), provide macro-scripting, support multi-level undo, be printable, display page setup and print preview windows, have a reasonable user interface (although without pretty icons), load/save files in a fairly compact XML format, provide illustrated online help, and fit within a .jar footprint of a little less than 100K. This will provide a template for third parties to add their own custom components to the Verdantium system. Different components can be compiled seperately from each other and then dynamically linked into the Verdantium system using Discovery. In terms of content, this component is a simple ripple-tank simulator for educational use in entry-level (e.g. high school) physics classes. It allows one to specify simple wave positions, frequencies, relative amplitudes, etc. and then see how the waves interfere. The underlying algorithm provides a very quick-and-dirty approximation of wave effects, and isn't guaranteed to be accurate in all circumstances (it chooses speed over accuracy). This release resolves symbols that changed due to the recent refactoring of Meta.
JUndo Runtime-- Fixed a series of issues in the runtime, particularly memory reclamation. Much of the original finalizzation code has been fixed, and turned back on. This is to say, the code that actually reclaims milieux after a garbage collection run has been turned on again. The JUndo Runtime actually gets faster after it has garbage-collected milieux, so this should provide large performance improvements for some operations. In addition, a number of C++-isms have been removed from the code.
I think this is a huge change in the grand scheme of things. It makes the undo system much more efficient, particularly for very large programs. This was one of the last serious bugs I have observed in the runtime, and fixing it brings the runtime much closer to moving to a pre-alpha or alpha state. It also gives people who read code an idea of how the runtime is supposed to manage memory when fully implemented. In most programs, the vast majority of milieux are garbage-collected, and hance only the remaining milieux should contribute to the performance of milieux lookups by the runtime. This goes a long way toward demonstrating how JUndo classes can be efficient.
Verdantium-- A series of new features has been added to the DrawApp drawing application such as the ability to erase individual rendering primitives. I focused on DrawApp operations that are relatively easy to do, but relatively difficult for non-temporal systems to undo. I think the new DrawApp code makes a very strong case for temporal undo, particularly with the new refinements to the JUndo Runtime described above.
Poseidon Sourceforge Package of Verdantium-- Poseidon shows how to create a small, useful component that can be embedded in other components (or run standalone), provide macro-scripting, support multi-level undo, be printable, display page setup and print preview windows, have a reasonable user interface (although without pretty icons), load/save files in a fairly compact XML format, provide illustrated online help, and fit within a .jar footprint of a little less than 100K. This will provide a template for third parties to add their own custom components to the Verdantium system. Different components can be compiled seperately from each other and then dynamically linked into the Verdantium system using Discovery. In terms of content, this component is a simple ripple-tank simulator for educational use in entry-level (e.g. high school) physics classes. It allows one to specify simple wave positions, frequencies, relative amplitudes, etc. and then see how the waves interfere. The underlying algorithm provides a very quick-and-dirty approximation of wave effects, and isn't guaranteed to be accurate in all circumstances (it chooses speed over accuracy). This release resolves symbols that changed due to the recent refactoring of Meta.
Labels:
garbage collection,
JUndo Runtime,
milieu,
milieux,
Verdantium
Tuesday, August 28, 2007
DocPrinter package added to Verdantium -- 0828 ; Printing
This has been a busy week. I completed the century (100 mile) bicycle ride in the Tour De Cure in Longmont, Colorado on Sunday. It's a charity event to support Diabetes research. At the same time, I also got Tour De France winner Greg LeMond's autograph (yeah!). Coding this week has been delayed by all of the fun.
One of the visions that I've had for Verdantium is to make it a system for high-quality and resolution-independent printing. I've always wanted Verdantium to provide better printing APIs than those provided by Java Beans. The Java Beans framework primarily has the component (the bean) print on a single page by overriding the print() method of the java.awt.Component class. Java provides an AWT Printable interface with multi-page printing capability, but strangely Java Beans does nothing to detect or utilize a bean that implements the interface.
Verdantium provides direct support for a variety of printable components and printing scenarios. In the simplest case, a component may be embedded in the one doing the printing (e.g. a picture component in a word processing document). In this case, the typical print() method in java.awt.Component will be used.
If the component being printed is the top-level embedding component of the print job, then the following steps will be performed:
* First, Verdantium will determine if the callee implements the Verdantium BookPrintable interface. If this is the case, then BookPrintable will be used. BookPrintable is the most versatile interface, but is probably too heavyweight for most components.
* Second, if the component does not implement BookPrintable, Verdantium will determine if the callee implements the AWT Printable interface. If so, then Verdantium will work through the Printable methods, and potentially print on multiple pages. Most components that print on multiple pages will probably utilize this option.
* Third, if neither Printable nor BookPrintable are implemented by the callee, then Verdantium will use the print() method on the component's GUI.
For the typical multi-page component implementing Printable, Verdantium will automatically generate Print Preview windows, show Page Setup dialogs, work with the Swing RepaintManager, etc. Ditto for simple single-page components that don't implement Printable. BookPrintable is only useful of one wants to implements one's own PrintPreview GUI and/or one finds design issues having the Verdantium component directly implement Printable (i.e. sometimes it makes more sense for the Printable to be a separate class).
I think the support for Printable and BookPrintable makes Verdantium's printing significantly different from that in Java Beans, and creates possibilities for document automation (i.e. automated printing) that aren't possible in the Beans framework. To demonstrate this, I added a new component package called DocPrinter to the Verdantium project on Sourceforge. DocPrinter is a simple component that prints other components through a common interface. This includes components that print on multiple pages.
During the testing of DocPrinter I also noticed a series of Verdantium bugs that were created by some of the new multi-level undo improvements. Hence I posted a new Verdantium version, 0828, on Sourceforge that closes some issues that had to be fixed in order to make DocPrinter work with certain documents.
Like the EventViewer component posted earlier, DocPrinter is best used by first launching Verdantium ProgramDirector, and then loading DocPrinter's .xnl file through the Discovery component.
All of the Verdantium's printing frameworks use the Java Foundation Classes (JFC) Java-2D APIs. Java-2D uses resolution-independent coordinates, and should be able to take advantage of any high resolution (i.e. 300 DPI and above) printer. The specification for Java-2D was written by the same company (Adobe) that created PostScript, Display PostScript, and Adobe Illustrator. There are two issues to keep in mind with Java-2D. First, Java-2D can display characters with completely different font metrics depending on whether anti-aliased rendering is utilized. Second, Java-2D has been equivocal about the pixelation limits of its rendering.
Pixelation limits have dogged high-resolution rendering for decades-- long before Java existed. The original Mac used 16 bit pixel coordinates that extended from -32K to +32K. Different implementations of Win32 APIs have had different pixelation limits. If my recollection serves, Win95 had 16-bit pixel coordinates, whereas Win NT 4.0 had 32-bit coordinates. Different versions of Java-2D have had different coordinates sizes. On Windows, Sun JDK 1.2.2 and JDK 1.3 had coordinates that extended completely across the floating-point space. This later got truncated by Sun to smaller coordinates. Then Sun accepted a bug number to bring the larger coordinates back. If trying to make something work on multiple platforms and multiple JDK versions than one should probably assume truncated coordinates.
Nevertheless, Java-2D is a very sophisticated API and Verdantium takes full advantage of it. It should be possible to build some very powerful printing capabilities using Verdantium and Java-2D.
One of the visions that I've had for Verdantium is to make it a system for high-quality and resolution-independent printing. I've always wanted Verdantium to provide better printing APIs than those provided by Java Beans. The Java Beans framework primarily has the component (the bean) print on a single page by overriding the print() method of the java.awt.Component class. Java provides an AWT Printable interface with multi-page printing capability, but strangely Java Beans does nothing to detect or utilize a bean that implements the interface.
Verdantium provides direct support for a variety of printable components and printing scenarios. In the simplest case, a component may be embedded in the one doing the printing (e.g. a picture component in a word processing document). In this case, the typical print() method in java.awt.Component will be used.
If the component being printed is the top-level embedding component of the print job, then the following steps will be performed:
* First, Verdantium will determine if the callee implements the Verdantium BookPrintable interface. If this is the case, then BookPrintable will be used. BookPrintable is the most versatile interface, but is probably too heavyweight for most components.
* Second, if the component does not implement BookPrintable, Verdantium will determine if the callee implements the AWT Printable interface. If so, then Verdantium will work through the Printable methods, and potentially print on multiple pages. Most components that print on multiple pages will probably utilize this option.
* Third, if neither Printable nor BookPrintable are implemented by the callee, then Verdantium will use the print() method on the component's GUI.
For the typical multi-page component implementing Printable, Verdantium will automatically generate Print Preview windows, show Page Setup dialogs, work with the Swing RepaintManager, etc. Ditto for simple single-page components that don't implement Printable. BookPrintable is only useful of one wants to implements one's own PrintPreview GUI and/or one finds design issues having the Verdantium component directly implement Printable (i.e. sometimes it makes more sense for the Printable to be a separate class).
I think the support for Printable and BookPrintable makes Verdantium's printing significantly different from that in Java Beans, and creates possibilities for document automation (i.e. automated printing) that aren't possible in the Beans framework. To demonstrate this, I added a new component package called DocPrinter to the Verdantium project on Sourceforge. DocPrinter is a simple component that prints other components through a common interface. This includes components that print on multiple pages.
During the testing of DocPrinter I also noticed a series of Verdantium bugs that were created by some of the new multi-level undo improvements. Hence I posted a new Verdantium version, 0828, on Sourceforge that closes some issues that had to be fixed in order to make DocPrinter work with certain documents.
Like the EventViewer component posted earlier, DocPrinter is best used by first launching Verdantium ProgramDirector, and then loading DocPrinter's .xnl file through the Discovery component.
All of the Verdantium's printing frameworks use the Java Foundation Classes (JFC) Java-2D APIs. Java-2D uses resolution-independent coordinates, and should be able to take advantage of any high resolution (i.e. 300 DPI and above) printer. The specification for Java-2D was written by the same company (Adobe) that created PostScript, Display PostScript, and Adobe Illustrator. There are two issues to keep in mind with Java-2D. First, Java-2D can display characters with completely different font metrics depending on whether anti-aliased rendering is utilized. Second, Java-2D has been equivocal about the pixelation limits of its rendering.
Pixelation limits have dogged high-resolution rendering for decades-- long before Java existed. The original Mac used 16 bit pixel coordinates that extended from -32K to +32K. Different implementations of Win32 APIs have had different pixelation limits. If my recollection serves, Win95 had 16-bit pixel coordinates, whereas Win NT 4.0 had 32-bit coordinates. Different versions of Java-2D have had different coordinates sizes. On Windows, Sun JDK 1.2.2 and JDK 1.3 had coordinates that extended completely across the floating-point space. This later got truncated by Sun to smaller coordinates. Then Sun accepted a bug number to bring the larger coordinates back. If trying to make something work on multiple platforms and multiple JDK versions than one should probably assume truncated coordinates.
Nevertheless, Java-2D is a very sophisticated API and Verdantium takes full advantage of it. It should be possible to build some very powerful printing capabilities using Verdantium and Java-2D.
Thursday, August 23, 2007
Added EventViewer package to Verdantium
Posted EventViewer, a component that acts as a debugging tool for watching event traffic moving through the Verdantium system.
To use EventViewer, one probably wants to load it into an existing system through the Verdantium Discovery component. Discovery allows one to discover Verdantium components over the network in a manner similar to how network printers are discovered in most modern operating systems.
Unlike Sun's older Applet concept, discovered components don't have a security model. One needs to make sure to only discover components from trusted sources (probably from within one's own network). However, the lack of a security model is very advantageous. A discovered component has full access to the computer on which it is running, and this makes life a lot easier. Want to write to a file? Just select "Save." Want to print? Just select "Print." You get the idea.
The procedure for loading EventViewer through Discovery is as follows:
* Drop EventViewer.jar and EventViewer_14.xnl into the same directory.
* Launch the verdantium.ProgramDirector class from Verdantium.
* Click the "Run..." button, select the "New" tab from the resulting editor, select the "Discovery" component from the "New" tab list, and then click the "Apply" button.
* The Discovery component will launch in a separate window. Click the "Choose File" button, and then navigate and select the "EventViewer_14.xnl" file from the file chooser. The "Event Viewer" listing will then be added to the bottom of the list of components under the Program Director's "New" tab.
* Select the newly added "Event Viewer" item under the Program Director's "New" tab, and click the "Apply" button. The Event Viewer will be launched. Subsequent Program Director actions will be shown in the Event Viewer.
Using the URL option of the Discovery component, this same procedure works over HTTP. This makes it possible to dynamically load Verdantium components over the network. Try it.
To use EventViewer, one probably wants to load it into an existing system through the Verdantium Discovery component. Discovery allows one to discover Verdantium components over the network in a manner similar to how network printers are discovered in most modern operating systems.
Unlike Sun's older Applet concept, discovered components don't have a security model. One needs to make sure to only discover components from trusted sources (probably from within one's own network). However, the lack of a security model is very advantageous. A discovered component has full access to the computer on which it is running, and this makes life a lot easier. Want to write to a file? Just select "Save." Want to print? Just select "Print." You get the idea.
The procedure for loading EventViewer through Discovery is as follows:
* Drop EventViewer.jar and EventViewer_14.xnl into the same directory.
* Launch the verdantium.ProgramDirector class from Verdantium.
* Click the "Run..." button, select the "New" tab from the resulting editor, select the "Discovery" component from the "New" tab list, and then click the "Apply" button.
* The Discovery component will launch in a separate window. Click the "Choose File" button, and then navigate and select the "EventViewer_14.xnl" file from the file chooser. The "Event Viewer" listing will then be added to the bottom of the list of components under the Program Director's "New" tab.
* Select the newly added "Event Viewer" item under the Program Director's "New" tab, and click the "Apply" button. The Event Viewer will be launched. Subsequent Program Director actions will be shown in the Event Viewer.
Using the URL option of the Discovery component, this same procedure works over HTTP. This makes it possible to dynamically load Verdantium components over the network. Try it.
Saturday, August 18, 2007
New Verdantium Version -- 0818 ; Book "Beyond Java"
I think I now have a fully working (except for bugs) version of undoable verdantium.standard.DrawApp. All of the persistence code is in now. I have done some smoke tests on the persistence, and it seems to work. This should be the full implementation.
In addition to Verdantium, one also needs the latest versions of Meta and the JUndo Runtime for this to build and work.
All I need to do with this now is fix bugs, documentation quirks (e.g. lack of copyright headers), and other small issues. I also might want to make some of the code more elegant, but that's an issue for later.
On a completely separate note, I purchased an interesting book this morning: "Beyond Java" by Bruce A. Tate (O'Reilly). On one hand, I applaud this book for raising the question of what is beyond Java. I think there are issues that Java and C# don't address. I had to write JUndo in order to address some of these issues. However, I am completely perplexed by how the author selected which languages were important, and which languages were not important. The book considers Python, Ruby, Groovy, and .NET (mostly C#) as major contenders for next generation languages. AspectJ only gets ONE SENTENCE in the entire book. The author doesn't even consider whether the next major programming language might be aspect-oriented. AspectJ deserved much more than one sentence of mention from this book.
I think Java has a few more years in it, particularly since many Java developers haven't even upgraded to JDK 1.5 and generics yet. Nevertheless, the time has come to think about what's next after Java and OOP. The idea for the book was great, but the book's implementation of that idea left me wanting more. One can find several projects on either Wikipedia or Sourceforge that seem significant, but get no mention in the book. For instance the language Pizza was never widely adopted, but was tremendously successful in demonstrating how generics could be added to the Java language. JDK 1.5's generics probably owe something to the Pizza language. Languages that never get wide adoption can be very important in defining the future of programming, and I wish this book would have included many more obscure languages.
In addition to Verdantium, one also needs the latest versions of Meta and the JUndo Runtime for this to build and work.
All I need to do with this now is fix bugs, documentation quirks (e.g. lack of copyright headers), and other small issues. I also might want to make some of the code more elegant, but that's an issue for later.
On a completely separate note, I purchased an interesting book this morning: "Beyond Java" by Bruce A. Tate (O'Reilly). On one hand, I applaud this book for raising the question of what is beyond Java. I think there are issues that Java and C# don't address. I had to write JUndo in order to address some of these issues. However, I am completely perplexed by how the author selected which languages were important, and which languages were not important. The book considers Python, Ruby, Groovy, and .NET (mostly C#) as major contenders for next generation languages. AspectJ only gets ONE SENTENCE in the entire book. The author doesn't even consider whether the next major programming language might be aspect-oriented. AspectJ deserved much more than one sentence of mention from this book.
I think Java has a few more years in it, particularly since many Java developers haven't even upgraded to JDK 1.5 and generics yet. Nevertheless, the time has come to think about what's next after Java and OOP. The idea for the book was great, but the book's implementation of that idea left me wanting more. One can find several projects on either Wikipedia or Sourceforge that seem significant, but get no mention in the book. For instance the language Pizza was never widely adopted, but was tremendously successful in demonstrating how generics could be added to the Java language. JDK 1.5's generics probably owe something to the Pizza language. Languages that never get wide adoption can be very important in defining the future of programming, and I wish this book would have included many more obscure languages.
Labels:
AspectJ,
Beyond Java,
JUndo,
multi-level undo,
persistence,
Verdantium
Monday, August 13, 2007
Object Models, Google, and Star Office
According to "The Haskell School of Expression" by Paul Hudak, "Java's recent astonishing rise in popularity is rather perplexing on one hand, yet quite understandable on another. As a language, it is simple and elegant, but certainly not revolutionary." The syntax of Java is similar to C and C++ and there are semantic similarities (hence Java's not revolutionary), but this does not explain why Java was successful or what should be done next.
C++ preceded Java, but C++ objects were basically C structures with added intelligence. Objects in the C++ runtime did not retain their identity. For instance, there was no way to introspect the objects generated by the early C++ compilers such as cfront.
Document object frameworks such as Apple's OpenDoc and Microsoft's Object Linking and Embedding (OLE) required objects with a built-in identity that could be dynamically linked. Objects for these frameworks needed to be separately compiled, and loaded at runtime. Microsoft solved this problem with the Microsoft Common Object Model (COM). Apple's OpenDoc used IBM's System Object Model (SOM), which was an implementation of the Common Object Request Broker Architecture (CORBA).
Typical CORBA development had the programmer produce Interface Definition Language (IDL) bindings to a standard language such as C or C++. This required the production of several entities such as IDL stubs, IDL skeletons, etc. Introspection in CORBA required the use of a Dynamic Invocation Interface (DII) in which dynamic requests were built through a long series of C-like API calls. The CORBA code then had to be submitted to an Object Request Broker (ORB). This made OpenDoc programming a labor-intensive process. Apple tried to solve this problem by creating a "Direct-To-SOM" compiler that would take C++ class definitions and compile them into CORBA objects.
Java appeared at the perfect time and it succeeded where Direct-To-SOM failed-- it provided a simple, straightforward language for building CORBA-like objects. The objects ran in a Virtual Machine (VM), but the VM acted much like an ORB. Later, Sun published a Introspection API for Java that made CORBA DII look like a cumbersome dinosaur.
Java quickly became the perfect language for writing an OpenDoc-like component model. An early pioneer in this realization was one of my former ASU professors: Tony Faustini. Faustini taught computer language courses at Arizona State, and two of his passions were visual languages and functional programming. When Sun announced Java and Applets to the world, Faustini immediately understood the implications. Very early in the history of the language, around the time when Sun was releasing Beta Applet APIs for the upcoming Java 1.0, he did something that I wouldn't fully appreciate until much later. He apparently found the Java ClassLoader APIs, and used them to build a container that loaded a series of visual components on startup. As it went through the loading process it displayed the loaded components in a progress bar-- much like the one Photoshop used when loading plugins on startup. The result was called Visual Java (not to be confused with the commercial product that is currently being called Visual Java). Visual Java could best be described as a GUI builder using an operator-net representation of the programming language Lucid, where the operator-net entities were dynamically loaded at runtime through a ClassLoader.
Through some promotional efforts by Faustini, Visual Java soon found its way to Sun Microsystems and Java evangelist Miko Matsumura. There is an early Java-related telecast with Miko Matsumura and Sun engineer John Gage where Miko used Visual Java to first make an animated dog run forward and then run backward. I developed a MacDraw-like component for Visual Java called Fresco. Verdantium was influenced by all of this.
To make a long story short, part of Visual Java wound up in Sun's BeanBox container for Java Beans. Part of Visual Java wound up in a Sun product called Java Studio. Java Studio seems very far removed from Tony's original vision. I don't know what, if anything, happened to Fresco. In a sense Visual Java turned into Java Beans, and then Java Beans integrated, after many travails, into systems like Star Office.
Suffice it to say I found it interesting when Google today announced it was going to start bundling Star Office with its products. I think Google is starting to understand reality-- they've realized that they aren't going to do everything with web applications and AJAX. I also have doubts about whether Star Office will be a success against Microsoft Office.
Microsoft Office is the McDonalds Happy Meal of the software industry. It is a single monolithic box packed with a hamburger (Microsoft Word), french fries (Microsoft PowerPoint), a soft drink (Microsoft Excel), and a toy (Microsoft Access). Microsoft produces lots of them with enormous economies of scale, and they're all pretty much the same. Star Office is trying to be the cheaper Happy Meal, or the more agile Happy Meal, or the more international Happy Meal, or the Happy Meal that is available in more places, etc. It's hard to imagine any of Star Office's marketing slogans really working, particularly if Microsoft tried to marginalize Star by cutting the price of MS Office. It's hard to make a big monolithic box better than Microsoft. Star seems to be trying to make something a lot like MS Office, and generally seems to be trying to beat Microsoft as its own game. As a strategy, this doesn't seem to be smart.
To compete with Microsoft, Google and Sun need to address the big truth that Microsoft ignores: most people don't want Happy Meals. As Simon Phipps stated during the 2007 JavaOne conference, people want to go to a buffet table where they are free to choose what suits their tastes. That is to say, the Java community needs to develop framework technologies that can be used to leverage the best talents of the Open Source community. Different people want different application suites. Ever notice how Adobe's application suite (i.e. Photoshop, Illustrator, etc.) looks very different from Microsoft's? Observe: Adobe doesn't even provide a spreadsheet. This shows the kinds of choices that people want from their "buffet table." Some people want Photoshop instead of Microsoft Paint (or vice versa). Some people want a page layout program instead of a word processor. Some people want Gantt charts built directly into the suite, and other people would rather not have to drag all of that code through their CPUs like a boat anchor.
Unlike the typical Microsoft offerings, Java is a language that can make the buffet table work. Tony Faustini demonstrated years ago how how to write code that can put the various items on the table at runtime. It's one of the main reasons why Java has been successful as a language. Choice is a fundamental human desire, and it's a desire that Microsoft doesn't satisfy. An open framework providing choice fully utilizes the best strengths of the Java programming language. Instead of another Happy Meal called Star Office with pre-configured applications, Google and Sun should be providing the full buffet table.
C++ preceded Java, but C++ objects were basically C structures with added intelligence. Objects in the C++ runtime did not retain their identity. For instance, there was no way to introspect the objects generated by the early C++ compilers such as cfront.
Document object frameworks such as Apple's OpenDoc and Microsoft's Object Linking and Embedding (OLE) required objects with a built-in identity that could be dynamically linked. Objects for these frameworks needed to be separately compiled, and loaded at runtime. Microsoft solved this problem with the Microsoft Common Object Model (COM). Apple's OpenDoc used IBM's System Object Model (SOM), which was an implementation of the Common Object Request Broker Architecture (CORBA).
Typical CORBA development had the programmer produce Interface Definition Language (IDL) bindings to a standard language such as C or C++. This required the production of several entities such as IDL stubs, IDL skeletons, etc. Introspection in CORBA required the use of a Dynamic Invocation Interface (DII) in which dynamic requests were built through a long series of C-like API calls. The CORBA code then had to be submitted to an Object Request Broker (ORB). This made OpenDoc programming a labor-intensive process. Apple tried to solve this problem by creating a "Direct-To-SOM" compiler that would take C++ class definitions and compile them into CORBA objects.
Java appeared at the perfect time and it succeeded where Direct-To-SOM failed-- it provided a simple, straightforward language for building CORBA-like objects. The objects ran in a Virtual Machine (VM), but the VM acted much like an ORB. Later, Sun published a Introspection API for Java that made CORBA DII look like a cumbersome dinosaur.
Java quickly became the perfect language for writing an OpenDoc-like component model. An early pioneer in this realization was one of my former ASU professors: Tony Faustini. Faustini taught computer language courses at Arizona State, and two of his passions were visual languages and functional programming. When Sun announced Java and Applets to the world, Faustini immediately understood the implications. Very early in the history of the language, around the time when Sun was releasing Beta Applet APIs for the upcoming Java 1.0, he did something that I wouldn't fully appreciate until much later. He apparently found the Java ClassLoader APIs, and used them to build a container that loaded a series of visual components on startup. As it went through the loading process it displayed the loaded components in a progress bar-- much like the one Photoshop used when loading plugins on startup. The result was called Visual Java (not to be confused with the commercial product that is currently being called Visual Java). Visual Java could best be described as a GUI builder using an operator-net representation of the programming language Lucid, where the operator-net entities were dynamically loaded at runtime through a ClassLoader.
Through some promotional efforts by Faustini, Visual Java soon found its way to Sun Microsystems and Java evangelist Miko Matsumura. There is an early Java-related telecast with Miko Matsumura and Sun engineer John Gage where Miko used Visual Java to first make an animated dog run forward and then run backward. I developed a MacDraw-like component for Visual Java called Fresco. Verdantium was influenced by all of this.
To make a long story short, part of Visual Java wound up in Sun's BeanBox container for Java Beans. Part of Visual Java wound up in a Sun product called Java Studio. Java Studio seems very far removed from Tony's original vision. I don't know what, if anything, happened to Fresco. In a sense Visual Java turned into Java Beans, and then Java Beans integrated, after many travails, into systems like Star Office.
Suffice it to say I found it interesting when Google today announced it was going to start bundling Star Office with its products. I think Google is starting to understand reality-- they've realized that they aren't going to do everything with web applications and AJAX. I also have doubts about whether Star Office will be a success against Microsoft Office.
Microsoft Office is the McDonalds Happy Meal of the software industry. It is a single monolithic box packed with a hamburger (Microsoft Word), french fries (Microsoft PowerPoint), a soft drink (Microsoft Excel), and a toy (Microsoft Access). Microsoft produces lots of them with enormous economies of scale, and they're all pretty much the same. Star Office is trying to be the cheaper Happy Meal, or the more agile Happy Meal, or the more international Happy Meal, or the Happy Meal that is available in more places, etc. It's hard to imagine any of Star Office's marketing slogans really working, particularly if Microsoft tried to marginalize Star by cutting the price of MS Office. It's hard to make a big monolithic box better than Microsoft. Star seems to be trying to make something a lot like MS Office, and generally seems to be trying to beat Microsoft as its own game. As a strategy, this doesn't seem to be smart.
To compete with Microsoft, Google and Sun need to address the big truth that Microsoft ignores: most people don't want Happy Meals. As Simon Phipps stated during the 2007 JavaOne conference, people want to go to a buffet table where they are free to choose what suits their tastes. That is to say, the Java community needs to develop framework technologies that can be used to leverage the best talents of the Open Source community. Different people want different application suites. Ever notice how Adobe's application suite (i.e. Photoshop, Illustrator, etc.) looks very different from Microsoft's? Observe: Adobe doesn't even provide a spreadsheet. This shows the kinds of choices that people want from their "buffet table." Some people want Photoshop instead of Microsoft Paint (or vice versa). Some people want a page layout program instead of a word processor. Some people want Gantt charts built directly into the suite, and other people would rather not have to drag all of that code through their CPUs like a boat anchor.
Unlike the typical Microsoft offerings, Java is a language that can make the buffet table work. Tony Faustini demonstrated years ago how how to write code that can put the various items on the table at runtime. It's one of the main reasons why Java has been successful as a language. Choice is a fundamental human desire, and it's a desire that Microsoft doesn't satisfy. An open framework providing choice fully utilizes the best strengths of the Java programming language. Instead of another Happy Meal called Star Office with pre-configured applications, Google and Sun should be providing the full buffet table.
Sunday, August 12, 2007
New Verdantium Version 0812
This was another day in which I have been doing a lot more coding than blogging. As in previous days, I have been continuing to work on the new version of class verdantium.standard.DrawApp. Today I got some persistent writes to work from the new DrawApp. Haven't had a chance to test persistent reads yet.
The new Verdantium requires downloading a new JUndo Runtime (both the jundoruntime and umeta packages). Otherwise, the new persistent writes won't work at all.
I also uploaded a new version of the JUndo compiler. Very small changes here. Mostly I fixed some nebulous error message generation.
The new Verdantium requires downloading a new JUndo Runtime (both the jundoruntime and umeta packages). Otherwise, the new persistent writes won't work at all.
I also uploaded a new version of the JUndo compiler. Very small changes here. Mostly I fixed some nebulous error message generation.
Thursday, August 9, 2007
Is AJAX really the next big thing?
I woke up this morning and realized to my surprise that it's been about ten years since Apple cancelled its ill-fated OpenDoc project. The cancellation of OpenDoc led directly to the creation of the first version of Verdantium, and ten years later I'm still not finished with it.
Ten years is a long time in the technology field. OpenDoc, even after all of this time, still seems ahead of its time. OpenDoc's concept of small cooperating visual components still does not seem to have been replicated by any popular mainstream framework. Nevertheless, I have thought about Verdantium's future. One one hand someone could argue that Verdantium is a really quaint JFC/Swing system that has been outmoded by the new shift toward Web Applications, Asynchronous Javascript and XML (AJAX) and Service Oriented Architecture (SOA). On the other hand, Verdantium's still seems to suggest a utopian future software architecture rather than a prosaic replay of the past.
There are some projects that the new AJAX web applications do well, and there are other projects that they don't seem to do well at all. Google Documents seems like the ultimate blog creation system rather than something that could overthrow office applications like Microsoft Word. The Google system ignores the printed page-- there's no page view, no print preview, no headers, no footers, no table of contents generation, no settings for different printer page sizes (e.g. A4), no color matching, no kerning, etc. Supporting all of this would require two things: first getting printer information to the network server, and second sending lots of bitmaps over the network in real-time. The second of these is likely to be prohibitive compared to Microsoft Word running in Page View. All of the bitmaps probably won't cross the network fast enough.
In spite of the hype about AJAX-based office applications running on a thin client, it's hard to imagine an AJAX-enabled word processor replacing current desktop software. And that's just the word processor. What about image processing? Would anybody want to use the equivalent of Photoshop over a network pipe?
I think the dominant productivity applications of the future are still going to run very thickly (as in thick-client or typical MS-style office application) on the CPU of the end-user's PC. But at the same time, I think it is possible to have a paradigm shift in how those applications are created.
In the currently dominant office applications Microsoft Office, Corel Ofice, Star Office, etc., there are a small number of enormous monolithic container applications (Microsoft Word, Microsoft PowerPoint, etc.) that embed smaller custom components (e.g. JPEG Movie Players) through protocols (e.g. Microsoft OLE/Active-X). This is counterproductive for both users and developers. Users can't mix and match components as they see fit. Developers don't have options for collaborating.
Imagine a framework where one could create a custom productivity suite by rolling together a large number of very small components through a protocol. No dominant office application-- just a protocol. That was what Apple originally proposed with OpenDoc, and even today it still seems like an exciting idea. Leverage each developer's particular skills. Have each developer write a small component in the domain she knows. Don't try to write a huge containing application, but instead provide a way for many smaller components to work together to create the equivalent of a powerful office suite.
Ever notice that it seems hard to write container applications in Microsoft OLE and Active-X? Of course it is. A lot of small, utilitarian container applications embedding each other could gang up on Microsoft Office.
In Verdantium, I tried to make it especially easy for developers to write container applications. In fact, anybody can write a container component supporting multi-level undo and scripting in a few hundred lines of code. In fact, there's a package in the Verdantium download on Sourceforge called MyContainerApp that gives a fully coded example of this. One who looks through the Verdantium source code long enough will find several other examples. I still think this is relevant post-AJAX.
The Verdantium undo system seems much more advanced than the other undo frameworks I've seen. It's more advanced (and faster) than trying to roll back a relational DB. It's more advanced than the system Sun has in the Swing APIs (which uses the inverse command pattern). It's more advanced than what Apple used to ship with OpenDoc. I am not aware of any Java-enabled open-source framework that is providing a temporal undo capability. I'm not aware of any web application frameworks for doing this, either. Temporal undo is highly advantageous for keeping the self-consistency of the multi-level undo implementation high while keeping the SLOC count (and hence the number of bugs) low. People like small, powerful components that are bug-free. Did I mention that multi-level undo is a capability that many Microsoft Office users ABSOLUTELY REQUIRE? That is to say, they will NEVER switch without it.
I think there is a point to all of this in the post-AJAX and post-SOA world. As computers get faster, there will be a point in the future where a Java-enabled system such as Verdantium will be "fast enough" compared to the current productivity suites. Verdantium will get there long before AJAX does (if AJAX gets there at all). Time is still available because technology hasn't yet advanced to make either alternative fast enough (yet!). "The future" could still happen.
Ten years is a long time in the technology field. OpenDoc, even after all of this time, still seems ahead of its time. OpenDoc's concept of small cooperating visual components still does not seem to have been replicated by any popular mainstream framework. Nevertheless, I have thought about Verdantium's future. One one hand someone could argue that Verdantium is a really quaint JFC/Swing system that has been outmoded by the new shift toward Web Applications, Asynchronous Javascript and XML (AJAX) and Service Oriented Architecture (SOA). On the other hand, Verdantium's still seems to suggest a utopian future software architecture rather than a prosaic replay of the past.
There are some projects that the new AJAX web applications do well, and there are other projects that they don't seem to do well at all. Google Documents seems like the ultimate blog creation system rather than something that could overthrow office applications like Microsoft Word. The Google system ignores the printed page-- there's no page view, no print preview, no headers, no footers, no table of contents generation, no settings for different printer page sizes (e.g. A4), no color matching, no kerning, etc. Supporting all of this would require two things: first getting printer information to the network server, and second sending lots of bitmaps over the network in real-time. The second of these is likely to be prohibitive compared to Microsoft Word running in Page View. All of the bitmaps probably won't cross the network fast enough.
In spite of the hype about AJAX-based office applications running on a thin client, it's hard to imagine an AJAX-enabled word processor replacing current desktop software. And that's just the word processor. What about image processing? Would anybody want to use the equivalent of Photoshop over a network pipe?
I think the dominant productivity applications of the future are still going to run very thickly (as in thick-client or typical MS-style office application) on the CPU of the end-user's PC. But at the same time, I think it is possible to have a paradigm shift in how those applications are created.
In the currently dominant office applications Microsoft Office, Corel Ofice, Star Office, etc., there are a small number of enormous monolithic container applications (Microsoft Word, Microsoft PowerPoint, etc.) that embed smaller custom components (e.g. JPEG Movie Players) through protocols (e.g. Microsoft OLE/Active-X). This is counterproductive for both users and developers. Users can't mix and match components as they see fit. Developers don't have options for collaborating.
Imagine a framework where one could create a custom productivity suite by rolling together a large number of very small components through a protocol. No dominant office application-- just a protocol. That was what Apple originally proposed with OpenDoc, and even today it still seems like an exciting idea. Leverage each developer's particular skills. Have each developer write a small component in the domain she knows. Don't try to write a huge containing application, but instead provide a way for many smaller components to work together to create the equivalent of a powerful office suite.
Ever notice that it seems hard to write container applications in Microsoft OLE and Active-X? Of course it is. A lot of small, utilitarian container applications embedding each other could gang up on Microsoft Office.
In Verdantium, I tried to make it especially easy for developers to write container applications. In fact, anybody can write a container component supporting multi-level undo and scripting in a few hundred lines of code. In fact, there's a package in the Verdantium download on Sourceforge called MyContainerApp that gives a fully coded example of this. One who looks through the Verdantium source code long enough will find several other examples. I still think this is relevant post-AJAX.
The Verdantium undo system seems much more advanced than the other undo frameworks I've seen. It's more advanced (and faster) than trying to roll back a relational DB. It's more advanced than the system Sun has in the Swing APIs (which uses the inverse command pattern). It's more advanced than what Apple used to ship with OpenDoc. I am not aware of any Java-enabled open-source framework that is providing a temporal undo capability. I'm not aware of any web application frameworks for doing this, either. Temporal undo is highly advantageous for keeping the self-consistency of the multi-level undo implementation high while keeping the SLOC count (and hence the number of bugs) low. People like small, powerful components that are bug-free. Did I mention that multi-level undo is a capability that many Microsoft Office users ABSOLUTELY REQUIRE? That is to say, they will NEVER switch without it.
I think there is a point to all of this in the post-AJAX and post-SOA world. As computers get faster, there will be a point in the future where a Java-enabled system such as Verdantium will be "fast enough" compared to the current productivity suites. Verdantium will get there long before AJAX does (if AJAX gets there at all). Time is still available because technology hasn't yet advanced to make either alternative fast enough (yet!). "The future" could still happen.
Labels:
AJAX,
Java,
JFC,
OpenDoc,
SOA,
Swing,
Verdantium,
web applications
Subscribe to:
Posts (Atom)