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.
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.
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.
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.
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).