Welcome!

Java Authors: Maureen O'Gara, Liz McMillan, Walter H. Pinson, III, Yakov Werde, Tony Bishop

Related Topics: Java, AJAX & REA

Java: Article

Java Feature — Jakarta Struts & JavaServer Faces

The add-and-remove pattern

The "languageList" and "chosenItem" fields and the "move" method are accessed from the "execute" method of the form's submit action. In the Struts implementation, this is an instance of the Struts Action class.

/**
* Populate the lists from the hidden field.
* <p>
* @param mapping action mapping
* @param form action form
* @param request HTTP servlet request
* @param response HTTP servlet reponse
* @throws Exception
*/
public ActionForward execute( ActionMapping mapping,
   ActionForm form, HttpServletRequest request,
   HttpServletResponse response ) throws Exception
{
   // Populate available list from language list.
   ExampleForm eForm = ( ExampleForm )form;
   eForm.getAvailableList().clear();
   eForm.getAvailableList().addAll( eForm.getLanguageList());

   // Populate chosen list from hidden field.
   eForm.getChosenList().clear();
   eForm.move( eForm.getAvailableList(),
eForm.getChosenItem().split( "\\|" ),
eForm.getChosenList());
}

JavaServer Faces Implementation
What is needed to implement this design pattern in JavaServer Faces? JSF is designed by some of the same people who designed Struts so we hope for a smooth migration path.

In JavaServer Faces, the JSP for the two lists is smaller, because JSF's tags are more compact. Instead of <table>, <tr>, and <td>, JSF uses <h:panelGrid>. Instead of <fmt:message>, JSF uses <h:outputText>. Instead of <html:select> and <html:optionsCollection>, JSF uses <h:selectManyListbox> and <f:selectItems>.

<h:panelGrid columns="3" rowClasses="center">
   <h:outputText value="#{bundle.available}" />
   <h:outputText value="" />
   <h:outputText value="#{bundle.chosen}" />
   <h:selectManyListbox style="width:100px; height:120px;"
      id="available" value="#{example.availableValues}"
      onchange="doUpdate( false, true );">
      <f:selectItems value="#{example.availableList}"/>
   </h:selectManyListbox>
    ...
   <h:selectManyListbox style="width:100px; height:120px;"
      id="chosen" value="#{example.chosenValues}"
      onchange="doUpdate( true, false );">
      <f:selectItems value="#{example.chosenList}"/>
   </h:selectManyListbox>
</h:panelGrid>

As in the Struts implementation, the <h:selectManyListbox> tags refer to the "availableList," "availableValues," "chosenList," and "chosenValues" properties of the backing JavaBean. The interfaces for these properties are identical to the Struts implementation. Internally the Struts Bean stores List properties as LabelValueBeans, while the JSF Bean stores them as SelectItems.

Like the Struts implementation, the four buttons in the middle column are implemented with standard HTML <input> tags. For JSF these have to be enclosed in <f:verbatim> tags. Other than that, the buttons are almost identical with the Struts implementation. The only wrinkle is that JSF generates hierarchical element identifiers. That's why JavaScript for JSF often contains identifiers like those with the "form:" prefix in the code below.

<h:panelGrid columns="1">
   <f:verbatim>
     <input type="button" style="width:100px;"
       id="add" onclick="doMove( 'form:available', 'form:chosen', false );"
       value="<fmt:message key='add'/>" /><br />
     <input type="button" style="width:100px;"
       id="addAll" onclick="doMove( 'form:available', 'form:chosen', true );"
       value="<fmt:message key='addAll'/>" /><br />
     <br />
     <input type="button" style="width:100px;"
       id="remove" onclick="doMove( 'form:chosen', 'form:available', false );"
       value="<fmt:message key='remove'/>" /><br />
     <input type="button" style="width:100px;"
       id="removeAll" onclick="doMove( 'form:chosen', 'form:available', true );"
       value="<fmt:message key='removeAll'/>" />
   </f:verbatim>
   <h:inputHidden id="chosenItem" value="#{example.chosenItem}" />
</h:panelGrid>

Other than the hierarchical identifiers, the "doMove()" and "doUpdate()" functions for JSF are identical to those in the Struts implementation. JavaScript provides client-side interactivity in JSF just as it does in Struts.

A convenience of JavaServer Faces is its handling of the submit action. In JavaServer Faces, you can define the submit button to explicitly invoke a method in the form bean:

<h:commandButton action="#{example.submit}" value="#{bundle.submit}" />

The "example:submit" method reads the hidden field and populates the lists. Because this method is attached to the submit button, there's no need to implement an Action object.

public String submit()
{
   // Populate the available list from the language list.
   availableList.clear();
   availableList.addAll( languageList );

   // Populate the chosen list from the hidden field.
   chosenList.clear();
   move( availableList, chosenItem.split( "\\|" ), chosenList );
    ...
   return( "success" );
}

There's not much of a learning curve to JSF. Tags are different, but they usually produce smaller JSPs. Java code is similar and sometimes requires fewer objects.

The strongest advantage of JavaServer Faces is its component architecture. If you get the free download of Sun's Java Studio Creator, you'll find it contains a complete Add-and-Remove component that you can drag-and-drop in your GUI. Sun's component includes features such as "Move Up" and "Move Down" buttons to tweak the order of the chosen items. We can expect many such useful components to emerge as JSF development advances.

Conclusion
This article has described a standard UI design pattern for making ordered selections and selections from long lists. Implementations of this pattern were compared using Jakarta Struts and JavaServer Faces.

JSF provides a natural migration path for projects moving from Struts. The JSP tags are simplified; the backing bean code is similar; and if you need JavaScript for interactivity, the same functions can be used.

JSF can be thought of as a simplified, componentized version of Struts. Its designers have done exactly the type of work one hopes for in a "second system": they've added useful features and reduced complexity.

For any new Web project, JavaServer Faces should be strongly considered. For existing Struts projects, JSF provides a smooth migration path.

Resources

More Stories By Heman Robinson

Heman Robinson is a senior developer with SAS Institute in Cary, N.C. He holds a BS in mathematics from the University of North Carolina and an MS in computer science from the University of Southern California. He has specialized in GUI design and development for 15 years and has been a Java developer since 1996.

Comments (4) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
Bill Dornbush 08/30/06 07:30:07 PM EDT

"Complete code listings for the backing beans, config files, and other code for all six list selection patterns can be downloaded from the JDJ Web site." Where is it?

n d 08/20/06 11:56:13 AM EDT

A previous article compared Jakarta Struts and JavaServer Faces implementations of five simple design patterns for list selection. (JDJ, Vol. 11, Issue 3). Long lists and ordered selections require a more complex design pattern. This pattern displays available items in one list and chosen items in another so the user's choices are always visible and easily modified.

n d 08/20/06 11:32:12 AM EDT

A previous article compared Jakarta Struts and JavaServer Faces implementations of five simple design patterns for list selection. (JDJ, Vol. 11, Issue 3). Long lists and ordered selections require a more complex design pattern. This pattern displays available items in one list and chosen items in another so the user's choices are always visible and easily modified.

n d 08/20/06 10:54:24 AM EDT

A previous article compared Jakarta Struts and JavaServer Faces implementations of five simple design patterns for list selection. (JDJ, Vol. 11, Issue 3). Long lists and ordered selections require a more complex design pattern. This pattern displays available items in one list and chosen items in another so the user's choices are always visible and easily modified.