Chapter 10. Advanced Techniques

This chapter is going to talk about some "advanced" RichFaces topics. You will discover with single examples how to use and implement pushing, partial updates, session expiration handling, and so on.

Poll

By using the a:poll component, you can periodically poll the server for data and updates using an Ajax request. The use is the same as for a:commandButton and a:commandLink, so you can invoke an action and re-render one or more page areas.

This component uses a form-based request, so, it is required to put the a:poll component inside h:form.

Here there is a little example that shows how to use it:

<h:form>
<a:poll id="poll" action="#{aBean.pollAction}" interval="500"
reRender="result" />
</h:form>
<h:outputText
id="result"
value="Polling result: #{aBean.pollResult}" />

In this piece of code, we used the a:poll component to execute an action (the method pollAction() of the aBean bean) every 500 milliseconds (using the interval attribute) and, after the execution finished, to update the component with id = "result" (that writes the value the pollAction() method set in the pollResult property of the web page).

As we've said, we need h:form surrounding the a:poll component in order to make it work.

Let's do another simple example we want to show a seconds counter updated every second with a checkbox that enables or disables it.

First, let's do our backing bean: in our project, by creating the book.richfaces.advcm.modules.main.examples.poll package and, inside that, a new class called PollExample. This class would look like this:

package book.richfaces.advcm.modules.main.examples.poll;
@Name("pollExample")
public class PollExample {
private boolean pollingEnabled = true;
public boolean getPollingEnabled() {
return pollingEnabled;
}
public void setPollingEnabled(boolean pollingEnabled) {
this.pollingEnabled = pollingEnabled;
}
public int getSeconds() {
Calendar cal = Calendar.getInstance();
return cal.get(Calendar.SECOND);
}
}

As you can see, it is a simple Seam component with the boolean property (pollingEnabled) having the getter and setter, and a method that returns the current time in seconds (getSeconds()).

Now, let's create the pollExample.xhtml page inside the /view/examples/poll/ directory. It might look like:

<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a="http://richfaces.org/a4j"
template="/layout/template.xhtml">
<ui:define name="body">
<h:form>
<a:poll id="myPoll" interval="1000"
enabled="#{pollExample.pollingEnabled}"
reRender="pollUpdate"
ajaxSingle="true"/>
<h:selectBooleanCheckbox
value="#{pollExample.pollingEnabled}">
<a:support event="onchange"
reRender="myPoll,pollUpdate"
ajaxSingle="true"/>
</h:selectBooleanCheckbox>
<h:panelGroup id="pollUpdate">
<h:outputText value="Polling active: "
rendered="#{pollExample.pollingEnabled}"/>
<h:outputText value="Polling NOT active: " rendered="#{!pollExample.pollingEnabled}"/>
<h:outputText value="#{pollExample.seconds}"/>
</h:panelGroup>
</h:form>
</ui:define>
</ui:composition>

Here, we have defined the a:poll component inside h:form, setting the polling interval to 1000 ms (that is, one second) and re-rendering the text section at every update. Also, we have set the ajaxSingle attribute to true, because we don't want to process the checkbox value every time the poll is fired (we should also use two different forms for that).

Inside the h:selectBooleanCheckbox, we inserted the a:support component to fire an Ajax action when the user clicks on the checkbox, submitting the form, updating the model with the new checkbox value, and re-rendering the a:poll component that is enabled or disabled, depending on the boolean value controlled by the checkbox (pollingEnabled).

Finally, the outputText component renders the information back to the user; those are updated every second by the a:poll component.

The result of the enabled polling is:

Poll

As we have said, the text is updated every second with the current time in seconds from the server clock.

When the poll component is disabled, nothing is updated and the text stays with the value of the latest update:

Poll

Creating images dynamically

In order to add something interesting to this example and also to explain another useful component, we are going to edit it by adding a dynamic graphical counter. We will use the a4j:mediaOutput RichFaces component to render an image (each second) with the current value of seconds from the server.

First of all, let's open PollExample.java and add the paint method to create the image:

public void paint(OutputStream out, Object data)
throws IOException {
// Creating an image
BufferedImage img = new BufferedImage(40, 40, BufferedImage.TYPE_ INT_RGB);
// Getting the Graphics2D object
Graphics2D graphics2D = img.createGraphics();
// Setting background color, foreground color and font size
graphics2D.setBackground(Color.WHITE);
graphics2D.setColor(Color.RED);
graphics2D.setFont(graphics2D.getFont().deriveFont(25f));
// Clearing the background with the color set
graphics2D.clearRect(0, 0, 40, 40);
// Drawing the number value
graphics2D.drawString(String.valueOf(getSeconds()),4,36);
// Writing the image into the output stream as PNG
ImageIO.write(img,"png",out);
}

As you can notice, the paint method has two parameters the first one is OutputStream used to write the output image to and the second one contains the Serializable object, passed by the value attribute of the component (in our case, we are not using it).

This method creates BufferedImage, fills it with the current seconds value, and writes it as a PNG image to the output stream.

Now, let's open pollExample.xhtml and insert the mediaOutput component:

Replace the following component:

<h:outputText value="#{pollExample.seconds}"/>

With this code:

<a:mediaOutput element="img" cacheable="false"
value="#{pollExample.seconds}"
createContent="#{pollExample.paint}"
mimeType="image/png"/>

As we can see, we have set the element attribute as img, which is why the component supports the dynamical generation of other kinds of objects such as Flash movies, applets, or scripts.

The cacheable attribute defines the caching strategy both for the client and the server. Anyway, for our frequent requests, it is possible that the client caches the image in any case. Therefore, it will not be refreshed each second.

In order to avoid this problem, it is sufficient to set the value attribute with a different value for every update (in our case, the current value of the seconds from the server). As the serialized object passed becomes part of the image name, the name will change for every new generated image, which will therefore not be cached by the browser.

The object passed using the value attribute is passed to the paint method, using the data parameter.

For specifying which method to call in order to generate the object, we use the createContent attribute and we've set the MIME type of the returned image (image/png) using mimeType.

The result, when polling is active, is as follows:

Creating images dynamically

When it is not active, we will see the last image sent:

Creating images dynamically
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.67.70