Download
FAQ
History
PrevHomeNext API
Search
Feedback
Divider

Delegating Rendering to a Renderer

Both the MapComponent and the AreaComponent delegate all of their rendering to a separate renderer. The section Performing Encoding explains how the MapRenderer performs the encoding for the MapComponent. This section explains in detail the process of delegating rendering to a renderer using the AreaRenderer, which performs the rendering for AreaComponent.

To delegate rendering, you perform these tasks:

Create the Renderer Class

When delegating rendering to a renderer, you can delegate all encoding and decoding to the renderer, or you can choose to do part of it in the component class. The AreaComponent class requires only encoding.

To perform the rendering for AreaComponent, the AreaRenderer must implement an encodeEnd method. The encodeEnd method of AreaRenderer must retrieve the shape, coordinates, and alt values stored in the ImageArea bean that is bound to AreaComponent. Suppose that the area tag currently being rendered has a value attribute value of "fraA". The following line from encodeEnd gets the value of the attribute "fraA" from the FacesContext.

ImageArea ia = (ImageArea)area.getValue(); 

The attribute value is the ImageArea bean instance, which contains the shape, coordinates, and alt values associated with the fraA AreaComponent instance. Configuring Model Data describes how the application stores these values.

After retrieving the ImageArea object, it renders the values for shape, coords, and alt by simply calling the associated accessor methods and passing the returned values to the ResponseWriter, as shown by these lines of code, which write out the shape and coordinates:

writer.startElement("area", area);
writer.writeAttribute("alt", iarea.getAlt(), "alt");
writer.writeAttribute("coords", iarea.getCoords(), "coords");
writer.writeAttribute("shape", iarea.getShape(), "shape"); 

The encodeEnd method also renders the JavaScript for the onmouseout, onmouseover, and onclick attributes. The page author need only provide the path to the images that are to be loaded during an onmouseover or onmouseout action:

<d:area id="France" value="#{fraA}" 
  onmouseover="/template/world_france.jpg" 
  onmouseout="/template/world.jpg" targetImage="mapImage" /> 

The AreaRenderer class takes care of generating the JavaScript for these actions, as shown in the following code from encodeEnd. The JavaScript that AreaRenderer generates for the onclick action sets the value of the hidden field to the value of the current area's component ID and submits the page.

sb = new StringBuffer("document.forms[0]['").
  append(targetImageId).append("'].src='");
sb.append(getURI(context, 
  (String) area.getAttributes().get("onmouseout")));
sb.append("'");
writer.writeAttribute("onmouseout", sb.toString(), 
  "onmouseout");
sb = new StringBuffer("document.forms[0]['").
  append(targetImageId).append("'].src='");
sb.append(getURI(context, 
  (String) area.getAttributes().get("onmouseover")));
sb.append("'");
writer.writeAttribute("onmouseover", sb.toString(), 
  "onmouseover");
sb = new StringBuffer("document.forms[0]['");
sb.append(getName(context, area));
sb.append("'].value='");
sb.append(iarea.getAlt());
sb.append("'; document.forms[0].submit()");
writer.writeAttribute("onclick", sb.toString(), "value");
writer.endElement("area"); 

By submitting the page, this code causes the JavaServer Faces life cycle to return back to the restore view phase. This phase saves any state information--including the value of the hidden field--so that a new request component tree is constructed. This value is retrieved by the decode method of the MapComponent class. This decode method is called by the JavaServer Faces implementation during the apply request values phase, which follows the restore view phase.

In addition to the encodeEnd method, AreaRenderer contains an empty constructor. This is used to create an instance of AreaRenderer so that it can be added to the render kit.

Note that AreaRenderer extends BaseRenderer, which in turn extends Renderer. It contains definitions of the Renderer class methods so that you don't have to include them in your renderer class.

Identify the Renderer Type

During the render response phase, the JavaServer Faces implementation calls the getRendererType method of the component's tag to determine which renderer to invoke, if there is one.

The getRendererType method of bookstore6/src/taglib/AreaTag must return the type associated with AreaRenderer. Recall that you identified this type when you registered AreaRenderer with the render kit. Here is the getRendererType method from the Duke Bookstore application's AreaTag class:

public String getRendererType() { return ("DemoArea");}  
Divider
Download
FAQ
History
PrevHomeNext API
Search
Feedback
Divider

All of the material in The J2EE(TM) 1.4 Tutorial is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.