JDemo - Java Demonstration Framework



JDemo Documentation 1.2





Markus Gebhard - Januar 8, 2005


Contents

Preface

Changes of this document

1 Overview

1.1 What is JDemo?

1.2 What is JDemo not?

1.3 What can JDemo be used for?

1.4 JUnit as Role Model

1.5 Differences between JUnit and JDemo

1.6 When to write a Demo

1.7 Installing JDemo

1.8 How to write a Demo

1.9 How to run a Demo

1.10 GUI Demos

1.11 More about JDemo

2 Typical Scenario

2.1 Example application

2.2 Demos for the application

2.3 Demos for multiple purposes

3 The Framework

3.1 Basic Framework Interfaces

3.2 Demo Execution and Life Cycle

3.2.1 Standard Demo Execution

3.2.2 Demo Execution States

3.2.3 GUI Demo Execution

4 DemoCase Base Classes, API and Usage

4.1 Choosing an Appropriate Base Class

4.2 Class Hierarchie

4.3 AbstractDemoCase

4.3.1 API Description

4.4 PlainDemoCase

4.4.1 Example Usage

4.5 DemoCase

4.5.1 API Description

4.5.2 Example Usage

4.6 GuiDemoCase

4.6.1 API Description

4.7 AwtDemoCase

4.7.1 API Description

4.7.2 Example Usage

4.8 SwingDemoCase

4.8.1 API Description

4.8.2 Example Usage

4.9 LookAndFeel with SwingDemoCases

4.9.1 API Description

4.9.2 Example Usage

4.9.3 Comments

4.10 SwtDemoCase

4.10.1 API Description

4.10.2 Example Usage

5 Demo Runner

5.1 Launching

5.2 Usage

6 Eclipse Integration

6.1 JDemo Wizards

6.2 JDemo Launch Type

6.3 Misc

6.3.1 Recreate Demo Suite

6.3.2 Go to Referring Demos

7 Capturing Demo Output

7.1 Demo Identifier

7.2 Capturing Textual Output

7.3 Capturing File Output

7.4 Making Screenshots

7.5 Ant Tasks

7.5.1 Capturing Text Output

7.5.2 Capturing File Output

7.5.3 Making Screenshots

7.5.4 Known limitations

7.6 Image processings

7.6.1 Generic image processings

7.6.2 Composing images

8 Demos as Unit Tests

8.1 Automated conversion from demos to tests

8.2 Peculiarities with demo-tests

8.3 Evaluation

9 Annotating Demos

9.1 JDemo Annotation

9.2 Example

10 Contributing to JDemo

10.1 JDemo CVS

10.2 Writing your own DemoRunner

10.3 Integrating the DemoRunner into other Applications

11 Future Development

11.1 Batch Capture

11.2 Executing Sequences of Demos

12 About this Document


Preface

During the last years, JUnit has established as the standard tool for automated testing in the Java world. Although there are some extensions to JUnit for testing gui (graphical user interface) components, there is a lack of a similar tool and strategy for interactive testing or demonstrating the look and feel of gui components.

In order to close this gap I have started to design and implement the new JDemo framework for writing and running demonstration code. Based on the concepts and source code of JUnit, it provides a uniform way for running demonstrations for gui components as well as for non gui code.

Implementing JDemo demonstrations is just as easy as writing JUnit tests. Abstract superclasses for Swing, AWT and SWT DemoCases provide convenience code that helps reducing code duplication and making it easy to write demos.

The framework includes a simple Swing based DemoRunner that can be used for running DemoCases and DemoSuits, which will be presented to the user in a hierarchical view.

Current development of JDemo concentrates on enhancing the framework and on using DemoCases for automatically producing screenshots or extracting program output for documentation purposes.

This document is meant for both giving an overview over JDemo and describing its API and concepts in detail. Readers should be familiar with JUnit, because the JDemo framework is based on its concepts. If not, visit the main JUnit website where there are a number of links to some excellent resources on the subject.

Markus Gebhard
markus@jdemo.de
http://www.jdemo.de

Changes to this document

Date Author Version Changes
8th January 2005


Markus Gebhard


1.2


1. Adjusted all chapters to the new
JDemo 1.2 version.
2. Added an index to the PDF version.
3. Adjusted version number to release.
2nd September 2004
Markus Gebhard
0.5
Minor corrections, added a new item
to the future development chapter.
16th August 2004
Markus Gebhard
0.4
Adjusted examples to the new
JDemo 1.1.1 version.

23rd July 2004

Markus Gebhard
0.3
Adjusted all chapters to the new
JDemo 1.1.0 version.
8th May 2004




Markus Gebhard




0.2




1. Added a chapter about a typical
usage scenario
2. Added a chapter about demos as
unit tests
3. Modified all other sections
to fit the current JDemo release
18th October 2003 Markus Gebhard 0.1 First public version

1 Overview

1.1 What is JDemo?

JDemo is a new demonstration framework written in and for the Java (Java is a trademark or registered trademark of Sun Microsystems, Inc. in the U.S. or other countries.) programming language. Its concept and implementation is based on the open source regression testing framework JUnit (http://www.junit.org) by Erich Gamma and Kent Beck. Although being quite different from JUnit, there are a lot of similarities.

JDemo provides a uniform and straightforward way for writing code snippets similar to unit testing code. The code snippets can be used to demonstrate both the code usage and the output of the program - either to the screen, to a file or just as plain text. Furthermore the demo code can be used for documentation purposes.

1.2 What is JDemo not?

JDemo is not an extension to JUnit. As will be described in the following sections, there are fundamental differences in the concepts of both frameworks.

Also JDemo is not a substitute for unit tests. In fact using JDemo in practice for a while has shown that using both, JDemo and JUnit side by side, makes a perfect combination.

Finally JDemo is not an academical project. On the contrary, most of the framework has been developed while working on serious (well, and also some not so serious...) projects. It has evolved and has already proven to be very useful for many purposes. Now that it is almost grown up, I want to share it with the open source community.

1.3 What can JDemo be used for?

Being both very simple and flexible, JDemo has multiple benefits. Here is a list of the most important ones I have found:

The list could be extended, but I think it is now time to explain the framework and show how to write a simple demo. Before that, I want to explain what the idea of JDemo goes back to though.

1.4 JUnit as Role Model

One day in early 2003 I found myself writing a JUnit test method that was not really meant to be an automated test, but rather a little piece of code making some kind of graphical output, I was interested in. I was tempted to use the unit test approach because I already had some code for initializing my software library in a unit test. By adding a few lines like Thread.sleep(10000) and frame.show() to the test and starting the TestRunner I was able to test drive the program and evaluate its output.

For those being familiar with JUnit, it is obvious that using unit tests for interactive testing just does not make sense. Unit tests are meant to be run and evaluated automatically. Each test is only run once and all tests in the selected test suite are being run. This other kind of test code - from now on called demo code - requires a slightly different approach. All demos in a suite must be presented to the user, who then can arbitrarily pick a demo to be executed. It depends on his intention, what the demo is used for: If he is a developer working on the code, he probably wants to run the demo in order to actually see that the demonstrated program part behaves in the right way. As a developer who is looking for a code library, he probably wants to see if the library fits his needs or how its API can be used. With these totally different aims it is clear that demos are different from tests and mixing up demo and test code must be avoided.

However there are a lot of advantages regarding the simplicity and the concept of writing unit tests, so I decided to make JDemo similar to the approved JUnit framework.

1.5 Differences between JUnit and JDemo

Developers familiar with unit testing will only have to learn a few things in order to use JDemo.
Here is a list of the main aspects and differences one has to be aware of:

1.6 When to write a Demo

There are some situations indicating that it is a good idea to write a demo:

1.7 Installing JDemo

Before writing the first demo, you will have to install the framework. Fortunately JDemo installation is simple: That's it.

Advanced users can reduce dependencies: The jdemo.jar consists of the smaller libraries jdemo_core.jar and jdemo_runner.jar. Both of them are contained in the download package, too. At compile time you only will need the core library. When executing demos you will also need the runner library. The Eclipse plugin (see chapter 6) for example contains a runner itself, so Eclipse users will only need the core library.

1.8 How to write a Demo

Similar to unit tests, demos are public methods named demo...(). They must be implemented in subclasses of one of the demo case implementations provided by the framework (e.g. de.jdemo.framework.DemoCase). Demo methods must not have any parameters and their return type must be void. They may declare to throw any kind of Exception, although a valid demo should never throw any (unless it demonstrates how to throw an Exception...).

The probably most simple demo is a hello world demo:

   public class HelloWorldDemo extends de.jdemo.framework.DemoCase {
   
  public void demoHelloWorld() {
   
    show("Hello World");
   
  }
   
}
This trivial demo class contains a single demo that will print out "Hello World" when being run. Note that the name of the demo is derived from the method name, so our first demo's name is "Hello World".

1.9 How to run a Demo

There are various ways for starting a demo. One is to call a JDemo runner from the command line. The command
java de.jdemo.swingui.DemoRunner HelloWorldDemo
will start the demo above by using the Swing based runner contained in the JDemo library. Note that JDemo has to be installed as described in section 1.7. Figure 1.1 shows the DemoRunner after executing the Hello World demo.


(a) Demo runner

(b) Demo output

Figure 1.1: Executing the Hello World demo

An alternative way for running a demo is to provide the code for starting the DemoRunner in the main method of the demo class itself:

   public static void main(String[] args) {
   
  de.jdemo.swingui.DemoRunner.run(HelloWorldDemo.class);
   
}
Note that this is not the recommended way for starting the DemoRunner: Directly referencing the DemoRunner from within a demo class adds lots of dependencies. The decision about what runner application to use should be made by the user at run time, not by the developer at compile time.

Rrunning one or more demos from within an integrated development environment might be much more convenient - at least when there are plugins or extensions for JDemo being available and installed. For the popular Eclipse IDE, for example, there is a plugin available (see chapter 6).

1.10 GUI Demos

Besides the text based DemoCase class, JDemo also contains demo case base classes providing convenience methods for GUI demos using AWT, Swing and SWT (for a complete overview of the available demo case base classes refer to section 4.1.

For example, imagine you have written the code for a Swing GUI component MyDice, showing the top side of a die.

Here is what a valid demo for this class could look like:

   public class MyDiceDemo extends de.jdemo.extensions.SwingDemoCase {
   
  public void demo6Dice() {
   
    JComponent diceComponent = new MyDice(6);
   
    show(diceComponent);
   
  }
   
}
The demo class subclasses de.jdemo.framework.extension.SwingDemoCase because it uses a Swing component for output. Note that there is no need to care about adding the component to a JFrame or JDialog. The SwingDemoCase class does all the work for you in the provided show(...) method.

Figure 1.2 shows what you will see when running the demo.


(a) Demo runner

(b) Demo output

Figure 1.2: Simple dice demo

Now lets imagine your dice component also has a default constructor (without a parameter) for creating a die with a random number. It is a good idea to also provide a demo for that by adding a second demo method to the MyDiceDemo class:

   public void demoRandomDice() {
   
  show(new MyDice());
   
}
Running the DemoRunner will now present two demo cases to the user. Figure 1.3shows example screenshots.


(a) Demo runner

(b) Demo output

Figure 1.3: Extended dice demo

The complete source code for this and other simple examples of JDemo usage can be found in the examples folder of the JDemo download package.

1.11 More about JDemo

This overview was meant for giving you an idea of what JDemo is all about. However there is a lot more to learn about it. So read on to the next chapters for a more detailed description of the framework and its API.

2 Typical Scenario

This chapter shows a typical scenario for using JDemo with real world software projects.

2.1 Example application

Let us have a look at a typical software application as shown in Figure 2.1. In order for the main application to start, you have to successfully log in at a login dialog. The main application frame consists of a tree, a list and a few other components. From there you can start a wizard for importing some files. Once there are files imported into the application you can move on to an export dialog that in the end creates a html file.



Figure 2.1: Draft of a typical software application

Obviously the application can be divided into separate parts (and I am pretty sure this structure will also be reflected by the modules or packages in the implementation): During development most of the time software developers will work on one of these parts without caring much about the others. This is also true for unit tests, which are meant for testing small units of code. But what about the dialogs? If I want to see the html export dialog I have to start the application, log in, import files, etc. I have to navigate the whole way through the application until I finally see it on the screen. Of course the same procedure has to be performed if I just want to have a look at some example html output.

So all that I want is some simple way to demonstrate certain parts of the application. But when looking into software engineering books I cannot find a single sentence about this kind of code demonstration.

2.2 Demos for the application

JDemo provides a consistent way for writing and organizing code for demonstrating parts of a software application. So for the application described in the previous section we would write a demo for the html export dialog, for example. Using the SwingDemoCase class described in section 4.8, the demo might look somewhat like this:

   public void demo() {
   
  ExportableData data = createExampleExportData();
   
  ExportDialog dialog = new ExportDialog(data);
   
  show(dialog);
   
}
At first some example data is being created. Then the export dialog is being created using this data and it is being shown by calling a convenience method in SwingDemoCase. The demo method contains everything being neccessary for demonstrating the export dialog - and nothing else.

As we also want to see what the html output looks like, we continue writing a demo for showing some example output:

   public void demo() throws IOException {
   
  File outputFile = createTempFile(".html");
   
  ExportableData data = createExampleExportData();
   
  new HtmlFileExport().export(data, outputFile);
   
  show(outputFile);
   
}
The code uses some convenience methods from the DemoCase class described in section 4.5 for creating and showing a temporary file.

Now these two code snippets and others are then being arranged into suites of demos. The suites from each software module on their part can be arranged in another suite and we will end up with a tree of demos as shown in figure 2.2.



Figure 2.2: Hirarchically aranged demos for the example application from Figure 2.1

From now on for each part of the application there is a demo available. In the next section we will see what they can be used for.

2.3 Demos for multiple purposes

Figure  2.3 shows what demos are useful for in the various phases of software development.



Figure 2.3: Field of applications for demos in various phases of software development

The most interesting fact is that demos are not only useful during implementation, but also for deployment and maintenance.

This chapter has not been finished and will be extended in a future version of this document.

3 The Framework

This chapter explains the JDemo framework in detail. The basic interfaces and classes are introduced, along with a description of a typical demo execution and its life cycle. For beginners I would suggest to rather skip this chapter now and check back later.

3.1 Basic Framework Interfaces

Figure 3.1 shows the base interfaces of the JDemo framework. As you can see, demos use the composite design pattern. IDemoCase objects are actual demo implementations. Each demo has a unique identifier DemoIdentifier consisting of the fully qualified demo class name and the demo method name. Demos can be aggregated in IDemoSuite objects.



Figure 3.1: Base interfaces of the JDemo framework

Compared to the JUnit framework there are two main differences:

Figure 3.2 shows the interface of the IDemoCaseRunnable. The runnable carries information about the current state of the demo it has been created on. The framework contains a typesafe enumeration implementation de.jdemo.framework.state.DemoState for the execution states. Section 3.2.2 describes the various states of a demo. A demo runner application can attach de.jdemo.framework.state.IDemoStateChangeListener objects to the DemoCaseRunnable in order to react on state changes (see figure 3.2). When the demo has crashed, the java.lang.Throwable object that describes the problem can be requested using the getThrowable() method.



Figure 3.2: The runnable for executing a demo case.

Being a Runnable, it can be started in a separate thread and execute the demo. The exit() method is being called from within the DemoCase or the runner for normal demo termination. If the user requests to cancel the demo from outside (for example by pressing a stop button in the demo runner application), the cancel() method is used instead to interrupt execution.

3.2 Demo Execution and Life Cycle

This section describes the execution of demos in JDemo using the DemoCaseRunnable introduced in the previous section.

3.2.1 Standard Demo Execution

Figure 3.3 shows the simplified sequence diagram of the execution of a demo (Note: Please don't mix up the DemoRunner and the DemoCaseRunnable: The DemoCaseRunnable is the default implementation of the IDemoCaseRunnable interface described in the previous section, whereas DemoRunner is a different class, that initiates the execution of a demo.) .



Figure 3.3: Sequence diagram of demo execution.

Demo execution is separated into two steps:

3.2.2 Demo Execution States

During execution, each demo goes through a number of states. For implementing or running demos you will not have to care much about the different states. However, for a better understanding of the framework we will have a look at them.

3.2.3 GUI Demo Execution

The execution of GUI demos is a little bit more complicated than the execution of standard demos described in the previous sections. This is because usually a demo with graphical output will show a window on the screen. When returning from its demo...() method, the window is still visible and the demo should be considered running until the window is being disposed.

The DemoCaseRunnable described in the previous sections does not care about that special case. It simply exits the demo by calling tearDown() right after returning from the demo...() method. So there is a different implementation GuiDemoCaseRunnable necessary for GUI demos. Figure 3.4 shows a simplified sequence diagram for the execution of an AWT or Swing GUI demo.



Figure 3.4: Sequence diagram of GUI demo execution.

The GuiDemoCase has to know what window has been made visible in the demo...() method. For this the show(Window) method delegates to registerDemoWindow(Window). Here the GuiDemoCase attaches a WindowListener to the window being shown. Before returning from the demo...() method, the GuiDemoCase makes the window object visible. The GuiDemoCaseRunnable considers the demo still being running and does not exit the demo.

Once the demo window is being disposed, the WindowListener of the GuiDemoCasecatches a windowClosing-event and requests the GuiDemoCaseRunnable to exit the demo.

Note that a window object being passed to the registerDemoWindow(Window) method is called a managed window. Any GUI DemoCase implementation should ensure that the window being shown is managed. The sections about the various GUI DemoCases in chapter 4 will explain how to achieve this. Otherwise the GuiDemoCaseRunnable cannot handle state changes correctly. Also other features like changing the LookAndFeel (see section 4.9) and creating screenshots (see section 7.4) will not work.

Finally note that for exiting a GUI demo from within the demo code itself (for example when the user hits a button) you can directly call the method exit() in the GuiDemoCase class to dispose the window and exit the demo.

4 DemoCase Base Classes, API and Usage

Having read the previous chapter you might think writing demos is complicated. Fortunately most of the complexity of demos is hidden behind the very simple API of the JDemo DemoCase implementations. This chapter explains the various DemoCase base classes and how to use their API.

4.1 Choosing an Appropriate Base Class

Depending on what kind of software output you want to demonstrate, you have to choose one of the base classes provided by the framework. Table 4.1 gives a quick overview of what base class you should pick for your demo.

What kind of output shall be demonstrated? Appropriate base class
Plain text (java.lang.CharSequence) de.jdemo.framework.DemoCase
File objects (e.g. *.html, *.rtf) de.jdemo.framework.DemoCase
Direct output to a hardware device
(e.g. Soundcard, LPT-Port)
de.jdemo.framework.PlainDemoCase
Components from the Java AWT
(e.g. java.awt.List)
de.jdemo.extensions.AwtDemoCase
Components from Java Swing
(e.g. javax.swing.JTable)
de.jdemo.extensions.SwingDemoCase
Components from the IBM Eclipse SWT de.jdemo.extensions.SwtDemoCase

Table 4.1: Base classes to choose for various purposes

Each of the base classes provides convenience methods for demo implementations. They are described in the following sections and in the JDemo JavaDoc API.

4.2 Class Hierarchie

Figure 4.1 shows the inheritance hierarchie of all demo case base classes provided with JDemo. Along with the base classes PlainDemoCase and DemoCase(for showing files and plain text), there are three gui demo case classes AwtDemoCase, SwingDemoCase and SwtDemoCase. All those classes are described in the following sections.



Figure 4.1: Inheritence hiearchie of the DemoCase base classes in JDemo

4.3 AbstractDemoCase

AbstractDemoCase is the abstract base class for all demo case implementations. It contains basic implementations and convenience methods. You will not have to care about this class, unless you want to implement a new type of demo case base class.

4.3.1 API Description

protected void exit();
   

This method can be called from inside a IDemoCase to send a request to the IDemoCaseRunnable to exit the running demo. As for now calling this method only makes sense for GUI demo cases. This has been described in section 3.2.3.



public void cancel();
   

This method will be called from the DemoCaseRunnable to send a request to the IDemoCase to cancel its execution. Subclasses can overwrite this method in order to e.g. dispose a window. This method should not be called from inside a demo method itself.



4.4 PlainDemoCase

PlainDemoCase is the most simple implementation of the IDemoCase interface. It only implements the methods already described in the previous sections.

You should choose this class as superclass for your demo if the output of your demo does not belong to the ones supported by the other base classes described below. This is most likely the case if your demo makes output directly to a hardware device like a soundcard, a printer or a robot connected to the serial port.

4.4.1 Example Usage

Here is an example of a PlainDemoCase demo playing a simple sound using the Toolkit.beep()method from AWT:

public class PlainDemoCaseUsageDemo extends PlainDemoCase {

  public void demoToolkitBeep() throws Exception {
    Toolkit.getDefaultToolkit().beep();
    Thread.sleep(500);
    Toolkit.getDefaultToolkit().beep();
  }
}

4.5 DemoCase

DemoCase is another implementation of the IDemoCase interface. It provides convenience methods that can be used in demo implementations for showing files and plain text:


4.5.1 API Description

protected File createTempFile(String suffix);
   

This convenience method creates a temporary file with the given suffix (=file name extension, e.g. ".txt"). The file will be deleted when the virtual machine terminates.



protected void show(File file);
   

Tries to open the given file by passing it to the operating system. This is useful for example if the output of the demo is a *.html file or any other kind of binary. The method passes the file's name to the operating system which hopefully will open the file using the default application.

Note that this might not work properly on some systems. In fact at the moment it only has been implemented for Windows systems. The implementation for file launching can be found in de.jdemo.util.FileLauncher.



protected void show(CharSequence text);
   

Shows the given text (java.lang.String implements the java.lang.CharSequence interface). By default the text is printed to System.out. The Swing based demo runner however shows the text in a dialog window instead.



4.5.2 Example Usage

In the examples directory of the JDemo distribution there is a class de.jdemo.examples.DemoCaseUsageDemo containing example demos using the DemoCase API. Here is an excerpt from this file:

public class DemoCaseUsageDemo extends DemoCase {
  /** Demo creating a temporary file and opening it using the convenience method. */
  public void demoShowFile() throws IOException {
    File file = createTempFile(".html");
    BufferedWriter bw = new BufferedWriter(new FileWriter(file));
    bw.write("<html><head></head><body>");
    bw.write("<h1>Demo file created from within a JDemo demonstration program</h1>");
    bw.write("</body></html>");
    bw.close();
    show(file);
  }
  
  /** Demo showing textual output. */
  public void demoShowText() {
    show("Hello World");
  }
}

4.6 GuiDemoCase

GuiDemoCase is the superclass class for AwtDemoCase and SwingDemoCase. It only provides methods for managing Window objets. Those methods are required by both subclasses and by the GUI capturing code described in chapter 7.


4.6.1 API Description

protected void registerDemoWindow(Window window);
   

Registers the given window as demo window for this GuiDemoCase. Usually called by any framework method that displays a window object.



public Window getRegisteredDemoWindow();
   

Returns the demo window registered with this GuiDemoCase or null if there is none registered.



Note that all show...() methods in the sublasses of GuiDemoCase ensure that the displayed objects are contained in a registered window. So you will not have to care for registering your component yourself.

4.7 AwtDemoCase


4.7.1 API Description

protected void show(CharSequence text);
   

Convenience method for showing the given text in a java.awt.TextArea component using a fixed width font.



protected void showProportional(CharSequence text);
   

Convenience method for showing the given text in a java.awt.TextArea component using a proportional font.



protected void show(Component component);
   

Convenience method for showing any kind of java.awt.Component object.



protected void show(Component[] components, LayoutManager layout);
   

Convenience method for showing an array of java.awt.Component objects. The specified layout manager will be used to lay out the components.



protected void show(Window window);
   

Convenience method for showing any kind of java.awt.Window object. The given object will also be registred as demo window for this democase (if not being registered already). Note that the window will be packed, centered on the screen and made non-modal if being a dialog.



protected void showAsIs(Window window);
   

Convenience method for showing any kind of java.awt.Window object. The given object will also be registred as demo window for this democase (if not being registered already). Note that the window will be made non-modal if being a dialog.



protected Frame createFrame();
   

Convenience method for creating a new java.awt.Frame object that can be used for demo implementations. The frame is automatically registered as demo window and decorated with the necessary window listener, icon, title, etc.



protected void setFrameTitle(String title);
   

Sets the title for the frame being created by this demo case. Setting it to null (default) will set the title to the name of the demo.



protected void setFrameIconImage(Image icon);
   

Sets the image that will be used for the frame icon when showing this demo.



4.7.2 Example Usage

In the examples directory of the JDemo distribution there is a class de.jdemo.examples.awt.AwtDemoCaseUsageDemo containing example demos using the AwtDemoCase API. Have a look at its commented source code in order to see proper usage of the API.

4.8 SwingDemoCase

As SwingDemoCase is a subclass of AwtDemoCase you can use all of its convenience methods. In addition it provides Swing specific methods.


4.8.1 API Description

protected void show(CharSequence text);
   

Convenience method for showing the given text in a javax.swing.JTextPane component using a fixed width font.



protected void showProportional(CharSequence text);
   

Convenience method for showing the given text in a javax.swing.JTextPane component using a proportional font.



protected void show(JComponent component);
   

Convenience method for showing any kind of javax.swing.JComponent object.



protected void show(Icon icon);
   

Convenience method for showing a javax.swing.Icon object.



protected void show(Icon[] icons, LayoutManager layout);
   

Convenience method for showing an array of javax.swing.Icon objects. The specified layout manager will be used to lay out the icons.



protected void show(Image image);
   

Convenience method for showing a java.awt.Image object.



protected void show(Image[] images, LayoutManager layout);
   

Convenience method for showing an array of java.awt.Image objects. The specified layout manager will be used to lay out the images.



protected void show(JPopupMenu popupMenu);
   

Convenience method for showing a popup menu. The menu will be "embedded" into a frame.



protected JFrame createJFrame();
   

Convenience method for creating a new javax.swing.JFrame object that can be used for demo implementations.



protected void setFrameIcon(Icon icon);
   

Sets the icon that will be used for the frame when showing this democase.



4.8.2 Example Usage

In the examples directory of the JDemo distribution there is a class de.jdemo.examples.jfc.SwingDemoCaseUsageDemo containing example demos using the SwingDemoCase API. Have a look at its commented source code in order to see proper usage of the API.

4.9 LookAndFeel with SwingDemoCases

Usually setting the LookAndFeel is being done by a call to a static method in the javax.swing.UIManager class. However for demos this is not good practice, since we would then have to implement multiple demos of the same component in order to see it in various LookAndFeels. To avoid this problem demos are subject to the following restrictions:

  1. Any demo implementation can set its preferred LookAndFeel in the setup method or at the beginning of the demo method.
  2. Users must be able to optionally tell the Demo runner what LookAndFeel to use when running a demo. This setting superceedes the preferred LookAndFeel specified in the demo (if any).
  3. By default demos are run in the Java Cross Platform LookAndFeel.
Setting the preferred LookAndFeel can be done by calling one of the convenience methods provided by the SwingDemoCase class:


4.9.1 API Description

protected void setPreferredLookAndFeel(String lookAndFeelClassName);
   

Sets the preferred LookAndFeel to the one represented by the given LookAndFeel class name.



protected void setPreferredLookAndFeelCrossPlatform();
   

Sets the preferred LookAndFeel to the Java Cross Platform LookAndFeel.



protected void setPreferredLookAndFeelGtk();
   

Sets the preferred LookAndFeel to the Gtk LookAndFeel (com.sun.java.swing.plaf.gtk.GTKLookAndFeel). Note that this LookAndFeel might not be supported on some systems.



protected void setPreferredLookAndFeelMotif();
   

Sets the preferred LookAndFeel to the Motif LookAndFeel (com.sun.java.swing.plaf.motif.MotifLookAndFeel). Note that this LookAndFeel might not be supported on some systems.



protected void setPreferredLookAndFeelSystem();
   

Sets the preferred LookAndFeel to the system's native LookAndFeel.



protected void setPreferredLookAndFeelWindows();
   

Sets the preferred LookAndFeel to the Windows LookAndFeel (com.sun.java.swing.plaf.windows.WindowsLookAndFeel). Note that this LookAndFeel might not be supported on some systems.



Note that using a LookAndFeel not available on your system will result in a java.lang.ClassNotFoundException or a java.lang.RuntimeException causing the demo to fail when being run.

4.9.2 Example Usage

In the examples directory of the JDemo distribution there is a class de.jdemo.examples.jfc.LookAndFeelDemo containing example demos using the SwingDemoCase LookAndFeel API. Here is an excerpt from this file containing three demos showing a JButton object in different LookAndFeels:

public class LookAndFeelDemo extends SwingDemoCase {

  public void demoSystemLookAndFeel() {
    setPreferredLookAndFeelSystem();
    show(new JButton("Button in system Look and Feel"));
  }

  public void demoCrossPlatformLookAndFeel() {
    setPreferredLookAndFeelCrossPlatform();
    show(new JButton("Button in CrossPlatform Look and Feel"));
  }

  public void demoMotifLookAndFeel() {
    setPreferredLookAndFeelMotif();
    show(new JButton("Button in Motif Look and Feel"));
  }
}
Figure 4.7 shows a screenshot of the output from the example.



Figure 4.7: The LookAndFeel demo example showing buttons in different LookAndFeels.

4.9.3 Comments

The default demo runner in JDemo itself uses the system LookAndFeel for its GUI. If there was no other LookAndFeel specified for the demo cases, they also would be rendered using the system LookAndFeel. In order to avoid this, JDemo initializes each Swing demo with the Java Cross Platform LookAndFeel.

Since all demos are run in the same virtual machine, it can not be guaranteed that setting the LookAndFeel for one demo does not affect others. This in particular is true when the demo creates new gui components after switching the LookAndFeel, e.g. when creating a new popup window.

4.10 SwtDemoCase

The most recent implemented DemoCase subclass is the one for supporting IBM's windowing toolkit SWT. At the moment it only provides one method:


4.10.1 API Description

protected Shell createShell();
   

Creates a new org.eclipse.swt.widgets.Shell object that can be used for adding widgets. The shell will automatically be made visible when returning from the demo...() method. Not that calling this method more often than once during execution of a single demo will result in a de.jdemo.framework.exceptions.DemoExecutionFailedError.




4.10.2 Example Usage

In the examples directory of the JDemo distribution there is a class de.jdemo.examples.swt.SwtDemoCaseUsageDemo containing example demos using the SwtDemoCase API. Here is an excerpt from this file:

public class SwtDemoCaseUsageDemo extends SwtDemoCase {

  public void demoSwtLabel() {
    Label label = new Label(createShell(), SWT.NONE);
    label.setText("Hello SWT World!");
  }

  public void demoExitFromWithinASwtDemoUsingAButton() {
    Button button = new Button(createShell(), SWT.PUSH);
    button.setText("Exit");
    button.addSelectionListener(new SelectionListener() {
      public void widgetSelected(SelectionEvent e) {
        exit();
      }
      public void widgetDefaultSelected(SelectionEvent e) {
      }
    });
  }
}
Note that for executing SWT demos you must ensure that Java can access the SWT library. Usually this is done by adding the folder containing the SWT libraries to the Java library path using a command like this: -Djava.library.path=D:/java/eclipse/plugins/org.eclipse.swt.win32_3.0.0/os/win32/x86If you want to eliminate the need for specifying the classpath and java.library.path options in the Java command line you can integrate the SWT JAR and DLL (for Windows) with your Java Runtime Environment (JRE) by copying the jar files to the JRE's lib/ext directory and the DLL to the JRE's bin directory (the same procedure can be applied to other platforms). Refer to the SWT documentation for more detailed information.

5 Demo Runner

A Demo Runner is an application for browsing and launching demos. The JDemo framework contains a Swing based Demo Runner implementation that can be used as standalone application and can also be integrated into development environments for example.

I have already introduced the standalone program in section 1.9 and want to go into detail here. Chapter 6 will then describe its integration into the Eclipse IDE.

5.1 Launching

For launching the Demo Runner you have to run the DemoRunner class de.jdemo.swingui.DemoRunner and specify the fully qualified name of the demo class or demo suite, that shall be loaded, as argument:

java de.jdemo.swingui.DemoRunner org.foo.MyDemo
Note that both the jdemo.jar (or jdemo_core.jar and jdemo_runner.jar) and the demo class must be on the CLASSPATH.

If you want the users to be able to browse the demo source code from within the Demo Runner you can specify a source code lookup path using the -sourcepath or -sp option:

java de.jdemo.swingui.DemoRunner -sp src.zip org.foo.MyDemo
Similar to the Java CLASSPATH, the sourcepath is a list of directories and zipor jar files.

For a complete description of the command line parameters of the Demo Runner use this command:

java de.jdemo.swingui.DemoRunner -help

5.2 Usage

The Demo Runner mainly consists of two parts. In the upper half there is the demo tree and in the lower half there is the demo execution list:


Demos can be started by double clicking them in the demo tree (of course it also works with keyboard navigation). The states of the invoked demos (see section 3.2.2) are shown in the execution list below.

Advanced features are available through the popup menu of the tree:




Figure 5.3: The source code of the Hello World demo displayed in JDemo

The demo execution list has a context menu, too:

6 Eclipse Integration

This chapter has not been finished and will be extended in a future version of this document.

For the Eclipse (http://www.eclipse.org) IDE there is a plugin available on the JDemo website (http://www.jdemo.de) . Its implementation is based on the JUnit plugin (version v20030220a, some features and bugfixes from subsequent versions were adopted) and it offers support for JDemo in a similar way as the JUnit plugin does. The main difference is that there is no integrated JDemo view available. Instead the Swing based demo runner is launched in a separate window. However there are investigations going on to embed the runner in Eclipse by using its new feature for integrating AWT/Swing components in SWT.



Figure 6.1: JDemo as Eclipse-Plugin.

The following sections provide detailed description of the various extensions the Eclipse JDemo plugin offers. There are two versions of the plugin available: One that is Eclipse 2.1.x compatible and another one being compatible to the new 3.0 version. This documentation is based on the 3.0 compatible version of the plugin, so if you are using the other one you might experience a few features missing.

6.1 JDemo Wizards

There are three Wizards for creating demo specific stuff:

6.2 JDemo Launch Type

There is a new launch type for running demos, providing new launch menu items "Run as JDemo Demonstration" and "Debug as JDemo Demonstration".

You can select a DemoCase, a DemoSuite or even a source folder containing demos to be run. The demos are being collected and shown in the Demo Runner.

Selecting the context menu item "Show source code" in the Demo Runner will cause Eclipse to open the selected demo and show its source code.

6.3 Misc

6.3.1 Recreate Demo Suite

New Context menu item: "Recreate Demo Suite..." for Demo Suites in the Package Explorer. Updates the selected demo suite to the DemoCase implementations in the same folder.

6.3.2 Go to Referring Demos

Menu "Navigate Go To Referring Demos..." shows a list of all demos for the selected type or method. (This action must be enabled in "Window Customize Perspective..." )

This chapter has not been finished and will be extended in a future version of this document.

7 Capturing Demo Output

As stated in section 1.4, automated execution of demos is something that does not make sense in most situations. However there is one very important exception from this rule: During development of JDemo it has shown that there is a lot of potential in demos when requiring program output for documentation purposes. With demos providing a uniform way of showing program output and demo cases already being written for other purposes, it is only a small step to automatically capturing the output.

This chapter deals with the various options and preconditions about capturing demo output using JDemo.

7.1 Demo Identifier

For capturing demo output it is necessary to provide a fully qualified String representation of the demo case. So each demo has a unique identifier DemoIdentifier consisting of the fully qualified demo class name and the demo method name, separated by a colon. The Hello World demo from section 1.8 for example has the identifier de.jdemo.examples.HelloWorldDemo:demoHelloWorld.

7.2 Capturing Textual Output

Capturing the text output from a DemoCase class is the most simple option for capturing demo output. The class de.jdemo.capture.text.TextDemoCapture provides a simple API for this purpose:

   public static void captureText(
   
    DemoIdentifier demoId,
   
    Writer writerthrows Throwable;
   

   
public static void captureText(
   
    DemoCase demoCase,
   
    Writer writerthrows Throwable;
There are two static methods for capturing the output of the demo having the given demo id or the instantiated DemoCase object. The text output will be written to the specified Writer object.

7.3 Capturing File Output

A file created as demo output from within a DemoCase class can be copied to a specified file using the class de.jdemo.capture.file.FileDemoCapture:

   public static void captureFile(
   
    DemoIdentifier id, 
   
    File outputFilethrows Throwable {
   

   
public static void captureFile(
   
    DemoCase demoCase,
   
    File outputFilethrows Throwable {
   
Again there are two static methods for capturing the file of the demo having the given demo id or the instantiated DemoCase object. The file will be copied to the specified File object.

7.4 Making Screenshots

Much more interesting than capturing textual output is to take screenshots from GUI demo cases. The class de.jdemo.capture.gui.GuiDemoCapture provides an API that can be used with AWT and Swing DemoCases:

    package de.jdemo.capture.gui;
   

   
    public class GuiDemoCapture {
   

   
      public BufferedImage capture(
   
        DemoIdentifier demoId,
   
        boolean includeFrameTitle)
   
          throws DemoScreenCaptureException, DemoClassNotFoundException;
   
        
   
      public void capture(
   
        DemoIdentifier demoId,
   
        boolean includeFrameTitle,
   
        String format,
   
        File file)
   
          throws 
   
            DemoScreenCaptureException,
   
            DemoClassNotFoundException,
   
            IOException;
   
    }
The GuiDemoCapture provides two methods: The first one just creates and returns a BufferedImage object containing the screenshot. The second one also writes out the image to the specified file using the given image format. Again you need the demo id to qualify the demo case to be captured. With both methods you have the option to only capture the frame contents or to also include its borders.

Note that there are increased system requirements for creating screenshots. The current implementation uses the java.awt.Robot class from JDK 1.3 for taking the screenshot and the new Java Image I/O Framework provided by Sun since JDK 1.4. Taking screenshots is not possible on systems in headless mode. The supported file formats depend on the imaging plugins being installed on your system. However I recommend to use PNG since it should be available on any system and most probably fits the needs for screenshots from your program. JPG is another alternative if your program outputs a true color image like a photo for example.

Also don't forget to make sure that the display window from your demo is managed (see section 4.6).

7.5 Ant Tasks

At the moment one of the standard tools for Java software deployment is Jakarta Ant. As capturing demo output is something that can be very valuable for deployment, JDemo also contains wrapper classes, making capturing available as Ant tasks.

7.5.1 Capturing Text Output

The following snippet of an Ant build target defines the new Ant task demoTextCapture and uses it for capturing the output from the Hello World demo:

   <taskdef name="demoTextCapture"
       classname="de.jdemo.capture.anttasks.TextDemoCaptureTask"
       classpath="jdemo.jar" 
   />
   <demoTextCapture
        demoId="de.jdemo.examples.HelloWorldDemo:demoHelloWorld"
        outputFile="captured_text.txt">
        <classpath path="." />
   </demoTextCapture>
Running the Ant script should result in a file captured_text.txt being created and containing the text "Hello World" as the output from that demo.

The Ant task has two properties, described in table 7.1.

Parameter description required
demoId Id of the demo to capture the output from yes
outputFile File to write the result to yes

Table 7.1: Properties for the text capture Ant task

7.5.2 Capturing File Output

Capturing a file shown as demo output is just as simple as capturing text. Here is an example Ant code:

   <taskdef name="demoFileCapture"
       classname="de.jdemo.capture.anttasks.FileDemoCaptureTask"
       classpath="jdemo.jar" 
   />
   <demoFileCapture
        demoId="de.jdemo.examples.FileLauncherDemo:demoShowHtmlFile"
        outputFile="captured_file.html">
        <classpath path="." />
   </demoFileCapture>
Running the Ant script should result in a file captured_file.html being created and containing the text html content from the demo.

The Ant task has two properties, described in table 7.2.

Parameter description required
demoId Id of the demo to capture the output from yes
outputFile File to write the result to yes

Table 7.2: Properties for the filecapture Ant task

7.5.3 Making Screenshots

There is another Ant task available for making screenshots:

   <taskdef name="demoGuiCapture"
      classname="de.jdemo.capture.anttasks.GuiDemoCaptureTask"
      classpath="..."   
   />
   <demoGuiCapture
      demoId="de.jdemo.examples.dice.demo.MyDiceDemo:demoShowRandomDice"
      imageFormat="png"
      outputFile="captured_gui.png"
   />
Running this Ant script will result in a file dice6.png containing the screenshot from a die as shown in figure 1.2 (b). The various properties for this Ant task are described in table 7.3.

Parameter description required
demoId Id of the demo to capture the output from yes
outputFile File to write the result image to yes
imageFormat

The name of the image output format as
defined by the installed imaging library
(e.g. PNG, JPG)
no, defaults to
the extension of
the output file
includeTitle

Flag indicating whether the title of the
output window shall be included in the
screenshot or not (true or false)
no, default is true

lookAndFeelClassName The name of the look&feel class to be used no

Table 7.3: Properties for the screenshot Ant task

When capturing Swing demos you can specify the look and feel that shall be used by providing the lookAndFeelClassName parameter. Table 7.4 shows the class names for popular look and feels. For more information about look and feels with demos refer to section 4.9.

Name class name notes
Metal javax.swing.plaf.metal.MetalLookAndFeel Java CrossPlatform
CDE/Motif
com.sun.java.swing.plaf.motif.MotifLookAndFeel
can be used on
any platform
Windows

com.sun.java.swing.plaf.windows.WindowsLookAndFeel

only available on
Microsoft Windows
systems
GTK+ com.sun.java.swing.plaf.gtk.GTKLookAndFeel since JDK1.4.2
Mac com.sun.java.swing.plaf.mac.MacLookAndFeel

Table 7.4: Popular look&feels

7.5.4 Known limitations

Taking screenshots is a non trivial job, so there are some things you have to take care of:

7.6 Image processings

Some screenshots require image processings before the images fit the requirements for the web or for other documents. As an experimental feature the JDemo project contains a few Ant tasks for such kind of image processings. Since they actually work independent of JDemo, it is likely that I will move those tasks to a separate project soon.

7.6.1 Generic image processings

There is a generic Ant task ImageProcessingTask that can be used for applying a sequence of processings to an image. At present, scaling is the only processing implemented.

Here is an example that reads the file screenshot.png, scales the image to a width of 200 pixels using a smooth scaling algorithm and writes the resulting image to the file screenshot_small.png:

   <taskdef name="imageProcessing"
      classname="de.jave.image.ant.ImageProcessingTask"
      classpath="${classpath}"
   />
   <imageProcessing
         srcFile="screenshot.png"
         outputFile="screenshot_small.png">
      <rescale width="200" qualityHint="smooth" />
   </imageProcessing>
Table 7.5 describes the parameters of the ImageProcessingTask and table 7.6 describes the parameters of its nested element rescale.

Parameter description required
srcFile File to read the original image from yes
outputFile File to write the result image to yes
imageFormat

The name of the image output format as
defined by the installed imaging library
(e.g. PNG, JPG)
no, defaults to
the extension of
the output file

Table 7.5: Parameters for the image processing Ant task

Parameter description required
width

The width of the result in pixels or as percentage
of the original image.
(e.g. 800, 75%)
Exactly one of width
or height must be
specified.
height

The height of the result in pixels or as percentage
of the original image.
(e.g. 800, 75%)
Exactly one of width
or height must be
specified.
qualityHint

Rescale filter as defined by the java.awt.Image
class. Valid values are: Smooth, AreaAveraging,
Default, Replicate and Fast
no, default is Smooth


Table 7.6: Parameters for the nested rescale processing

7.6.2 Composing images

The ImageCompositionTask loads images from multiple files and arrages them to a new image. The size of the result image is the maximum extent of all positioned images. This task was used to create figure 4.7, which is a composition of four images captured using JDemo. Here is the source code from the Ant build script:

   <taskdef name="imageComposition"
      classname="de.jave.image.ant.ImageCompositionTask"
      classpath="${classpath}"
   />
   <imageComposition
        backgroundColor="FFFFFF"
        outputFile="${screenshot.dir}/lookandfeelbuttons.png">
      <image file="${tmp.dir}/laf_jdemo.png" x="0" y="0" />
      <image file="${tmp.dir}/laf_system.png" x="296" y="26" />
      <image file="${tmp.dir}/laf_crossplatform.png" x="269" y="95" />
      <image file="${tmp.dir}/laf_motif.png" x="296" y="169" />
   </imageComposition>
Table 7.7 describes the parameters of the ImageCompositionTask and table 7.8 describes the parameters of its nested element image.

Parameter description required
outputFile File to write the result image to yes
imageFormat

The name of the image output format as
defined by the installed imaging library
(e.g. PNG, JPG)
no, defaults to
the extension of
the output file
backgroundColor
The background color of the image to be created
as six-digit hexadecimal rgb value
No, default is FFFFFF

Table 7.7: Parameters for the image composition Ant task

Parameter description required
file File to read the original image from yes
x The x position to add the image at no, default is 0
y The y position to add the image at no, default is 0

Table 7.8: Parameters for the nested image element

Note that this Ant task could also be used for adding mouse cursors or other transparent images to decorate screenshots.

8 Demos as Unit Tests

Code that is not being used tends to break. Of course this is also true for demos. Fortunately there is a simple API for executing demos. This is why the JDemo library contains a class for converting demos to JUnit tests. So all your demos can be run automatically, ensuring that they don't throw exceptions when being run.

8.1 Automated conversion from demos to tests

The class de.jdemo.junit.Demo2TestConverter creates a JUnit testcase (or testsuite) from the given democase (or demosuite):

   public static Test createTest(IDemo demo);
The created unit test runs the demo and cancels it immediately. It fails if there is a java.lang.Throwable thrown during this procedure. It also stops with a timeout error if returning from the demo method takes very long. You can either use the default timeout value (30000ms in the current implementation of the framework) or specify the number of milliseconds when creating the test:

   public static Test createTest(IDemo demo, long timeOutMillis);

By using the methods above you can easily add demos to your suite of unit tests. You only have to add a single line of code to your main test suite:

   public class AllTests {
   
  public static Test suite() {
   
    TestSuite suite = new TestSuite();
   
    suite.addTest(Demo2TestConverter.createTest(AllDemos.suite()));
   
    //add other test suites...
   
    return suite;
   
  }
   
}

This code converts all demos contained in the main demo suite AllDemos to tests and adds them to the suite of tests.

8.2 Peculiarities with demo-tests

There is one peculiarity when executing tests based on demos that show a file using the show(File) method in the DemoCase class: The file is not being shown in an external browser but instead it is only being checked whether the file exists. If it does not exist, the test fails.

8.3 Evaluation

Tests created from demos are nothing more than smoke tests. They only fail when something goes terribly wrong but by no means guarantee that the demo does what it should.

However on the other hand those demo-tests are for free, and by ensuring that all demos can be executed, they will help you to prevent some of the most embarrassing kind of bugs in demo code. So all in all I think its worth using them.

9 Annotating Demos

When working in a Java 5 (Tiger) environment, JDemo methods can be annotated using the Java annotation feature. This allows us to add comments or other information, that can be used by Demo Runner applications during runtime.

9.1 JDemo Annotation

The JDemo annotation is defined as follows:

package de.jdemo.annotation;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})

public @interface JDemo {
  public String description() default "";
  public String[] categories() default {};
}
The annotation contains two optional elements:

9.2 Example

Here is a simple example using the JDemo annotation feature:

@JDemo(
  description = "<h1>Hello World</h1><p>Prints &quot;Hello World!&quot;.</p>",
  categories = "example""public" }  
)
public void demoHelloWorld() {
  show("Hello World!");
}
The example adds a HTML description to the demo method and assigns it to the categories exampleand public. Note that there are no predefined categories in the framework.

The JDemo Demo Runner can be configured to show descriptions from annotations in an additional panel on the right (Use the View menu to adjust this setting):


10 Contributing to JDemo

Any kind of bug reports, comments and enhancements are welcome. You can send me a mail containing any of these to markus@jdemo.de or report them on the SourceForge site at http://sourceforge.net/projects/jdemo/.

10.1 JDemo CVS

The source code of the complete JDemo framework is contained in the download package. You can also access the most current version from the SourceForge CVS (http://sourceforge.net/projects/jdemo/). There you will have to check out the following projects:

Project Contents
JDemo The core project for the framework
JDemo_build Build script for compilation and deployment
JDemo_swingrunner The Swing based demo runner application
JDemo_examples The examples
JDemo_thirdparty Thirdparty libraries required for JDemo and deployment
JDemo_tiger JDK 1.5 (Tiger) related classes e.g. for Annotations
JDemo_imageprocessing Image processing code for screen capture and Ant tasks
JDemo_eclipse
Eclipse plugin for Eclipse 3.0/3.1
(there also is a branch for the 2.1 version)

The JDemo_eclipse and JDemo_examples projects are optional. In order to build JDemo you can use the Ant build script from the JDemo_build project. For a full build you will need both a JDK1.4 and a JDK1.5 compiler. You must specify the paths to your compilers by creating a properties file system_dependent_build.properties. There is a template for this file in the build project.

10.2 Writing your own DemoRunner

Unless you have a very brillant idea for a new demo runner, I recommend contributing to the existing one. However if you want to write your own runner you are welcome to do so, too. Look at the source code of the original demo runner to get an idea of how to build the tree etc. Some utility methods for instantiating a demo can be found in the class de.jdemo.framework.util.DemoUtilities. Once you have an instance myDemoof a JDemo demo you can launch using code somewhat like this:

   IDemoCaseRunnable runnable = myDemo.createRunnable();
   
runner.addDemoStateChangeListener(new IDemoStateChangeListener() {
   
  public void demoStateChanged(IDemoStateChangeEvent event) {
   
    //Do whatever appropriate for the state change happened
   
  }
   
});
   
new Thread(runnable).start();

10.3 Integrating the DemoRunner into other Applications

At the moment Eclipse is the only IDE supporting JDemo by a plugin (see chapter 6). Supporting other development environments should not be hard to be done. The wizards for creating demo cases and suites can be implemented similar as the existing ones for JUnit support. Launching demos should be done by launching the existing Runner. Feel free to ask me if you have any questions about this.

11 Future Development

This chapter is meant for gathering ideas for the future development of the JDemo framework. Feel free to send me comments or share your ideas, too.

11.1 Batch Capture

An additional Ant task for capturing complete suites instead of single demos (see chapter 7) would be nice. Also optionally a Html page should be created, containing the captured images (or links to captured files).

11.2 Executing Sequences of Demos

JDemo demos are unit demos: one demo case can only demonstrate a single unit - either a dialog or an exported file, for example, but not both together. In some situations I would like to be able to connect multiple demos to a more complex scenario.

Example: Given we have two demos, one that displays a dialog for entering information, and a second one for demonstrating some kind of file export. The file export works with some demonstration data, but would also work with the information that has been entered in the first demo. In this situation I would like to be able to (optionally) connect both demos, so that the user can enter the data in the dialog and also sees the exported file afterwards.

I do not yet have any idea about how to make this work. On the other hand I am also not really sure if I want to allow such complex kind of interaction. The power of JDemo is its simplicity and I cannot imagine a simple solution here. However any kind of ideas or comments are welcome.

12 About this Document

This document has been written in PDFLaTeX under MiKTeX using the ecleTeX plugin (http://sourceforge.net/projects/etex/) in the Eclipse 3.1 IDE.

The Java and Ant code snippets have been converted to LaTeX using Java2Html (http://www.java2html.de).

Diagrams have been created using the Win32 version of Dia(http://www.gnome.org/projects/dia/).

The HTML version of this document has been automatically generated from the TeX source files using a simple tool I have written (I am not planning to release this tool, since it has lots of restrictions).

All screenshots in chapters 1, 2, 4and 5 have been created automatically using the JDemo Ant tasks described in chapter 7. The same is true for the decorated icons in section 3.2.2.

Converted from PDFLaTeX to HTML 2005-01-08 using PDFLaTeX2Html 1.0

Valid XHTML 1.0!