Developing Graphical Simulations in Java
August 11, 1999
I worked on two projects during the summer 1999 REU program at University of Alabama. The first project, proposed by Dr. Jeff Jackson, was to develop a simulation of a certain variety of Programmable Logic Circuit that could be used as a training tool. A commercial product, LadSim (by Bytronic Corporation) allowed drag and drop design and graphical simulation of one variety of Programmable Logic Controller, but had several disadvantages: First, LadSim is an expensive application. A free simulator for educational use was needed. Second, LadSim was geared towards a slightly different variety of PLC than what Dr. Jackson was primarily interested in. Third, LadSim could not be extended by the user - Dr. Jackson wanted simulation software with full source code that could be easily modified to add new capabilities.
The second project I worked on was proposed by Dr. Richard Borie. He wanted a visual simulator for parallel algorithms. He had a collection of lecture slides illustrating the execution of various parallel algorithms step-by-step, and wanted a simulation that would allow real-time animation showing the algorithms' behavior. This posed an interesting design challenge, since it required creating a single program that would be able to simulate algorithms running on a variety of parallel computer topologies.
Both projects were simulations that lent themselves fairly naturally to an Object-Oriented Programming approach. Furthermore, both were going to be heavily reliant on graphical user interfaces. This made Java a reasonable choice of implementation language for both projects, since it provided an excellent toolkit for developing graphical applications, and was well suited to a modular OOP programming style.
Planning for extendibility
Both of these simulation projects had future expansion as a primary goal. The PLC simulator had to allow new varieties of circuit components to be added with a minimum of hassle - while only 8 different components would be implemented in the initial version, it was clear from the outset that future expansions might want to support as many as 50 components. Also, it was expected that customized front-ends to the PLC simulation interface might be wanted in the future. Similarly, the parallel algorithm simulator was intended to accommodate a wide variety of algorithms running on many different types of parallel computer topologies. Thus, a major goal was to make both the addition of new algorithms utilizing an existing topology and the addition of entirely new network topologies as easy as possible, both to allow rapid initial development and future expansion.
With these factors in mind, a clear priority emerged: the single most important goal in development was to keep the designs as modular as possible, and to keep all of the code thoroughly documented for future reference. Indeed, program clarity assumed importance exceeding even that of program correctness, which initially seems an absurd assignment of priorities - until one recognizes that program correctness emerges automatically as a natural consequence of the writing for clarity. This rather important lesson in software design becomes all too clear in the development of even these relatively small applications.
Since future development of both projects would involve the addition of many new modules, it was essential to provide a procedure for incorporating new modules with a minimum amount of modification to existing files. A plug-in model for expansion, like that common to many web browsers, seemed like an appropriate design to strive for. At this point, it is worth noting that Java allows for dynamically loading and linking classes at runtime. Using this aspect of the language, it was straightforward to design both simulations so that they dynamically load new extensions based on information specified in a text-editable configuration file, without requiring any modification or recompilation of existing source code.
Human-Computer Interaction: The Dominant Factor
One issue became clear very early in the development process: writing the actual simulations would only account for a small fraction of the total work. The overwhelming majority of effort would go into refining the graphical user interfaces for the simulations to provide effective and intuitive control of the simulations. Indeed, in the PLC simulation, less than 10% of the total code and the total development time went into simulation logic - all the rest was devoted to the interface. What follows is a series of illustrative examples of the kinds of interface problems that arose in both of the simulations, and the steps taken to address them.
First, any software application must be "gracious" towards the user - it should not appear to ignore the user, or force the user to repeat themselves. For example, the PLC Simulator initially had the pop-up locations for windows hard-coded. This proves intensely frustrating - the proper behavior is that once the user drags a window to a new location, it should keep popping up there, until it gets dragged somewhere else (stubbornness is not an acceptable trait in a software package). Similarly, file open/close boxes need to remember what directories they were previously looking at so that the user is not forced to retraverse the directory tree to get to where they want. In order to handle these concerns, it is necessary to maintain a properties file that keeps track of settings like the current directory and the locations of all the windows whenever the user quits the simulation, so that they can be restored the next time the simulation is loaded.
The user's interaction with the software should feel natural. As much as possible, familiar menus and iconic buttons should be used. Both the PLC simulator and the parallel algorithm simulator use standard VCR-style controls to start, slow, pause, or stop a simulation, a visual metaphor that should be familiar for most users. Another situation where a natural feel of control was important was in the cube topology in the parallel algorithm simulator. Here, the user is able to rotate a cube in three dimensions by dragging it with the mouse. It is quite important that the rate at which the cube rotates in response to mouse movements be set just right; if the cube rotates too much or too little in response to a mouse movement, the interface feels contrived and the user doesn't get the appropriate feeling of control.
Using an early version of the PLC simulator even for a short time revealed another important aspect of interface design: make the common tasks fast. Proper design dictates a careful balancing act between placing the most frequently needed options in prominent locations and organizing less common options into menus to reduce clutter and simplify the interface. Context sensitive menus proved quite useful in the PLC simulator as a way of providing users with the right options in the right place at the right time, without cluttering the interface.
Providing users with useful visual feedback is essential in a graphical interface. Consider the parallel algorithm simulation, for instance: here, the central goal is to convey the behavior of an algorithm to an observer in a purely visual way. The use of color is essential for lending context to what would otherwise be nothing more than a jumble of numbers moving around the screen. Algorithms performing matrix multiplication, for example, begin with one matrix represented in yellow, the other in blue, and as they are multiplied together their product gradually appears in green. This use of color makes it immediately clear what individual data elements represent as the simulation progresses, thereby greatly increasing the amount of information conveyed visually.
The Programmable Logic Circuit Simulator allows users to design ladder logic circuits by dragging and dropping circuit components onto the workspace. Circuit components and their connecting wiring can be configured using context-sensitive menus. Large projects are divided into multiple windows (each representing one network within the circuit), which can be organized and navigated through using single mouse clicks within the network manager's list of windows. Once created, circuit diagrams can be loaded, saved, and printed. The interface for simulation is much like that used in the commercial product LadSim, but with a slightly greater variety of controls. An HTML mini-browser is used within the application for displaying help documentation.
From the programmer's perspective, expanding the simulator to incorporate new features should be relatively easy. All of the code has been documented using Javadoc, a tool for automatically generating an HTML formatted API hierarchy from the in-code comments. New circuit components can be added by creating the necessary graphics and a single new class implementing theCircuitComponent interface (the definition of the methods through which the component will interact with the rest of the simulation). Source code for circuit components is typically 8-12 KB, most of which is comments. Robert Marlowe, an undergraduate student with no previous experience programming in Java, has been able to add a number of new components to the simulation as part of an independent study with Dr. Jackson this summer. This success suggests that the ease-of-expansion goal has been reasonably met. Another area in which the simulator has been left open to easy expansion is in the addition of plug-in front ends to the interface. No significant work has yet been done utilizing this avenue for expansion, but it is available for future use.
The Parallel Algorithm Visualizer currently animates the execution of several different algorithms for searching, sorting, and performing various matrix operations. The currently implemented algorithms illustrate three different network topologies: the linear array, the rectangular mesh, and the three-dimensional cube. The simulation supports a simple form of message-passing communication between independently threaded nodes of execution. Thus, programmers wishing to add new algorithms to the simulation's repertoire can use simplesend and recv methods to exchange information between nodes. The existing simulation framework takes care of all of the work of managing thread-safe communication, maintaining queues of pending messages, and animating message transfers. So, new algorithms and new parallel computer topologies can be developed for the simulation with relative ease, without developers becoming bogged down in the intricate details. Like the PLC simulator, all code is documented using Javadoc, and new algorithms and topologies are added using a plug-in model so they are dynamically loaded and linked at runtime.