JIDE Desktop Application Framework - Tutorials

Introduction

Welcome to the the JIDE Desktop Application Framework (JDAF) Tutorial page! This page is intended to show the basics of using JDAF. Download the full evaluation copy of the JDAF product and dig into the comprehensive Developers Guide and JavaDoc for a greater understanding of this material. The source for these tutorials are included in the evaluation copy. Also, try out the JDAF Application Wizard, which is a code generation wizard that will frame-out a JDAF application for you.

Abstract

Making a small frame-based Swing application is fairly straightforward. Most developers are comfortable with classes like JFrame and the normal palette of Swing Components. You may even be familiar with our JIDE family of Swing Components. However, things start to get out of hand quickly when an application gets larger. For example, introducing the concept of multiple documents starts one down a path of requirements such as data management, menu wiring, dialog negotiations, and window management. This behavior is expected by users but has little to do with core application functionality, yet it takes a significant amount of time and resources to accomplish. Compound this with the challenges of cross-platform deployment such as OS Guidelines integration and varying Java VM versions and implementations and you suddenly have a non-trivial venture.

The goal of the JDAF was to solve these real-world problems. With a Model-View-Controller (MVC) architecture and our ground-breaking Managed Application UI technology, you can focus on your core application functionality and not get mired in the escalade of details required to implement a non-trivial application.

The following examples are intended to illustrate how easy it is to start creating a robust, fully-featured application in Java using the JIDE Desktop Application Framework, while explaining the fundamentals of using it.

Overview

The use of JDAF centers around the DesktopApplication class. JDAF supports two types of applications through the subclasses GUIApplication and ConsoleApplication. You may either subclass these or use them as instances. In these examples, we will always use the instance as opposed to subclassing for sake of illustration, if for no other reason.

The following examples are intended to provide a brief introduction to using the JDAF to create GUI applications.

Tutorial 1: HelloGUIWorld.java

Let's start with a "Hello World" example. JDAF is a MVC architecture. DesktopApplication is the Controller. For GUI applications we use the subclass GUIApplication. So, the first thing to do is instantiate a GUIApplication:

GUIApplication application = new GUIApplication("HelloGUIWorld");
                                        

Next we need to provide a Model for our application. This is facilitated by the DataModel interface. DataModel facilitates the lifecycle of data in an application. JDAF provides a basic implementation with the BasicDataModel. This class has a data property to store your user data. For our example, the String "Hello World!" is our data.

public class MyModel extends BasicDataModel {
	public void newData() {
		setData("Hello World!");
	}
}
                                        

Here, we have implemented new behavior, since this is the only requirement. You may implement other methods such as openData(), saveData(), resetData() and closeData(). The GUIApplication is pre-wired to call these methods as appropriate from the UI. You may additionally register a DataModelListener with the GUIApplication to monitor all DataModel lifecycles.

In a real-world application, models needs to be generated on demand, say from a menu or at application startup. There may even be different kinds of models as well. JDAF facilitates this with the DataModelFactory class. It is necessary to set one or more of these in the GUIApplication to tell it how to create a DataModel in response to input criteria. JDAF provides some DataModelFactory implementations for immediate productivity. For this example we'll use the BasicDataModelFactory which allows us to vend a DataModel using its Class alone.

application.addDataModelFactory(new BasicDataModelFactory(MyModel.class));
                                        

Next we need to provide a View for our model. JDAF automatically manages the model-view relationship in your application, which in a GUI application means managing the windowing architecture, so all you need to do is supply the content for the view. This is facilitated by the DataView interface. JDAF provides a default implementation for a GUIApplication called DataViewPanel. This Component is based off JPanel and provides some strategy methods.

public class MyView extends DataViewPane {
	JLabel label;
	protected void initializeComponents() {
		label = new JLabel();
		label.setFont(new Font("serif", Font.PLAIN, 24));
		add(label, BorderLayout.CENTER);
	}
	public void updateView(DataModel dataModel) throws DataModelException {
		label.setText((String)dataModel.getData());
	}
}
                                        

The initializeComponents() method is where we create components. The updateView() method is called to cause the view to reflect the model. (There is a corresponding updateModel(), but that is inapplicable here.) Notice how we pass our data into the view. The DataModel.getData() will return our "Hello World!" value and place it in the JLabel.

As previously discussed, the GUIApplication is responsible for generating models and views. A corresponding DataView should be generated for each DataModel. This is accomplished using a DataViewFactory. We will add a BasicDataViewFactory which allows us to vend our DataView by Class.

application.addDataViewFactory(new BasicDataViewFactory(MyView.class));
                                        

You may register a DataViewListener with the GUIApplication to monitor all DataView lifecycles. The GUIApplication is now configured. The last thing to do is run it! This is accomplished with a call to the run() method.

application.run(args)
                                        

Here is the entire HelloGUIWorld application:

public class HelloGUIWorld {

    public static void main(String[] args) {
        GUIApplication application = new GUIApplication("HelloGUIWorld");
        application.addDataModelFactory(new BasicDataModelFactory(MyModel.class));
        application.addDataViewFactory(new BasicDataViewFactory(MyView.class));
        application.run(args);
    }

    public static class MyData extends BasicDataModel {
	   public void newData() {
		   setData("Hello World!");
	   }
    }

    public static class MyView extends DataViewPane {
        JLabel label;
        protected void initializeComponents() {
            label = new JLabel();
            label.setFont(new Font("serif", Font.PLAIN, 24));
            add(label, BorderLayout.CENTER);
        }
        
        public void updateView(DataModel dataModel) throws DataModelException {
            label.setText((String)dataModel.getData());
        }
    }
}
                                        

Here is the result on various platforms:

What's this? Menus, Toolbars? Yes, and they are fully operational! This is the result of the Managed Application UI technology. Out of the gate your application has a significant amount of functionality. Notice the differences in window titling, icon themes, and menu and toolbar configurations. This GUI will configure differently based on where it is run, while retaining equivalent functionality. Each configuration is based on OS Guidelines and case studies. (See the screen shots here to see the difference in menu configurations.) This application will satisfy OS Guidelines on each platform, which means that the end user has a seemless experience on their platform with your Java application. Talk about extreme GUI programming!

Tutorial 2: PlainTextEditor.java

Let's do something a little more substantial. We'll create a plain text editor. The point is to illustrate the most common manifestation of a real-world desktop application; the Document-Centric or File-Based Application. With this example we'll illustrate a usability subclass of GUIApplication called the FileBasedApplication. This application will read and write text files.

The first thing we do is create the application instance, similar to the way we created a GUIApplication in the previous example:

FileBasedApplication application = new FileBasedApplication("Plain Text Editor");
                                        

FileBasedApplication manages your models for you by managing the loading and saving of data to/from files using a FileDataModelFactory and FileDataModel. FileDataModel is similar to BasicDataModel in that it maintains data in the data property, accept the data in this case is sourced from a File. More on this later.

Let's define our view for the text. Since this is plain text, we'll make a DataView using a common Swing Component; JTextArea.

public static class TextView extends DataViewPane {
   private JTextArea textArea;
   private DocumentListener docListener;
   protected void initializeComponents() {
          
       // sets the window size
        setPreferredSize(new Dimension(550, 400));
        setBackground(Color.WHITE);
        setBorder(null);
        
        // init text area
        textArea = new JTextArea();
        textArea.setFont(textArea.getFont().deriveFont(12f));
        textArea.setWrapStyleWord(true);
        textArea.setLineWrap(true);
        docListener = new DocumentListener() {
           public void insertUpdate(DocumentEvent e) {
              makeDirty(true);
           }
           public void removeUpdate(DocumentEvent e) {
              makeDirty(true);
           }
           public void changedUpdate(DocumentEvent e) {
              // unnecessary for plain text
           }
        };
        textArea.getDocument().addDocumentListener(docListener);
        textArea.setBorder(BorderFactory.createEmptyBorder(4,10,4,4));
        JScrollPane scrollPane = new JScrollPane(textArea);
        scrollPane.setBorder(null);
        scrollPane.setOpaque(false);
        add(scrollPane);
        
        // install editing features
        EditUtils.installEditTooling(getApplication(), textArea);
    }
    
    public void updateView(DataModel dataModel) {
       FileDataModel fileDataModel = (FileDataModel)dataModel;
       textArea.getDocument().removeDocumentListener(docListener);
       textArea.setText(fileDataModel.getData() != null ? fileDataModel.getData().toString() : "");
       textArea.setCaretPosition(0);
       textArea.getDocument().addDocumentListener(docListener);
    }

    public void updateModel(DataModel dataModel) {
       FileDataModel fileDataModel = (FileDataModel)dataModel;
       fileDataModel.setData(textArea.getText());
    }
}
                                        

In the initializeComponents() method we basically create the JTextArea and place it in a JScrollPane. Since the view size is indeterminate, we set it with setPreferredSize() explicitly. The managed UI will obey this setting when hosting the view. A few lines of code require explaination. The DocumentListener is used to dirty the DataModel when content changes. This flags the application that the model has changed and is a candidate for saving. The code EditUtils.installEditTooling(getApplication(), textArea) is used to integrate our text component into the Edit menu. See the Developer's Guide for more details. Notice in updateView() and updateModel() we simply pass back and forth the text data.

As mentioned previously, FileBasedApplication manages models automatically. Models will be of the type FileDataModel. This class contains two important members; File and FileFormat. With FileBasedApplication, to support a given type of data you provide a FileFormat, to read and/or write the data, and a DataView, to display and/or edit the data. We've just created a DataView to handle text, all we need then is a FileFormat to read and write the text. The JDAF provides some basic FileFormat classes, and creating new ones is trivial provided you can work with the file format. One FileFormat we supply is TextFileFormat. Here is the code to tell the application that its supports text files and should use our TextView to view them.

application.addFileMapping(new TextFileFormat("txt", "Text"), TextView.class);
                                        

That's it. You can add as many FileFormat/DataView combinations as you like. The application UI will adapt appropriately. See the Developers Guide for more details.

Finally, we run the application.

application.run(args)
                                        

Here is the entire Plain Text Editor application:

public class PlainTextEditor {

    public static void main(String[] args) {
      FileBasedApplication application = 
                  new FileBasedApplication("Plain Text Editor");
      application.addFileMapping(
                  new TextFileFormat("txt"), TextView.class);
      application.run(args);
    }
   
    public static class TextView extends DataViewPane {
       private JTextArea textArea;
       private DocumentListener docListener;
       protected void initializeComponents() {
             
          // sets the window size
           setPreferredSize(new Dimension(550, 400));
           setBackground(Color.WHITE);
           setBorder(null);
           
           // init text area
           textArea = new JTextArea();
           textArea.setFont(textArea.getFont().deriveFont(12f));
           textArea.setWrapStyleWord(true);
           textArea.setLineWrap(true);
           docListener = new DocumentListener() {
              public void insertUpdate(DocumentEvent e) {
                 makeDirty(true);
              }
              public void removeUpdate(DocumentEvent e) {
                 makeDirty(true);
              }
              public void changedUpdate(DocumentEvent e) {
                 // unnecessary for plain text
              }
           };
           textArea.getDocument().addDocumentListener(docListener);
           textArea.setBorder(BorderFactory.createEmptyBorder(4,10,4,4));
           JScrollPane scrollPane = new JScrollPane(textArea);
           scrollPane.setBorder(null);
           scrollPane.setOpaque(false);
           add(scrollPane);
           
           // install editing features
           EditUtils.installEditTooling(getApplication(), textArea);
       }
       
       public void updateView(DataModel dataModel) {
          FileDataModel fileDataModel = (FileDataModel)dataModel;
          textArea.getDocument().removeDocumentListener(docListener);
          textArea.setText(fileDataModel.getData() != null ? fileDataModel.getData().toString() : "");
          textArea.setCaretPosition(0);
          textArea.getDocument().addDocumentListener(docListener);
       }
   
       public void updateModel(DataModel dataModel) {
          FileDataModel fileDataModel = (FileDataModel)dataModel;
          fileDataModel.setData(textArea.getText());
       }
   }
}
                                        

Here is a screenshot:

(Using the "Java Cross Platform" Application UI)

If you run this application you will experience fully-featured document behavior, including open and save dialogs, various standard dialogs such as save alerts, file replace and about 18 other file-related validations. On various platforms you may experience a summary save alert on Mac OS X and Linux/Gnome, if more that one document is dirty. On Gnome you'll see the document age in various file dialogs. You may experience other effects on some platforms like visual queues when a document is dirty, either in the title or the window decorations. If you can experience the application on various platforms note the differences in document titling semantics as well.

Swing Look and Feel and JDAF

This is a good time to discuss the relationship between Swing Look and Feel and the JDAF Managed Application UI. One of the goals of JDAF is to facilitate the best possible cross-platform OS integration. This is accomplished using the combined effects of the System Default Swing Look and Feels and our Managed Application UI. In other words, these two technologies work collectively to facilitate a high-degree of believability on a given platform. Be aware that changing the Look and Feel alone will not change the behavior of the Application UI, which follows OS Guidelines. So we recommend that on platforms where the System look and feel is appropriate, go with it.

However, there are always exceptions. For example, in the event that JDAF does not support a given OS/platform, the Java Cross-Platform Application UI is used, which conforms to the Sun Java Look and Feel Guidelines and hence uses the Metal Look and Feel. Changing the Look And Feel here may be acceptable, but keep in mind that the Sun Java Look And Feel Guidelines concerning application behavior will still be enforced.

In the event that your project requires a consistent Look And Feel on all platforms, you can set the "usecp" System property to "true", then all platforms will use this Cross Platform Application UI.

Another clear example is Windows XP, where one encounters varying application UIs, even within Microsofts own product lines. (In the Vista Guidelines, Microsoft is encouraging more consistency). If you are familiar with JIDE products then you are aware of the many Look and Feels available for Windows OS. These Look and Feels give your application that polished look on Windows XP.

If you desire to change the look and feel, let's discuss the proper way to do so in JDAF. When GUIApplication.run() is called, ultimately the managed UI will startup, which will set the Look and Feel. On Windows, JDAF installs VSNET and modern XP icons by default if in XP mode. If using Classic mode, the normal Look and Feel is used with Classic icons. If you set the Look and Feel before a call to run(), JDAF will override your settings because of the managed UI. So first we must turn off this behavior in the GUIApplication. This is done in the ApplicationUIManager, which implements the UI of the GUIApplication, like so:

application.getApplicationUIManager().setLookAndFeel(false);
                                        
Note: This setting is turned off if you define the "swing.defaultlaf" System property. Again, we do not recommend doing this unless you are branding your application to look the same on all platforms. In which case you should also pass the option "usecp". This will force the Cross Platform Application UI to be used on all platforms.

Now we can set a special Look and Feel on Windows:

LookAndFeelFactory.setDefaultStyle(LookAndFeelFactory.XERTO_STYLE);
LookAndFeelFactory.installDefaultLookAndFeelAndExtension();
                                        

Another decision the managed UI makes is whether icons should appear in the menus or not. So let's make this setting to:

application.getApplicationUIManager().getMenuBarsUI().setShowIcons(true);
                                        

Here are the changes to the main() method from our previous example:

public static void main(String[] args) {
    FileBasedApplication application = new FileBasedApplication("Plain Text Editor");
    application.addFileMapping(new TextFileFormat("txt"), TextView.class);
    if(SystemInfo.isWindows() && XPUtils.isXPStyleOn()) {
	    application.getApplicationUIManager().setSetsLookAndFeel(false);
	    application.getApplicationUIManager().getMenuBarsUI().setShowIcons(true);
	    LookAndFeelFactory.setDefaultStyle(LookAndFeelFactory.XERTO_STYLE);
	    LookAndFeelFactory.installDefaultLookAndFeelAndExtension();
    }
    application.run(args);
}
                                        

Here are the results on Windows XP:

Next Steps

Now that you have been exposed to the power of the Managed UI, we hope you can appreciate the value that it will add to your projects, not only in time, but in the success of your cross-platform application. The next steps are up to you, your requirements and imagination.

These examples introduced you to working with the JIDE Desktop Application Framework to create GUI Applicatons. We have only scratched the surface of the JDAF capabilities. For example, JDAF supports clean integration with our other framework products such as the JIDE Docking Framework and JIDE Action Framework.

To point you in the right direction, in the JDAF, the primary means of providing application-specific behavior to GUIApplication is by attaching various listeners, customizers, Actions, factories and other objects to your DesktopApplication instance. This encourages a method of application development that produces quality, reusable, and maintainable codebases. Following is a list of classes you may wish to explore:

Class/Interface Description
ApplicationLifecycleListener Listen to the application lifecycle
DataModelListener Listen to the data lifecycle
DataViewListener Listen to the view lifecycle
DialogListener Listen to dialog activity
MenuBarCustomizer Customize standard menus and create your application menus
ToolBarCustomizer Customize standard toolbars and create your application toolbars
WindowCustomizer Customize windows on open and close
DataModelFactory Create data in response to application requests
DataViewFactory Create views in response to application requests
PrintSource Provide a Pageable instance for printing in response to application requests
HelpSource Invoke your help system in response to application requests
ApplicationFeature A super-adapter made up of JDAF listeners and customizers that can be added to a GUIApplication to create reusable cross-cutting functionality
Resources Read and convert resource bundle values, bind resources to objects

Tutorial 3: ImageViewFeature.java

Jumping ahead to a more advanced topic of ApplicationFeatures, we put this class together called ImageViewFeature. It will embue the PlainTextEditor application with the ability to open jpeg, gif, png, and bitmap images. It also installs a image preview (where supported) into the open file dialog. Simply add this line of code to the example class before calling run(args).

application.addApplicationFeature(new ImageViewFeature());
                                        

This is a good example of mixing DataModel/DataViews. We leave this class to explore on your own.

Example 4: HelloConsoleWorld.java

JDAF is equally capable of creating Console applications. Console applications, or command-line applications, remain relevant due to their ability to provide functionality without the overhead of UI development. In fact, on many platforms, GUI applications are actually front-ends to the "command-line" versions.

Using JDAF to create console applications gives you the benefits of a MVC architecture and an object-oriented API that facilitates the command-driven nature of console applications much better than large switch or if statements necessary by handle-written ones. You also get built-in file-handling, printing, and help system commands, so you can get right down to the required functionality.

A command-line application in JDAF centers around the ConsoleApplication class. Creating our "Hello World" then starts with creating this object:

ConsoleApplication application = new ConsoleApplication("Hello World!");
  
Let's just run it and see what we get.
application.run(args);

Here we took advantage of the fact that by default ConsoleApplication announces the name and version of the application on startup. Also notice that we are on a new line, ready to take the next command. For example, to quit this application we type "exit".

ConsoleApplication is command-driven. Commands are facilitated by the ConsoleCommand class. By typing "exit" and hitting enter, the ExitCommand was located and executed to terminate the program.

Likewise, every command typed into the console will attempt to be matched with a ConsoleCommand object and executed. If a command cannot be found, the IdleCommand is executed. The IdleCommand has no prompt, so will simply look like a new line in the console. But it actually takes the last console input and attempts to find a ConsoleCommand to recover the program flow. Below, we typed a few new lines and nonsense commands, but where finally able to resolve the "exit" command.

Let's change the code a little to do a proper command that prints "Hello World!" and let's do it MVC style by creating a model:

public static class MyModel extends BasicDataModel {
   public void newData() {
      setData("Hello World!");
   }
}
                                        

There is no need to create a DataView as ConsoleApplication provides one for us called ConsoleView to represent the command prompt. More on this later. Now our constructor looks like this:

ConsoleApplication application = 
  new ConsoleApplication("HelloConsoleWorld", MyModel.class);
                                        

Creating a ConsoleCommand is simple, it's an Action class. All you do is implement actionPerformed() and add it to the application using putCommand("command", ConsoleCommand). Here we create and add a ConsoleCommand with the command name "sayhello".

application.putCommand("sayhello", new ConsoleCommand() {
  public void actionPerformed(ActionEvent e) {
     getConsole().writeLine("Hello World!");
  }
});
                                        

Here is the total source for our "Hello World" console application:

public class HelloConsoleWorld {
   public static class MyModel extends BasicDataModel {
      public void newData() {
         setData("Hello World!");
      }
   }
   
   public static void main(String args) {
      ConsoleApplication application = 
          new ConsoleApplication("HelloConsoleWorld", MyModel.class);
      application.putCommand("sayhello", new ConsoleCommand() {
        public void actionPerformed(ActionEvent e) {
           getConsole().writeLine("Hello World!");
        }
      });
      application.run(args);
   }
}
                                        

Here are the results:

There is no need to create a DataView, in one sense because our view is provided by the Java console, in another because ConsoleApplication always provides a DataView implementation called ConsoleView. This view is our proxy to the Java console. As can be seen in the previous example, we can write to this object to get information to the console. While console writing is trivial, ConsoleView provides many beneficial features such as formatted writes using both MessageFormat and our own UL-language based ObjectFormat, as well as being able to write data as tables.

Tutorial 5: ConsoleFlowDemo.java

In this example we will dig more into how command flow operates in a ConsoleApplication as well as introducing the powerful console input facilities of ConsoleView.

As mentioned previously, if a command cannot be found, the IdleCommand is executed. Hence, this command can be thought of as a safety net and as a default command. You could replace the IdleCommand (but not remove it), or better yet, set its prompt. This is a great way to implement a "menu" that will always show in the absence of another command, instead of an empty line. Since we are going to create a handful of comands in this example, let's use this convention:

ConsoleCommand idle = (ConsoleCommand)application.getActionMap().get(IdleCommand.KEY);	
idle.setPrompt("Enter a command: ");
                                        

Reading and Writing To Console

ConsoleApplication automatically provides a DataView called ConsoleView. As can be seen in the previous example, we can write to this object to get information to the console. ConsoleView has many read and write methods. In fact, perhaps the most powerful feature in the console API are the blocking write methods. These methods write to the console and block until the user enters the correct data. By "block" we mean that the prompt repreats until the correct data is input. Consider this command:

application.putCommand("int", new ConsoleCommand("Enter an integer: ") {
  public void actionPerformed(ActionEvent e) {
     int n = getConsole().readInt();
     getConsole().writeLine("You entered " + n);
  }
});
                                        

Notice in this example we placed the prompt in the constructor of the ConsoleCommand. This is an optional technique. You could just as easily prompt by writing to the ConsoleView with one of the many write methods.

This command will block until an int is input in the console. There are blocking reads for Strings and all the Java primitive types, and some special case character types. Here is one for a letter:

application.putCommand("letter", new ConsoleCommand("Enter a letter: ") {
  public void actionPerformed(ActionEvent e) {
     char n = getConsole().readLetter();
     getConsole().writeLine("You entered " + n);
  }
});
                                        

Objects can be parsed as well via ObjectConverters. Here we ask for a value that needs to resolve to a Point:

application.putCommand("point", new ConsoleCommand("Enter a Point (x,y): ") {
   public void actionPerformed(ActionEvent e) {
      Point p = (Point)getConsole().readObject(Point.class);
      getConsole().writeLine("You entered " + p);
   }
});
                                        

You can also facilitate your own custom blocking read using a ConsoleInputValidator. Consider this command that necessitates a number between 1 - 5:

application.putCommand("range", new ConsoleCommand("Enter a Number (1 - 5): ") {
   public void actionPerformed(ActionEvent e) {
      CommandString s = getConsole().readInput(new ConsoleInputValidator() {
         public boolean validateInput(CommandString input) {
            if(input.validate(int.class, 0)) {
               int n = input.getInt(0);
               return n >= 1 && n <= 5;
            }
            else {
               return false;
            }
         }
      });
		
      getConsole().writeLine("You entered: {0}", 
                 new Object[]{new Integer(s.getInt(0))});
   }
});
                                        

Here we use another Object in the ConsoleApplication API; CommandString. This is a powerful command-line parser that simply wraps a String. It provides significant command-line validation and parsing capabilities. The readInput() method returns the input String as a CommandString. In this case, our custom validator made sure it was an int, then parsed the int to do the range check. Also notice the writeLine() signature that accepts a MessageFormat pattern.

Control Flow

There are many ways to control flow in the console applicaton. For example, you can control program flow with the readResponse() methods. These are blocking reads that facilitate command-line dialogs with the user and work with the same constants used with dialogs in the GUIApplication. Here we will direct the user to different actions based on their response.

application.putCommand("choose", new ConsoleCommand() {
   public void actionPerformed(ActionEvent e) {
      int response = getConsole().readResponse("Do This?", YES_NO_DIALOG);
      if(response == RESPONSE_YES) {
         setNextCommand("this");
      }
      else {
         setNextCommand("that");
      }
   }
});

application.putCommand("this", new ConsoleCommand() {
   public void actionPerformed(ActionEvent e) {
      getConsole().writeLine("You did this");
   }
});

application.putCommand("that", new ConsoleCommand() {
   public void actionPerformed(ActionEvent e) {
      getConsole().writeLine("You did that");
   }
});
                                        

In this example we use a couple of flow control devices. First we used the blocking dialog response read via readResponse(). Notice how it supplies the options. Also notice the forgiving interpretation of the response. "Yes" would have worked for "Y", "y" and "ok", too.

The other flow control device we use here, and more importantly, is the setNextCommand() method. Remember that the ConsoleApplication is command-driven. A ConsoleCommand will only execute once. The application will then look for another command to execute based on the input buffer. If a command cannot be found, the IdleCommand is executed, as mentioned before. Therefore, as we have done in this example, you can move from command to command by calling setNextCommand() to tell ConsoleApplication the next command to execute. You can also call resetCommand() , which allows you to develop commands that bounce back to the caller, which could be a menu or submenu command.

Next Steps

As you can see, there is plently of convenience and power here in the ConsoleApplication. We havn't reviewed the built-in commands that provide data management, help, and printing. Just try typing "help" to inspect these commands. There is plenty to explore. Here are some classes you may wish to review:

Class/Interface Description
ApplicationLifecycleListener Listen to the application lifecycle
DataModelListener Listen to the data lifecycle
ConsoleViewListener Listen to the ConsoleView context switches
ConsoleCommand Implement to provide a command to the application
DelegatingCommand Use to execute command methods in another class to reduce class count
ExternalCommand Execute OS-specific processes
CommandInputValidator Create custom blocking-reads
ConsoleFilter Filter all i/o to/from the view
Resources Read and convert resource bundle values, bind resources to objects

We're sure this API will get you going fast with that next command-line application.

Closing

We encourage you to download, experiment, or make an application yourself with the JIDE Desktop Application Framework. The Developer Guide is thorough and even includes a migration guide if you have an "at risk" project and are looking for alternatives.

Minimum JDAF Requirements:
- jide-jdaf.jar
- jide-commons.jar (2.1.2+)
- jlfgr_1_0.jar (Java Look and Feel Graphics Repository. Used by the Cross Platform Application UI)

JSR-296 Compatibility

For those of you who are keeping an eye on the work being done by Hans Muller and the group on JSR-296, we currently provide a JSR-296 wrapper API that will allow you to you use both JSR-296 and JDAF.