[ Pobierz całość w formacie PDF ]

onmouseover="/world_namer.jpg" onmouseout="/world.jpg" />
132 CREATING CUSTOM UI COMPONENTS
The UIMap component has one or more UIArea components as children. Its
behavior consists of:
" Retrieving the value of the currently-selected area.
" Rendering the map tag and the input tag
" Generating an event when the user clicks on the image map
" Queuing the event on the FacesContext
The UIMap class extends from UICommand because UIMap generates an Action-
Event when a user clicks on the map. Since UICommand components already
have the ability to generate this kind of event, it makes sense to extend UICom-
mand rather than redefining this functionality in a custom component extending
from UIComponentBase.
TheUIAreacomponent class extendsUIOutputbecauseUIArearequires a value
and valueRef attribute, which are already defined by UIOutput.
The UIArea component is bound to a model object that stores the shape and
coordinates of the region of the image map. You ll see how all of this data is
accessed through the valueRef expression in Performing Encoding (page 132).
The behavior of the UIArea component consists of:
" Retrieving the shape and coordinate data from the model object
" Setting the value of the selectedArea tag to the id of this component
" Rendering the area tag, including the JavaScript for the onmouseover,
onmouseout, and onclick functions
Although these tasks are actually performed by AreaRenderer, theUIAreacom-
ponent class must delegate the tasks to AreaRenderer. See Delegating Render-
ing to a Renderer (page 136) for more information.
The rest of these ccomponents behavior is performed in its encoding and decod-
ing methods. Performing Encoding (page 132) and Performing
Decoding (page 135) explain how this behavior is implemented.
Performing Encoding
During the Render Response phase, the JavaServer Faces implementation pro-
cesses the encoding methods of all components and their associated renderers in
the tree. The encoding methods convert the current local value of the component
into the corresponding markup that represents it in the response.
PERFORMING ENCODING 133
The UIComponentBase class defines a set of methods for rendering markup:
encodeBegin, encodeChildren, encodeEnd. If the component has child compo-
nents, you might need to use more than one of these methods to render the com-
ponent; otherwise, all rendering should be done in encodeEnd.
The UIArea class defines the component corresponding to the area tags:
...
onmouseover="/cardemo/world_samer.gif"
onmouseout="/cardemo/world.gif" />
...
The UIArea component is bound to a model object that stores the shape and
coordinates of the region of the image map. You ll see how all of this data is
accessed through the valueRef expression in Performing Encoding (page 132).
TheUIAreacomponent delegates its rendering to a renderer, as explained in Del-
egating Rendering to a Renderer (page 136). Therefore, UIArea has no rendering
behavior.
Since UIMap is a parent component of UIArea, the area tags must be rendered
after the beginning map tag and before the ending map tag. To accomplish this,
theUIMapclass renders the beginningmaptag inencodeBeginand the rest of the
map tag in encodeEnd.
The JavaServer Faces implementation will automatically invoke the encodeEnd
method of the UIArea component s renderer after it invokes UIMap s encodeBe-
gin method and before it invokes UIMap s encodeEnd method. If a component
needs to perform the rendering for its children, it does this in the encodeChil-
dren method.
Here are the encodeBegin and encodeEnd methods of UIMap:
public void encodeBegin(FacesContext context) throws
IOException {
if (context == null) {
System.out.println("Map: context is null");
throw new NullPointerException();
}
ResponseWriter writer = context.getResponseWriter();
134 CREATING CUSTOM UI COMPONENTS
writer.write("
writer.write(getComponentId());
writer.write("\">");
}
public void encodeEnd(FacesContext context) throws IOException
{
if (context == null) {
throw new NullPointerException();
}
ResponseWriter writer = context.getResponseWriter();
writer.write(
"
writer.write("\">");
writer.write("");
}
Notice that encodeBegin renders only the beginning map tag. The encodeEnd
method renders the input tag and the ending map tag.
These methods first check if the FacesContext is null. The FacesContext con-
tains all of the information associated with the current request.
You also need a ResponseWriter, which you get from the FacesContext. The
ResponseWriter writes out the markup to the current response.
The rest of the method renders the markup to the ResponseWriter. This basi-
cally involves passing the HTML tags and attributes to the ResponseWriter as
strings, retrieving the values of the component attributes, and passing these val-
ues to the ResponseWriter.
The id attribute value is retrieved with the getComponentId method, which
returns the component s unique identifier. The other attribute values are retrieved
with the getAttribute method, which takes the name of the attribute.
If you want your component to perform its own rendering but delegate to a
Renderer if there is one, include the following lines in the encode method to
check if there is a renderer associated with this component.
if (getRendererType() != null) {
super.encodeEnd(context);
return;
}
PERFORMING DECODING 135
If there is a Renderer available, this method invokes the superclass encodeEnd
method, which does the work of finding the renderer. The UIMap class performs
its own rendering so does not need to check for available renderers.
In some custom component classes that extend standard components, you might
need to implement additional methods besides encodeEnd. For example, if you
need to retrieve the component s value from the request parameters such as to
update a model object you also have to implement the decode method.
Performing Decoding
During the Apply Request Values phase, the JavaServer Faces implementation
processes thedecodemethods of all components in the tree. Thedecodemethod
extracts a component s local value from incoming request parameters and con-
verts the value to a type acceptable to the component class.
A custom component class needs to implement the decode method only if it
must retrieve the local value, or it needs to queue events onto the FacesContext.
The UIMap component must do both of the tasks. Here is the decode method of
UIMap:
public void decode(FacesContext context) throws IOException {
if (context == null) {
throw new NullPointerException();
}
String value =
context.getServletRequest().getParameter("selectedArea");
if (value != null)
setAttribute("currentArea", value);
context.addFacesEvent(
new ActionEvent(this, commandName));
setValid(true);
}
The decode method first extracts the value of selectedArea from the request
parameters. Then, it sets the value of UIMap s currentArea attribute to the value
of selectedArea. The currentArea attribute value indicates the currently-
selected area.
The decode method queues an action event onto the FacesContext. In the JSP
page, theaction_listenertag nested inside themaptag causes theImageMapE-
ventHandler to be registered on the map component. This event handler will
136 CREATING CUSTOM UI COMPONENTS
handle the queued event during the Apply Request Values phase, as explained in
Handling Events for Custom Components (page 141).
Finally, the decode method calls setValid(true) to confirm that the local val- [ Pobierz całość w formacie PDF ]

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • szopcia.htw.pl