A set of server-side user interface components for web applications. The user interface components are similar to those of traditional GUIs, such as Sun's Swing.

To learn how Bebop works, start with the documentation for the class {@link com.arsdigita.bebop.Page Page}, the top level container of all Bebop components.

State management

Bebop makes the creation and use of stateful user interface components easy. It helps developers of such components manage the state of one component (for example, a tabbed pane) in a transparent and isolated way.

Nested Containers

Bebop components and containers can be nested arbitrarily deep. For example, it is possible to build a page that contains a {@link com.arsdigita.bebop.TabbedPane} that contains a {@link com.arsdigita.bebop.Form} that contains a {@link com.arsdigita.bebop.Table} that contains a checkbox widget in every row.

Static and request-specific objects

Every Bebop component lets you split the underlying data structures into two parts:

The static part of a page can be built once and then be reused for all the requests to the page. This initialization is typically done in the init method of a servlet. Classes that contain only static information implement the interface {@link com.arsdigita.bebop.util.Lockable}.

Request-specific data structures are built within the doPost or doGet methods of a servlet. Corresponding to the static Page, there is a {@link com.arsdigita.bebop.PageState} class that will carry all the request-specific information connected to the Page. If your application needs to modify parts of a Page during a request, you need to build the page in the servlet's doPost or doGet methods.

As a simple example, consider a page that displays a login screen. The login screen is a form that accepts a screen_name and a password. The static part of the page consists of building up the component hierarchy and locking it. This code would typically be in the init method of a servlet:

    // Create a text widget for screen_name which can not be empty.
    Text screenName = new Text("screen_name");
    screenName.addValidationListener(new NotNullValidationListener());
    // Create a text widget for the password which can not be empty.
    Password password = new Password("password");
    password.addValidationListener(new NotNullValidationListener());
    // Set up the form
    Form form = new Form("aForm");
    form.add(screenName);
    form.add(password);
    // Add a (hypothetical) custom password checker
    form.addValidationListener(new PasswordChecker(screenName, password));
    // Add a listener that forwards the user to his workspace
    form.addProcessListener(new SendUserToWorkspace());
    // Add the form to the page and signal that its building is finished:
    Page page = new Page();
    page.add(f);
    page.lock();

The last line of the above example is very important:

The call to {@link com.arsdigita.bebop.Page#lock} locks the page and guarantees that no further modification to its structure is possible.

Example

The simplest use of this page in the doPost or doGet method of the servlet consists of a single call:

    page.service(request, response)
  

The {@link com.arsdigita.bebop.Page#process Page.process} method will initiate all the steps that are necessary to process the request. It notifies the form that a request has been made and prints the page that results from the form that processes the request.

To process the request, the form extracts the parameter values from the request, runs validation listeners, and either runs process listeners (if the request was a valid submission) or displays the form together with error messages (if the request was not a valid submission).

Related Documentation


Last modified: 2001-06-22