Understanding Echo

Monday May 22nd 2006 by Mugdha Vairagade
Share:

Discover a free Java-based Open Source framework that helps build Web applications that are as good as feature-rich, rich-client applications and are modular and event-driven.

With this article you will gain an understanding of Echo by reviewing its benefits, discovering how it works, and learning how to build an application. The material is meant for Web developers who are looking for better/free/Open Source/Java-based Web development tools & APIs. Knowledge of Java programming (JDK 1.3 or higher) and Servlets would be helpful to understand this article.

Developing an application for the Web has many advantages. Web applications have a short development cycle and are low cost. Also, Web applications are ideal for multi-user scenarios (due to zero-cost-per-client advantage), where many users access a central application through the Internet or an intranet using a Web interface (for example, timesheet recording at offices, customer care help desks, collaboration tools, and so forth). Now, even traditional rich-client (desktop-based) applications for tasks such as word processing, spreadsheets, and presentation making are also available online as Web applications.

Limitations of Web Applications

Web applications score heavily on many counts over rich-client applications that are complex, take lots of time to build, and are costly. But, Web applications do have a few serious drawbacks that force developers to move towards rich-client applications.

Web applications are page-based and non-modular. This makes modifications and upgrading difficult because developers have to go through a maze of Web pages to make necessary changes.

Because the Web is essentially stateless, developers have to do some extra work to save state—session/user-specific data for each Web page viewed, to maintain continuity (return to page viewed last)—or user-specific customization as in rich client applications. A significant amount of code is devoted simply for saving state data.

To make a Web application interactive, a sophisticated event generation and handling mechanism is required; it is available only through scripting (written in JavaScript, VBScript, PHP, CGI, and so on). Complex scripting must be embedded in the desired Web pages to add event-based functionality (for example, displaying sub options on selection of form elements, pre-submission form data validation, and the like), thus increasing page size and coding time. These scripts are mostly non-modular and non-reusable. This drawback also makes developing multi-window/multi-frame web applications difficult because tracking events across multiple windows/frames is highly error-prone.

Web applications send user input (form data) to the server, encoded as HTTP request parameters. Server-side scripting is used to parse and validate these parameters for each HTTP request. In case of multiple forms, a corresponding number of server-side scripts is required, one script for each form. Thus, a significant part of application code is dedicated to this repetitive task.

To create a Web application that is feature-rich and multi-modal such as a rich client application, developers must overcome these limitations. Echo, a free Java-based Open Source framework, helps to do just that.

What Echo Has to Offer Web Developers

The Echo framework is basically an API that provides ready-made components for developing Web applications. The Echo framework consists of two separate tiers, The Component Framework and The Application Container. These two tiers separate the concern of event-driven Web interface development from actual coding requirements to represent the same in a browser environment.

The component framework

The Component Framework tier, which is an API, provides a user interface toolkit (similar to the Java SWING API) for developing a Web user interface or Web UI, which is feature-rich and event-driven like a rich client application. Just like SWING, this toolkit contains ready-made and reusable UI components. Developers can put together these components, such as Window, ContentPane, Button, and so forth, or create custom components by deriving from these components to create a Web UI rapidly. Developers can also "add" Listeners to any such UI component to listen to and handle any events generated by the component (again, like SWING).

The application container

Whereas the Component Framework helps put together an event-driven UI for the Web application, the Application Container takes care of translating the same UI into its browser representation at the client-side, with a rich-client–like look-and-feel.

The Application Container dynamically generates one peer object for each UI component included in the Web UI. Now, these peer objects are responsible for synchronizing the current state of client-side browser representation with a server-side Web UI model. They follow a two-way approach to do so, involving the following tasks:

  1. Rendering and re-rendering browser representation at the client side according to the current state of the server-side Web UI model, using appropriate HTML-JavaScript code. This coding also lends event-based functionality and rich-client–like look-and-feel to the client-side browser representation.
  2. Firing appropriate events to corresponding server-side UI components, to keep their state updated, in response to any changes made by the end user in relevant parts of the client-side browser representation (for example, opening/closing of windows, changing scrollbar positions, and input submission from multiple forms).

This approach has obvious advantages for developers. It enables the developers to work directly with the server-side component-based UI model, instead of worrying about coding of underlying HTML and JavaScript necessary to implement the same in a client browser. Any modifications made in the server-side UI model are immediately reflected in the client browser. This approach also lends modularity and hence maintainability to the resulting Web application.

At the client side, any changes in browser representation made by the end-user are recorded by using invisible form elements inside a hidden "controller" frame, which is automatically attached to each application window being rendered in the client browser by the Application Container. This controller frame's job is to record all these changes until the client browser needs to send an HTTP request to the server (usually on form data submission). Then, the controller frame submits all changes at once to the server, encoded as parameters of an outgoing HTTP request. This approach helps reduce the server load by minimizing server interaction.

At the server-side, the Application Container receives and processes such HTTP requests. The Application Container takes care of parsing and validating parameters of every HTTP request and, in response, fires appropriate events to server-side UI components modified by the end user in the client browser. Now, the corresponding event handlers ensure that the server-side components are synchronized with their updated state in the client browser representation.

Echo also provides state-saving functionality through its abstract class, EchoInstance. Every Echo application must extend this EchoInstance class. For every new user, an EchoInstance object is created by the Application Container and stored in the user's session. This stateful object now is used to store application-wide state information for each end-user—such as user name, references to open transactions, last visited page, and so forth.

The Echo framework takes care of all the underlying and repetitive work while allowing developers to concentrate on a higher level of application development and giving end users a rich-client–like experience from Echo-based Web applications.

Setting up Echo

After getting acquainted with Echo, you are ready to build an application with Echo. But first, you need to set up Echo by following these steps:

  1. Download the compressed latest stable version (1.1.4) of the Echo framework source code (in zip or .tar.gz format), from the Echo Web site.
  2. Note: Running Echo will also require that the following are installed:

    • JDK 1.3 or higher (because Echo is Java-based).
    • A Servlet Container compliant with Servlet specification v2.2 or higher; for example, Jakarta Tomcat 4.0+, JRUN 3.0+, Resin 1.1+, and the like. Under the hood Echo applications are Servlets and need a servlet container to run them.
    • Optionally, a Java build tool to compile application code and create a deployable Web Archive (.war) file; for example, Apache Ant or Maven.
  3. Uncompress the Echo source and save the resulting Echo directory in any desired location. Now, locate the Echo.jar and EchoServer.jar files inside the lib subdirectory. Either include the absolute path of these two files in the CLASSPATH of the Web application being developed; or for a Web application to be deployed as a Web archive, copy both files in the WEB-INF/lib directory of the Web application's project.

Now, you are ready to build applications over the Echo Framework.

Building Applications with Echo

An example application

You will build a simple Web application that asks for the user's name and, upon input, responds with a welcome message. This application's UI will consist of a screen (inside a browser window), which has following text "Please enter your name here", a textbox, and two buttons, "Submit" and "Clear" (one to submit the user name and other to clear the input). On entering a name in the textbox and clicking the "Submit" button, a message appears in the same screen, containing Hello followed by the user name. Call this application WelcomeDemo.

The application UI

To build the application's UI, Echo provides readymade Components. The most basic component is a Window, representing the client browser's window where the application UI is displayed. A Window may contain "panes", or separate areas inside a window. There are two types of panes available: ContentPane and ContainerPane. ContentPane may contain other user input or formatting components; for example, Label, TextField, Button, Grid, and so forth; whereas ContainerPane is used to further divide the pane area into separate panes and can only contain other ContentPane or ContainerPane components. This application will have a Window containing a ContentPane named inputPane. This inputPane will in turn contain the following components:

  • Two Label components; msgLabel for text asking for user input, and welcomeLabel to display a welcome message.
  • A TextField inputField for entering the user name.
  • Two Button components, submitButton and clearButton.
  • A Filler component used for creating blanks spaces and lines (used for formatting).

Listing 1 shows a skeleton of the application UI.

Listing 1: Skeleton of WelcomeDemoServlet.java

import nextapp.echo.Button;
import nextapp.echo.ContentPane;
import nextapp.echo.EchoInstance;
import nextapp.echo.Filler;
import nextapp.echo.Label;
import nextapp.echo.TextField;
import nextapp.echo.Window;

import nextapp.echoservlet.EchoServer;

public class WelcomeDemoServlet extends EchoServer {

   // Returns a new user-instance of the Echo application.
   public EchoInstance newInstance() {
      return new WelcomeDemo();
   }
}

class WelcomeDemo extends EchoInstance {

   private Label msgLabel, welcomeLabel;
   private TextField entryField;
   private Button submitButton, clearButton;
   private ContentPane inputPane;

   // This init method is called when a user first visits the
   // application. It must return a Window object that will
   // occupy the contents of the user's open browser window.

   public Window init() {

      //Create a new window.
      Window window = new Window("Input Window");

      //Create a content pane to which components may be added
      inputPane = new ContentPane();

      //Add a contentpane to the window
      window.setContent(inputPane);

      //Create a new label to display message
      msgLabel = new Label("Please enter your name here:");

      //Add the label to the contentpane
      inputPane.add(msgLabel);

      //add 2 blank spaces
      inputPane.add(Filler.createHorizontalStrut(2));

      //Create and add a textfield that's 10 characters long
      entryField = new TextField(10);
      inputPane.add(entryField);

      //add 2 blank rows
      inputPane.add(Filler.createVerticalStrut(2));

      //Create a new submit button and add to contentpane
      submitButton = new Button("Submit");
      inputPane.add(submitButton);

      //add 2 blank spaces
      inputPane.add(Filler.createHorizontalStrut(2));

      //Create a clear button and add to contentpane
      clearButton = new Button("Clear");
      inputPane.add(clearButton);

      //add 2 blank rows
      inputPane.add(Filler.createVerticalStrut(2));

      //Create and add an empty label, used to display a
      //welcome message on user input
      welcomeLabel = new Label();
      inputPane.add(welcomeLabel);

      // Return the new window.
      return window;

   }    //end of init()
}

Because the Echo applications are actually Servlets, the application code consists of a servlet class called WelcomeDemoServlet. Each of these servlet classes (WelcomeDemoServlet here) must extend the EchoServer class of the Echo framework. EchoServer is responsible for providing implementation of javax.servlet.http.HttpServlet to the Echo application servlets. EchoServer takes care of all routine servlet tasks behind the scene, including handling incoming HTTP requests by feeding them to the Application Container.

The WelcomeDemoServlet simply provides an implementation of the inherited newInstance() method that is meant to return a new user instance of this application.

return new WelcomeDemo();

Next, the application class WelcomeDemo extends the EchoInstance class, and overrides the init() method it thus inherits. This init() method's job is to create an application UI and return a Window object that represents the initial state of the application UI in the client browser window.

Adding event-handling capabilities

To make an Echo application event-driven, the application class must implement the Echo framework's ActionListener interface, just as Java SWING does. Also, the application class (WelcomeDemo here) must register itself as an event-listener with every UI component that generates events of interest in response to user action. This is achieved by passing an instance of the application class as an argument to the addActionListener() method of the desired components. Listing 2 shows a code snippet highlighting the modifications made to add event-handling functionality.

Listing 2: Adding event-handling code to WelcomeDemoServlet.java

import nextapp.echo.Button;

// more code....

import nextapp.echo.event.ActionListener;
import nextapp.echo.event.ActionEvent;

// more code here....

class WelcomeDemo extends EchoInstance implements ActionListener {

   private Label msgLabel, welcomeLabel;

   // more code here....

   private String input;

   public void actionPerformed(ActionEvent e) {

      if (e.getActionCommand().equals("submit name")) {
         try {

            // Using getText() method of TextField component
            // to receive user input
            input = entryField.getText();

         } catch (NullPointerException ex) {
            welcomeLabel.setText("You did not enter anything.");
            return;
         }     //end try-catch block

         //The welcomeLabel displays Hello
         //followed by user name
         welcomeLabel.setText("Hello " + input);
      }    //end if
      else if (e.getActionCommand().equals("clear name")) {
         entryField.setText("");    //Clear the text field

      }

   }    //end actionperformed()

   public Window init() {

      //more code....

      submitButton = new Button("Submit");
      submitButton.setActionCommand("submit name");
      submitButton.addActionListener(this);
      inputPane.add(submitButton);

      //more code here....

      clearButton = new Button("Clear");
      clearButton.setActionCommand("clear name");
      clearButton.addActionListener(this);
      inputPane.add(clearButton);

      //more code here ....

      return window;
   }
}

Because in this application the submitButton and clearButton are the only UI components that generate events of interest (events of user input submission and clearing user input), the WelcomeDemo object registers itself as an event-listener with both of them using their addActionListener() method.

Also, both of these components use their setActionCommand() method to define commands to perform desired actions. This allows developers to define their own command strings ("submit name", "clear name") corresponding to the events generated by components, making event-handling code easy to understand and maintain.

The events generated by the UI components are processed by the actionPerformed() method inherited by the event-listener class WelcomeDemo from the ActionListener interface, and duly implemented. This method receives information about generated events through the ActionEvent object passed to it as argument. This method contains instructions on what action to perform when a certain event occurs (or alternatively, which corresponding command is executed). Thus, appropriate actions are performed on occurrence of matching events or commands.

Here, user input is easily accessible through the getText() method of the entryField UI component. Because Application Container takes care of all the underlying work regarding user input processing behind the scenes, developers can directly access the user input through methods of corresponding UI components. Also in response to the user input made, desired changes in any UI component can be affected in a similar fashion.

input = entryField.getText();
//... ...
welcomeLabel.setText("Hello " + input);
//... ... ...
entryField.setText("");

The complete source code of this Echo application can be downloaded from here.

The result

When compiled and deployed on a servlet container server, this Echo application WelcomeDemo will look something like this in a client browser:

Figure 1: UI of WelcomeDemo in client browser

Here, the actual rendering of the UI is automatically being taken care of by the Application Container. Figures 2 and 3 show user input and resulting changes on input submission (by clicking the Submit button) respectively.

Figure 2: User input in the UI of WelcomeDemo

Figure 3: Changes in UI in response to input submission

Conclusion

Echo is a useful Java-based, Open Source framework that saves coding efforts on part of developers, while providing the end user a rich-client like experience from Echo-based Web applications. The Echo framework automates most Web development tasks, including HTTP request parsing and rendering complex HTML-JavaScript based browser representation of the OOP-based UI model, thus saving valuable development time and reducing code size along with developmental cost. Echo also provides the basic building blocks for UI development.

About the Author

Mugdha Vairagade is a senior IT consultant and author. Her major tech portals include developer.com, IBM developerWorks, CNET Networks, Slashdot; many eZines regularly publish her work. Her expertise and interests include Java, Linux, XML, and Open Source projects.

Share:
Home
Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved