Become a programming Picasso with JHotDraw

Use the highly customizable GUI framework to simplify draw application development

Software developers want to build software applications quickly and still focus on quality. One way to reduce development time and improve software quality is to use a framework. Frameworks are designed for reuse; they offer prefabricated components as building blocks and design patterns as blueprints for the architecture.

Many Java programmers frequently use a framework -- maybe even without realizing it. JFC Swing can be viewed as a rather simple framework for creating almost all general-purpose graphical user interfaces (GUIs). Although you can use it for many applications, JFC Swing lacks a clear structure for a GUI-based application. A more specific framework in that respect is JHotDraw (see Resources for a link), which targets applications for drawing technical and structured graphics -- such as network layouts and Pert diagrams -- and offers much better support to develop editors for those purposes. JHotDraw demonstrates frameworks' power and usefulness within their application domain. Before I examine JHotDraw in detail, I'll discuss frameworks and the concepts they embody.

Theory of frameworks and design patterns

By using frameworks, developers usually reuse not only code, but also the design and architecture of a prototype application. Consequently, frameworks must be tailored to meet the needs of the problem domain. Unlike a class library, frameworks provide not only components, but also a structure for integrating those components, a predefined interoperation of components, and often a basic skeleton of an application. The skeleton is not passive like a class library, but has its own execution path from which user-defined component code is called, resulting in an inversion of control.

Developers often face problems in software design that are recurring and typical of a certain situation. You can capture a proven solution to those problems in a design pattern. A design pattern describes a problem, its context, and a reusable solution. It also assigns the problem a meaningful name, which can be used to communicate the solution to other developers.

Frameworks often rely on design patterns to help achieve a flexible general-purpose application design. The patterns introduce indirections and abstractions, which let you plug in your own classes and components.

A framework helps create an application that is developed in a timely manner and customized to the user's requirements, and still benefits from the framework's maturity with regard to robustness and stability. However, this result comes at a price -- the cost of learning and understanding a framework's interactions and even limitations. Most frameworks are rather complex pieces of software at high levels of abstraction. Understanding a framework can be difficult, and debugging framework code is sometimes cumbersome. Frameworks offer some customization facilities, but they can impose some restrictions and may require special programming techniques, especially if you want to perform functionality slightly out of the framework's defined scope.

Before you use a framework, it is important to understand these things: its strengths and weaknesses, what target applications it addresses, its components and structure, the development process, and its fundamental design patterns and programming techniques.

Description of JHotDraw

In contrast to JFC Swing, JHotDraw defines a basic skeleton for a GUI-based editor with tools in a tool palette, different views, user-defined graphical figures, and support for saving, loading, and printing drawings. The framework can be customized using inheritance and combining components.

Besides the main drawing window, JHotDraw offers little support for different kinds of windows, such as text editors. With some knowledge of JHotDraw's structure, you can extend the framework to include missing functionality. If you run the examples included, you can see what a typical application developed with JHotDraw looks like. (See Resources for information on where to download the package.) For example, JavaDraw is a standard drawing application that provides a good overview of what is possible with JHotDraw. You can start JavaDraw by typing:

java CH.ifa.draw.samples.javadraw.JavaDrawApp

in the directory where you unzipped JHotDraw. In addition, CH.ifa.draw.samples.pert.PertApplication demonstrates some of JHotDraw's customization possibilities.

Figure 1. JavaDraw as a typical application of JHotDraw. Click on thumbnail to view full-size image (17 KB)

JHotDraw is interesting from a software engineering point of view as well. Originally developed in Smalltalk by Kent Beck and Ward Cunningham, JHotDraw was one of the first software development projects explicitly designed for reuse and labeled a framework. It was also documented very early in terms of design patterns (see Resources for a link to "Documenting Frameworks Using Patterns"), and was therefore very influential to the design pattern community. Erich Gamma and Thomas Eggenschwiler developed the original version of JHotDraw. (See Resources for a link.)

This article describes a new version of JHotDraw (v. 5.2) in which the original AWT components have been replaced by their JFC Swing counterparts. It also supports new JFC Swing features like windows with several internal frames, split panes, scrollbars, toolbars, and pop-up menus. Therefore, JHotDraw -- as an application-specific GUI framework -- is based on the general-purpose GUI facilities that the JFC Swing framework offers, but adds its own features and functionality.

Package organization

All JHotDraw classes and interfaces are organized in packages according to their functionality. The package CH.ifa.draw.framework contains mostly interface definitions of core component requirements -- their responsibility, functionality, and interoperation. You can find a standard implementation of these interfaces in CH.ifa.draw.standard. You can locate additional functionality in CH.ifa.draw.figures and CH.ifa.draw.contrib. A skeleton of an application or applet is defined in CH.ifa.draw.application or CH.ifa.draw.applet respectively.

Structure of JHotDraw

A more detailed look at the packages -- in particular, the core framework package -- reveals JHotDraw's structure and shows what role each of its components plays. (See Figure 2 below.)

Figure 2. Basic components of JHotDraw's architecture. Click on thumbnail to view full-size image. (4 KB)

Any application that uses JHotDraw has a window dedicated for drawing. This DrawWindow is the editor window and is a subclass of javax.swing.JFrame. It contains one or more internal frames, each associated with a drawing view. The DrawingView, a subclass of javax.swing.JPanel, is an area that can display a Drawing and accepts user input. Changes in the Drawing are propagated to the DrawingView that is responsible for updating any graphics. The Drawing consists of Figures, which in turn can be containers for other Figures. Each Figure has Handles, which define access points and determine how to interact with the Figure (for example, how to connect the Figure with another Figure). In a DrawingView, you can select several figures and manipulate them. The DrawWindow itself usually has one active Tool from the tool palette, which operates on the Drawing associated with the current DrawingView.

Typical development process using JHotDraw

The following is a list of recurring tasks involved with developing an application with JHotDraw. The tasks focus on integrating JHotDraw into your application and working together with your object model from the "Problem description for a sample application" section of this article.

  1. Create your own graphical figures and symbols for your application. More often than not, it is necessary to define your own graphical figures. Fortunately, some predefined figures like AbstractFigure, CompositeFigure, and AttributeFigure are already available. You can refine their behavior by subclassing and overriding some methods, such as draw(), to customize the graphical representation in the diagram. Typically, the graphical figures should correspond and somehow relate to the objects used in your application.
  2. Develop your own tools to create figures and manipulate them according to application requirements. Again, JHotDraw offers some starting points: for instance, CreationTool, ConnectionTool, SelectionTool, and TextTool. Subclassing those tools and overriding methods like mouseUp() and mouseDown() allows you to specify your own application interaction and perform the tasks your application needs -- such as manipulating the object defined by your application.
  3. Create the actual GUI and integrate it into your application. Unsurprisingly, JHotDraw already includes a basic application skeleton: either a basic DrawApplication, a MDI_DrawApplication with support for several internal frames, or a DrawApplet. You can define your own menus by refining createMenus(), createFileMenu(), and so on, and plug in new tools by overriding the createTools() method in a subclass. A complete GUI is created when you instantiate your application at runtime and call the open() method.
  4. Compile the applications using javac. It is important to incorporate all packages needed by JHotDraw into the classpath when calling either javac or java.

Some of these tasks involve applying certain design patterns, which I'll discuss later in more detail.

Problem description for a sample application

Before using a framework, it is important to know its target application domain (if there is one) and how the framework addresses problems found within that domain.

The development of a simple class diagram editor called JModeller will serve as a sample application in this article. JModeller helps you design class diagrams and document software architecture. It supports classes with association (has-a), aggregation (consists-of), dependency (uses-a), and inheritance (is-a) relationships between them. Beyond these fundamental design constructs, the editor has no advanced features and can only save, load, and print the object models that are designed with it.

The object model for managing classes in the class diagram editor is rather simple. The main object in this model, JModellerClass, represents a class, which consists of a class name, attributes, and methods. If the association, dependency, and inheritance relationships become more complex, you can include a dedicated class in the model for keeping track of their properties and behavior. That is not necessary at the moment, so classes store the information about their relationships themselves. Still, there are specialized graphical figures responsible for drawing a class, an association, a dependency, or an inheritance line. You should not confuse the object model for building a class editor with the class editor's capability to design new object models in a class diagram. This particular object model just stores the information needed by many class diagrams, as well as some graphical information.

Figure 3. The JModellerClass and its figures for graphical representation Click on thumbnail to view full-size image. (8 KB)

Obviously, the kind of application that is suitable to build with JHotDraw fits this requirement description exactly.

Using JHotDraw's design patterns

Now I will show you how to develop the class diagram editor using JHotDraw's design patterns.

The Model-View-Controller paradigm

First, keep in mind that JHotDraw is based on the Model-View-Controller (MVC) paradigm (see Resources for a link), which separates application logic from user interface dependencies. The view is usually responsible for displaying information in a user interface; the controller handles the user interaction and maps it onto the application functionality. The model underlies the view and the controller and consists of the application's logic and data. The view is notified of changes in the data.

You should adhere to MVC when using JHotDraw to build applications; usually, you must provide your own object model and add figures to graphically represent the model's underlying objects. JHotDraw becomes a view, and partly a controller. As a controller, it offers tool components for managing user interaction and manipulating graphical objects. In turn, changes to a graphical object should be reflected onto the object model. You can also develop tools that contain application logic and deal with the object model directly.

The Composite design pattern

As I mentioned before, the object model for storing information about classes in a class diagram is straightforward. You just need a single JModellerClass, which you can find in JModellerClass.java. The graphical figure for representing a class in a class diagram is more interesting. It has multiple requirements that are not covered by the basic figures. Therefore, a new GraphicalCompositeFigure is created; the figure incorporates the advantages of several existing figures, most notably one TextFigure for the class name and several TextFigures for attributes and methods. JHotDraw already provides a CompositeFigure, which integrates several figures into a single one.

1 2 3 Page 1