TimezoneTutorial by samsoftdollar

VIEWS: 103 PAGES: 28

									ICEfaces Tutorial: The TimeZone Application

This tutorial will guide you through a series of exercises that take a basic JavaServer Faces application and transform it, using the ICEfaces product, into a much more dynamic application with an enriched user experience. The tutorial is based on a simple web application called TimeZone (shown in Figure 1).
Figure 1 ICEfaces TimeZone Application

From this tutorial, you will learn how to: • • • • Take an existing JSF application and migrate it to run with ICEfaces. Add dynamic asynchronous updates to cause clocks to tick in the application. Add a dynamic data table that is customized through a set of selection checkboxes. Stylize the application to produce a professional look and feel.
1

© 2005 ICEsoft Technologies Inc.

ICEfaces Tutorial: The TimeZone Application

The tutorial consists of five steps with increasing levels of richness, each designed to demonstrate ICEfaces capabilities: Step 1: Basic JSF TimeZone Application on page 3 shows a basic JSF application built entirely from JSF HTML basic components, and XHTML. Step 2: Integrating ICEfaces on page 13 uses the same basic JSF application migrated to run with ICEfaces. For this step, there are no application source code changes required. Step 3: Dynamic Updating—Make the Clocks Tick on page 15 adds ticking clocks to the application. Step 4: Dynamic Table Rendering on page 18 adds a dynamic data table to make the application more interactive. Step 5. Applying Styles on page 25 demonstrates how to add formatting and styles to enhance the look of the application. The five exercises are organized in the directory structure shown in the screen capture on the right. Prior to starting this tutorial, we recommend that you complete the ICEfaces Getting Started Guide. Completion of that will ensure that ICEfaces is installed properly, and that your environment is configured properly to deploy and ready to execute ICEfaces applications on your J2EE application server.

2

ICEfaces Tutorial: The TimeZone Application

Overview of the TimeZone Application
By following all the exercises in this tutorial you will build an ICEfaces application called TimeZone (shown in Figure 1) from source code and deploy it to your local Tomcat server. The application is not entirely an accurate representation of all time zones represented on the map, but serves as an effective example of how to enrich a web application with ICEfaces. The application was deliberately simplified to demonstrate the features that ICEfaces provides to improve the richness and interactivity of a web application. The ICEfaces TimeZone application has the following features: • • • The current time on which the application is running is displayed in the top left of the table. To the right of the current time is a second time display for an alternate time zone that is chosen by clicking a different section on the image map. Below the map are check boxes that, when selected, add time zone details to the table at the bottom. Deselecting a checkbox removes the details from the table.

Step 1:

Basic JSF TimeZone Application
The first step is to create a regular JavaServer Faces (JSF) version of the TimeZone web application using stock JSF components. All of the files in this part of the tutorial are in the timezone1 directory.

Creating a JSP Page with Standard JSF and HTML Tags
Our first iteration of the TimeZone application (see Figure 2 below) has a PanelGrid component at the top to hold the two separate time displays: • • the application's host server time, and the time for the zone selected from the map.

A second PanelGrid below holds six time zone map images, implemented as CommandButton components. When a region of the map is clicked, the display at the top right will display the selected region’s time and time zone.

3

ICEfaces Tutorial: The TimeZone Application

Figure 2

TimeZone Application as Stock JSF Application

The code for the timezone.jsp page is as follows:
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <f:view> <html> <head> <title>Time Zone</title> </head> <body> <h3>Time Zone Sample Application</h3> <h:form> <h:panelGrid columns="2"> <h:outputText style="font-weight:600" value="Server Time Zone"/> <h:outputText style="font-weight:600" value="Time Zone Selected from Map"/> <h:outputText value="#{timeZoneBean.serverTimeZoneName}"/> <h:outputText value="#{timeZoneBean.selectedTimeZoneName}"/> <h:outputText style="font-weight:800" value="#{timeZoneBean.serverTime}"/> 4

ICEfaces Tutorial: The TimeZone Application

<h:outputText style="font-weight:800" value="#{timeZoneBean.selectedTime}"/> </h:panelGrid> <h:panelGrid columns="6"> <h:commandButton id="GMTminus10" image="images/hawaii.jpg" actionListener="#{timeZoneBean.listen}"/> <h:commandButton id="GMTminus9" image="images/alaska.jpg" actionListener="#{timeZoneBean.listen}"/> <h:commandButton id="GMTminus8" image="images/pacific.jpg" actionListener="#{timeZoneBean.listen}"/> <h:commandButton id="GMTminus7" image="images/mountain.jpg" actionListener="#{timeZoneBean.listen}"/> <h:commandButton id="GMTminus6" image="images/central.jpg" actionListener="#{timeZoneBean.listen}"/> <h:commandButton id="GMTminus5" image="images/eastern.jpg" actionListener="#{timeZoneBean.listen}"/> </h:panelGrid> <pre/> </h:form> </body> </html> </f:view>

Most of the components are dynamically bound to backing JavaBeans through JSF expression language bindings as shown below:
<h:outputText value="#{timeZoneBean.serverTimeZoneName}"/>

The commandButton components also use JSF expression language bindings in the actionListener attribute as shown below.
<h:commandButton id="GMTminus10" image="images/hawaii.jpg" actionListener="#{timeZoneBean.listen}"/>

The id attribute of a commandButton component is used to pass information into the bean identifying which button was pressed.
<h:commandButton id="GMTminus10" image="images/hawaii.jpg" actionListener="#{timeZoneBean.listen}"/>

Creating the Backing JavaBean (TimeZoneBean.java)
The com.icesoft.faces.tutorial.TimeZoneBean.java file is the implementation of the backing bean for the timezone.jsp page. The bean stores the current state of the selections and all the time zone information. The code for the TimeZoneBean.java class is as follows:
package com.icesoft.tutorial; 5

ICEfaces Tutorial: The TimeZone Application

import import import import import import import

javax.faces.context.FacesContext; javax.faces.event.ActionEvent; java.text.DateFormat; java.text.SimpleDateFormat; java.util.Calendar; java.util.StringTokenizer; java.util.TimeZone;

/** * Bean backing the Time Zone application. Controls time zone information during * the session. */ public class TimeZoneBean { /** * {@link DateFormat} used to display time. */ private DateFormat currentFormat; /** * The default {@link TimeZone} for this host server. */ private TimeZone serverTimeZone; /** * Active {@link TimeZone} displayed at top of UI. Changes when a time zone * is selected by pressing one of six commandButtons in UI map. */ private TimeZone selectedTimeZone; /** * Constants designating a specific location in a time zone. This level of * detail is required to extract daylight time properties. */ private static final String GMT5DAYLIGHTLOCATION = "America/New_York"; private static final String GMT6DAYLIGHTLOCATION = "America/Chicago"; private static final String GMT7DAYLIGHTLOCATION = "America/Phoenix"; private static final String GMT8DAYLIGHTLOCATION = "America/Los_Angeles"; private static final String GMT9DAYLIGHTLOCATION = "America/Anchorage"; private static final String GMT10DAYLIGHTLOCATION = "Pacific/Honolulu"; /** * Constructor, initializes time zones. */ public TimeZoneBean() { init(); 6

ICEfaces Tutorial: The TimeZone Application

} /** * Initializes this TimeZoneBean's properties. */ private void init() { currentFormat = new SimpleDateFormat("EEE, HH:mm:ss"); serverTimeZone = TimeZone.getDefault(); // selected time zone set to UTC as default selectedTimeZone = TimeZone.getTimeZone("Etc/GMT+0"); } /** * Gets selected time zone time. This is the time zone selected by one of * six commandButtons from the map in the UI. * * @return selectedTimeZone time. */ public String getSelectedTime() { return getComputedTime(selectedTimeZone); } /** * Gets selected time zone display name. * * @return selectedTimeZone display name. */ public String getSelectedTimeZoneName() { return displayNameTokenizer(selectedTimeZone.getDisplayName()); } /** * Gets server time. * * @return Server time. */ public String getServerTime() { long now = System.currentTimeMillis(); Calendar serverZoneCal = Calendar.getInstance(serverTimeZone); serverZoneCal.setTimeInMillis(now); return currentFormat.format(serverZoneCal.getTime()); } /** * Gets server time zone display name. * 7

ICEfaces Tutorial: The TimeZone Application

* @return Server time zone display name. */ public String getServerTimeZoneName() { return displayNameTokenizer(serverTimeZone.getDisplayName()); } /** * Extracts the first word from a TimeZone displayName. * * @param String A TimeZone displayName. * @return String The first word from the TimeZone displayName. */ public String displayNameTokenizer(String displayName) { if(displayName==null){ displayName = ""; } else { StringTokenizer tokens = new StringTokenizer(displayName," "); if (tokens.hasMoreTokens()) { displayName = tokens.nextToken(); } } return displayName; } /** * Calculates the current time in a specified time zone. * * @param zone The specified time zone. * @return Time in the specified time zone. */ protected String getComputedTime(TimeZone zone) { String tmpTime = "No Time available"; long now = System.currentTimeMillis(); Calendar currentZoneCal = Calendar.getInstance(zone); currentZoneCal.setTimeInMillis(now); int shift = -1 * serverTimeZone.getRawOffset(); long calcMillis = zone.getRawOffset() + shift + now; Calendar cal = Calendar.getInstance(zone); cal.setTimeInMillis(calcMillis); tmpTime = currentFormat.format(cal.getTime()); return tmpTime; } /** 8

ICEfaces Tutorial: The TimeZone Application

* Extracts a {@link TimeZone} id from a component id, then selects a more * specific id within that time zone. The specific locations used in this * sample are saved in constants and were chosen based on the largest * American city in the time zone. * * @param temp Component id containing time zone id. * @return {@link TimeZone} id. */ private String interpretID(String temp, String minus, String plus) { // fallback is GMT time zone if no zoneid found. String zoneId = "Etc/GMT+0"; if (temp.indexOf(minus) > 0) { int transIndex = Integer.parseInt( temp.substring(temp.lastIndexOf(minus) + minus.length())); zoneId = "Etc/GMT+" + transIndex; } else { if (temp.indexOf(plus) > 0) { int transIndex = Integer.parseInt( temp.substring(temp.lastIndexOf(plus) + plus.length())); zoneId = "Etc/GMT-" + transIndex; } } // Choosing a specific {@link TimeZone} // id within the larger {@link TimeZone}. if (zoneId.endsWith("5")) { zoneId = GMT5DAYLIGHTLOCATION; } else if (zoneId.endsWith("6")) { zoneId = GMT6DAYLIGHTLOCATION; } else if (zoneId.endsWith("7")) { zoneId = GMT7DAYLIGHTLOCATION; } else if (zoneId.endsWith("8")) { zoneId = GMT8DAYLIGHTLOCATION; } else if (zoneId.endsWith("9")) { zoneId = GMT9DAYLIGHTLOCATION; } else if (zoneId.endsWith("10")) { zoneId = GMT10DAYLIGHTLOCATION; } return zoneId; } /** * Listens to client input from commandButtons in the UI map and sets the * selected time zone. * * @param e ActionEvent. */ 9

ICEfaces Tutorial: The TimeZone Application

public void listen(ActionEvent e) { FacesContext context = FacesContext.getCurrentInstance(); String temp = e.getComponent().getClientId(context); String zoneId = interpretID(temp, "GMTplus", "GMTminus"); selectedTimeZone = TimeZone.getTimeZone(zoneId); } }

Besides storing the current state and the time zone information, the TimeZoneBean also handles the actions generated by clicking the commandButtons. The listen(ActionEvent e) method in the bean takes the id of the commandButton clicked and passes it into the method interpretId(). This method takes the component id and returns a TimeZone id that can be used to instantiate a TimeZone object. The commandButton ids represent a number relative to Greenwich Mean Time (GMT).

Binding The Bean to the JSP Page
JSF uses an XML file called faces-config.xml to manage the configuration of beans so that the beans' methods are available to components in the page. The code for the faces-config.xml file is as follows:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd"> <faces-config xmlns="http://java.sun.com/JSF/Configuration"> <managed-bean> <managed-bean-name>timeZoneBean</managed-bean-name> <managed-bean-class>com.icesoft.tutorial.TimeZoneBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> </faces-config>

The entry bean is given a name by which it can be referred to in the JSP page and the name is also associated with a Java class so that it can be instantiated as required. The bean is also given a scope to indicate how the bean can be accessed.

Configuring the Web Application
At the heart of it, our TimeZone application is a standard J2EE web application and requires a deployment descriptor. This means we need to create a web.xml file.

10

ICEfaces Tutorial: The TimeZone Application

The code for the web.xml file is as follows:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>ICEfaces Tutorial: Timezone Part 1</display-name> <description> ICEfaces Tutorial: Timezone Part 1 </description> <context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>server</param-value> </context-param> <context-param> <param-name>javax.faces.application.CONFIG_FILES</param-name> <param-value>/WEB-INF/faces-config.xml</param-value> </context-param> <!-- Faces Servlet --> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup> 1 </load-on-startup> </servlet> <!-- Faces Servlet Mapping --> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.faces</url-pattern> </servlet-mapping> </web-app>

This is a fairly typical descriptor for a JSF application. The Faces Servlet is declared and configured to load on startup. The .faces extension is mapped to the faces Servlet.

Building and Deploying timezone1
For the tutorial applications, we rely on Ant as a build tool and Tomcat as the container to run the application. A build.xml file has been provided that can build and deploy the
11

ICEfaces Tutorial: The TimeZone Application

application to Tomcat for you. The build file relies on build.properties for system specific information it needs to successfully build and deploy the application. The content of build.properties is as follows:
username=nobody password=nowhere # Set true to bundle all dependent jars into the webapp build.standalone=true #Compilation flags compile.deprecation = true compile.debug = true

1. Edit the build.properties file to suit your environment. You will need to modify the username and password to correspond to some existing username and password in the Tomcat tomcat-users.xml file or add a user with the manager role to the file if one is not already present

Note:

For security, the default Tomcat configuration does NOT include a username with the manager role. If you have just downloaded and installed Tomcat, you will need to add one in order to deploy to Tomcat using the ant install task. An example tomcat-users.xml file is included in the tutorial directory as a reference. You can also look at the documentation for Tomcat for more information.

2. To deploy the application using the build file, ensure that you have an account that will let you deploy using the remote deployment mechanism. 3. Ensure that Tomcat is running. 4. Once your environment is ready, navigate to the <icefaces-installdir>/tutorial/timezone1 directory from the command line and type:
ant install

This will compile the source code, generate a .war file with all the required resources, and deploy it to the running Tomcat server. 5. To interact with the application, point your web browser at the following URL, making adjustments for your environment as required. For example, port 8080 is the default port that Tomcat uses but if you have changed this in your installation, alter the following URL accordingly.
http://localhost:8080/timezone1/timezone.faces

If all goes well, you should see the first incarnation of the TimeZone application running in your browser. Clicking a different time zone on the map updates the time and time zone information in the top right of the table.

12

ICEfaces Tutorial: The TimeZone Application

Step 2:

Integrating ICEfaces
In this step of the tutorial, we integrate ICEfaces technology into our existing JSF application. All the files and resources for this section of the tutorial are contained in the timezone2 directory.

Turning JSP into JSP Document
JSP pages (unlike the more recent JSP Document specification) are not required to be well-formed XML documents. ICEfaces requires well-formed XML documents, so we need to make some modifications to our JSP page to align it with the JSP Document specification. 1. Change the file extension of the timezone.jsp file from .jsp to .jspx. This is the first step in converting the web page to a JSP Document (XML-compatible JSP). The .jspx extension identifies the file as an XML-compliant JSP page and allows us a bit of flexibility with our servlet mappings. 2. Remove the JSP taglib directives and declare them using xml namespaces in the JSF <f:view> element:
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> becomes: <f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">

If the page consists of well-formed JSF and XHTML tags, this is the only change necessary to convert the page to a JSP document.

Registering ICEfaces Servlets
As an extension to JSF, ICEfaces provides its own version of the FacesServlet (PersistentFacesServlet) as well as an additional Servlet (BlockingServlet) for handling asynchronous updates. We register these Servlets in the deployment descriptor file (web.xml) by adding the following entries:
<servlet> <servlet-name>Persistent Faces Servlet</servlet-name> <servlet-class>com.icesoft.faces.webapp.xmlhttp.PersistentFacesServlet </servlet-class> <load-on-startup> 1 </load-on-startup> </servlet> <servlet> <servlet-name>Blocking Servlet</servlet-name>

13

ICEfaces Tutorial: The TimeZone Application

<servlet-class>com.icesoft.faces.webapp.xmlhttp.BlockingServlet</servletclass> <load-on-startup> 1 </load-on-startup> </servlet>

We also need to add new Servlet mappings. Since we have a new file extension, we map FacesServlet to .jspx and PersistentFacesServlet is mapped to .iface. With this strategy we can have a single page and run it in either plain JSF mode or with ICEfaces by simply changing the extension in the URL.
<servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jspx</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Persistent Faces Servlet</servlet-name> <url-pattern>*.iface</url-pattern> </servlet-mapping>

We also need to add a couple of mappings for ICEfaces' internal use.
<servlet-mapping> <servlet-name>Persistent Faces Servlet</servlet-name> <url-pattern>/xmlhttp/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Blocking Servlet</servlet-name> <url-pattern>/block/*</url-pattern> </servlet-mapping>

Building and Deploying timezone2
If you got timezone1 to run, then your environment has been set up and is running correctly. From the command line, navigate to the <icefaces-installdir>/tutorial/timezone2 directory and type:
ant install

This should compile the source code, generate a .war file with all the required resources, and deploy it to a running Tomcat server. To interact with the application, point your web browser at the following URL, making adjustments for your environment as required.
http://localhost:8080/timezone2/timezone.iface

14

ICEfaces Tutorial: The TimeZone Application

Note:

The extension we are using now is .iface so that the request gets mapped to the ICEfaces PersistentFacesServlet.

This version of TimeZone looks identical to timezone1 and has no functional difference. However, with little effort, we've integrated ICEfaces into our JSF application. The components are now being rendered by the ICEfaces Direct-to-DOM (D2D)RenderKit and we are now ready to enrich this application with some dynamic, asynchronous updates.

Step 3:

Dynamic Updating—Make the Clocks Tick
In this section, we are going to make the clocks tick by pushing updates from the server to the page and changing the content dynamically, but without a full page refresh, thanks to ICEfaces and Direct-to-DOM rendering.

Enhancing the TimeZoneBean
Now that we've integrated ICEfaces, the work to make the clocks tick is done in the bean. To make the clock tick every second, we are going to create our own thread and have it send updates at a set interval. We also need to add a bit of ICEfaces-specific code to force a JSF render pass after the clock data has been updated. For timezone3, the following changes are made to the TimeZoneBean.java file. 1. First we add some imports to support the new ICEfaces features:
import com.icesoft.faces.webapp.xmlhttp.PersistentFacesState; import javax.servlet.http.HttpSession;

2. Then we make the bean implement runnable so we can use it with a thread:
public class TimeZoneBean implements Runnable {

3. A polling interval is added as a bean property:
/** * Time thread sleeps between polls. */ private int pollInterval = 500;

4. An HttpSession is added as a bean property:
/** * Identifies a user across more than one page request and stores * information about that user.

15

ICEfaces Tutorial: The TimeZone Application

*/ private HttpSession session;

5. The constructor instantiates a thread and starts it:
/** * Constructor, initializes time zones and starts thread which updates the * time. */ public TimeZoneBean() { init(); Thread ticker = new Thread(this); ticker.start(); }

6. We get and store a reference to the current HttpSession with some code in the init method:
/** * Initializes this TimeZoneBean's properties. */ private void init() { currentFormat = new SimpleDateFormat("EEE, HH:mm:ss"); serverTimeZone = TimeZone.getDefault(); // selected time zone set to UTC as default selectedTimeZone = TimeZone.getTimeZone("Etc/GMT+0"); session = (HttpSession)FacesContext.getCurrentInstance(). getExternalContext().getSession(false); }

7.

Then we add a run method to implement the Runnable interface. When the thread runs, it gets a reference to the PersistentFacesState from the HttpSession. This state can be used to initiate a render pass, which triggers the dynamic update to the client. The bean sleeps for the specified polling interval in between calls to render.

public void run() { try { while (0 != pollInterval) { PersistentFacesState state = (PersistentFacesState) session.getAttribute( PersistentFacesState.PERSISTENT_FACES_STATE);

Thread.sleep(pollInterval); if (null != state) { state.render(); } else { System.out.println("null PersistentFacesState"); break;

16

ICEfaces Tutorial: The TimeZone Application

} } } catch (Exception e) { System.out.println(e); } }

That's about it. We've enhanced the bean so that it can now push updates to the client asynchronously. And since the components are being rendered with the ICEfaces Direct-to-DOM RenderKit, we see clocks ticking smoothly in the page as we interact with the application.

Building and Deploying timezone3
To see timezone3 in action, navigate to the <icefaces-install-dir>/tutorial/timezone3 directory and type:
ant install

This should compile the source code, generate a .war file with all the required resources, and deploy it to a running Tomcat server. To interact with the application, point your web browser at the following URL, making adjustments for your environment as required.
http://localhost:8080/timezone3/timezone.iface

This version of TimeZone looks identical to timezone1 and timezone2 but now you should see the clocks ticking as the page is dynamically updated with each render pass initiated by the bean.

17

ICEfaces Tutorial: The TimeZone Application

Step 4:

Dynamic Table Rendering
Now that we have the page updating dynamically, let's make it more interactive. We're going to add the ability to select time zones for which we want to see more detailed information. To do this we will add some SelectBooleanCheckbox components and a DataTable component. As the checkboxes are selected and de-selected, the rows of the table will show or hide themselves without requiring a page refresh. The finished product will look something like Figure 3:

Figure 3

TimeZone Application with Dynamic Table Rendering

So in the timezone.jspx page, we make the following changes:

18

ICEfaces Tutorial: The TimeZone Application

1. Add a row of six selectBooleancheckbox components to the existing panelGrid holding the map.
<h:selectBooleanCheckbox id="Cminus10" required="false" immediate="true" valueChangeListener="#{timeZoneBean.timeZoneChanged}" /> <h:selectBooleanCheckbox id="Cminus9" required="false" immediate="true" valueChangeListener="#{timeZoneBean.timeZoneChanged}" /> <h:selectBooleanCheckbox id="Cminus8" required="false" immediate="true" valueChangeListener="#{timeZoneBean.timeZoneChanged}" /> <h:selectBooleanCheckbox id="Cminus7" required="false" immediate="true" valueChangeListener="#{timeZoneBean.timeZoneChanged}" /> <h:selectBooleanCheckbox id="Cminus6" required="false" immediate="true" valueChangeListener="#{timeZoneBean.timeZoneChanged}" /> <h:selectBooleanCheckbox id="Cminus5" required="false" immediate="true" valueChangeListener="#{timeZoneBean.timeZoneChanged}" />

Checking one of these components will fire a valueChangeEvent that results in the valueChangeListener calling timeZoneChanged(ValueChangeEvent event) in TimeZoneBean.java. Time zone-specific information is passed into the bean via the selectBooleanCheckbox id attribute. The id is used to identify the location of the time zone relative to GMT (Greenwich Mean Time). The C is used as a prefix in the id to avoid duplication of commandButton ids. 2. A dataTable is added below the panelGrid in the UI. This dataTable will hold information on all the selectBooleanCheckboxes checked, getting its data from the array of CheckedTimeZone objects returned from the bean. The arrayList of CheckedTimeZone objects is retrieved from TimeZoneBean.java in the value attribute of the dataTable component. The properties of each object in the arrayList are then displayed through value bindings in outputText components in each row of the dataTable.
<h:dataTable frame="box" value="#{timeZoneBean.checkedTimeZoneList}" var="checkedTimeZone"> <f:facet name="header"> <h:outputText value="Checked Time Zones" /> </f:facet> <h:column> <f:facet name="header"><h:outputText value="Time Zone" /></f:facet> <h:outputText value="#{checkedTimeZone.displayName}"/> </h:column> <h:column> <f:facet name="header"><h:outputText value="Location" /></f:facet> <h:outputText value="#{checkedTimeZone.id}"/> </h:column> <h:column> <f:facet name="header"><h:outputText value="Uses DST" /></f:facet> <h:outputText value="#{checkedTimeZone.useDaylightTime}"/> </h:column> <h:column>

19

ICEfaces Tutorial: The TimeZone Application

<f:facet name="header"><h:outputText value="In DST" /></f:facet> <h:outputText value="#{checkedTimeZone.inDaylightTime}"/> </h:column> <h:column> <f:facet name="header"><h:outputText value="Time" /></f:facet> <h:outputText value=" #{checkedTimeZone.time} "/> </h:column> </h:dataTable>

Next, we create an additional convenience class called CheckedTimeZone.java, for holding the time zone information details that are returned to the page when the timeZoneChanged method is triggered:
package com.icesoft.tutorial; import java.util.TimeZone; /** * Bean holding time zone specific information. Checking a selectBooleanCheckbox * in the UI will cause instances of this class to populate the ArrayList in * <code>TimeZoneBean</code>. That ArrayList is used to create a DataTable of * checked time zones in the UI. */ public class CheckedTimeZone { /** * Time zone name displayed in the UI. DisplayName is associated with the id * for this CheckedTimeZone. */ private String dislayName; /** * {@link TimeZone} id used to identify the time zone. This is the id * returned from <code>interpretId</code> in TimeZoneBean. * <code>interpretId</code> returns a specific location in a timezone so * that daylight time properties can be accessed. */ private String id; /** * TimeZoneBean used to access dynamic time. */ private TimeZoneBean parent; /** * Time zone uses daylight savings time. */ private boolean useDaylightTime; 20

ICEfaces Tutorial: The TimeZone Application

/** * Time zone in daylight savings time. */ private boolean inDaylightTime; /** * Constructor * * @param displayName Time zone name that is displayed in the UI. * @param id {@link TimeZone} id used to identify the time * zone. * @param useDaylightTime Does time zone use daylight time. * @param inDaylightTime Is time zone currently in daylight time. * @param parent TimeZoneBean instance to access dynamic time in * time zone. */ public CheckedTimeZone(String displayName, String id, boolean useDaylightTime, boolean inDaylightTime, TimeZoneBean parent) { this.dislayName = displayName; this.id = id; this.useDaylightTime = useDaylightTime; this.inDaylightTime = inDaylightTime; this.parent = parent; } /** * Gets the name of this time zone to be displayed in the UI. * * @return String */ public String getDisplayName() { return dislayName; } /** * Gets the {@link TimeZone} id used to identify this time zone. * * @return String */ public String getId() { return id; } /** * Gets the dynamic time through the <code>getComputedTime</code> method in 21

ICEfaces Tutorial: The TimeZone Application

* the <code>TimeZoneBean</code>. * * @return String */ public String getTime() { TimeZone thisTimeZone = TimeZone.getTimeZone(id); return parent.getComputedTime(thisTimeZone); } /** * Gets whether or not this time zone uses DayLight time. * * @return Returns the useDaylightTime. */ public String getUseDaylightTime() { if (useDaylightTime) { return "Yes"; } else { return "No"; } } /** * Gets the state of DayLight Time in this time zone. * * @return Returns the inDaylightTime. */ public String getInDaylightTime() { if (inDaylightTime) { return "Yes"; } else { return "No"; } } }

Then in the TimeZoneBean.java class, we make the following changes: 1. Add a timeZoneChanged(ValueChangeEvent event) method in TimeZoneBean.java to be called when a selectBooleanCheckbox is checked.
/** * Adds or removes a <code>CheckedTimeZone</code> to * <code>checkedTimeZoneList</code> when a selectBooleanCheckbox * ValueChangeEvent is fired from the UI. * * @param event ValueChangeEvent.

22

ICEfaces Tutorial: The TimeZone Application

*/ public void timeZoneChanged(ValueChangeEvent event) { UIComponent comp = event.getComponent(); FacesContext context = FacesContext.getCurrentInstance(); String zoneId = interpretID(comp.getClientId(context), "Cplus", "Cminus"); TimeZone timeZone = TimeZone.getTimeZone(zoneId); //Calendar is required to obtain a Date object to pass into // inDaylightTime method. Calendar cal = Calendar.getInstance(timeZone); boolean newVal = ((Boolean) event.getNewValue()).booleanValue(); if (newVal) { CheckedTimeZone checkedTimeZone = new CheckedTimeZone( timeZone.getDisplayName(), zoneId, timeZone.useDaylightTime(), timeZone.inDaylightTime(cal.getTime()), this); checkedTimeZoneList.add(checkedTimeZone); } else { for (int i = 0; i < checkedTimeZoneList.size(); i++) { if (((CheckedTimeZone) (checkedTimeZoneList.get(i))).getId() .equals(timeZone.getID())) { checkedTimeZoneList.remove(i); } } } }

This method extracts the id from the selectBooleanCheckbox component, passes this id into the interpretId method of TimeZoneBean.java, which returns a valid TimeZone id. This id is used to instantiate a TimeZone object. The TimeZone is used in turn to instantiate a CheckedTimeZone object. CheckedTimeZone objects contain details on the time zone checked by the selectBooleanCheckbox. 2. Finally, add an arrayList of CheckedTimeZone objects to TimeZoneBean.java. The CheckedTimeZone is added or deleted from the arrayList of CheckedTimeZone objects in TimeZoneBean.java. This is the arrayList used to populate the dataTable. The timeZoneChanged method will add or delete CheckedTimeZone objects to the arrayList based on the value of the selectBooleanCheckbox.
/** * ArrayList of <code>CheckedTimeZone</code> objects. These objects are used * to populate the DataTable in UI. */ private ArrayList checkedTimeZoneList; /** * Gets ArrayList of <code>CheckedTimeZone</code> objects. This list is 23

ICEfaces Tutorial: The TimeZone Application

* populated by selectBooleanCheckbox components in UI. * * @return ArrayList of CheckedTimeZone objects. */ public ArrayList getCheckedTimeZoneList() { return checkedTimeZoneList; } The arrayList is initialized in the init() method. /** * Initializes this TimeZoneBean's properties. */ private void init() { currentFormat = new SimpleDateFormat("EEE, HH:mm:ss"); serverTimeZone = TimeZone.getDefault(); // selected time zone set to UTC as default selectedTimeZone = TimeZone.getTimeZone("Etc/GMT+0"); session = (HttpSession) FacesContext.getCurrentInstance() .getExternalContext() .getSession(false); checkedTimeZoneList = new ArrayList(); }

Building and Deploying timezone4
To run timezone4, navigate to the <icefaces-install-dir>/tutorial/timezone4 directory and type:
ant install

This should compile the source code, generate a .war file with all the required resources, and deploy it to a running Tomcat server. To interact with the application, point your web browser at the following URL, making adjustments for your environment as required.
http://localhost:8080/timezone4/timezone.iface

This version of TimeZone should now have checkboxes. As you click the checkboxes, the rows in the table should show and hide themselves accordingly. Although we're still using stock JSF components, the interface is now richer and more dynamic thanks to ICEfaces and Direct-to-DOM rendering.

24

ICEfaces Tutorial: The TimeZone Application

Step 5.

Applying Styles
The final step of the tutorial outlines how to apply styles throughout the TimeZone application to make it more visually appealing. This is an important aspect of web application development, and shows how the dual roles of application developer and page developer come together to put the final polish on an application.

Add Stylesheet to Application
A Cascading Style Sheet is added to the web folder of timezone.jspx. This file is accessed by the application through the following line, added to timezone.jspx under the <head> tag:
<link rel="stylesheet" type="text/css" href="./icesoft_styles1.css" />

Add Pictures to Application
Any pictures used by the stylesheet should be dropped into the images subfolder of the application web folder.

Implement Styles
In tutorial examples timezone1 to 4, inline styles were used: <h:outputText style="font-weight:600" value="Server Time Zone"/>. Tutorial example timezone5 uses only styles from the stylesheet as shown below:
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"> <html> <head> <title>Time Zone</title> </head> <link rel="stylesheet" type="text/css" href="./icesoft_styles1.css" /> <body bgcolor="white"> <div id="headerDiv"> <table width="100%" cellpadding="0" cellspacing="0"> <tr class="demoHeaderBkgnd" > <td width="338" align="left"><img src="images/demo-page-left.gif" width="338" height="60"/></td> <td width="183"></td> <td width="120" rowspan="2" align="right" valign="top"> <img src="images/demo-page-right.gif" width="119" height="96"/> </td> </tr> <tr> <td align="left" valign="top"><img src="images/timezone_logo.gif" 25

ICEfaces Tutorial: The TimeZone Application

width="200" height="31"/></td> <td align="right"></td> </tr> </table> </div> <div id="timeZonePanel" > <h:form> <h:panelGrid columns="2" rowClasses="floatingDialogHeader, , " width="100%" > <h:outputText value="Server Time Zone"/> <h:outputText value="Time Zone Selected from Map"/> <h:outputText styleClass="formLabel" value="#{timeZoneBean.serverTimeZoneName}"/> <h:outputText styleClass="formLabel" value="#{timeZoneBean.selectedTimeZoneName}"/> <h:outputText value="#{timeZoneBean.serverTime}"/> <h:outputText value="#{timeZoneBean.selectedTime}"/> </h:panelGrid> <h:panelGrid columns="6" width="100%" cellpadding="0" cellspacing="0"> <h:commandButton id="GMTminus10" image="images/hawaii.jpg" actionListener="#{timeZoneBean.listen}"/> <h:commandButton id="GMTminus9" image="images/alaska.jpg" actionListener="#{timeZoneBean.listen}"/> <h:commandButton id="GMTminus8" image="images/pacific.jpg" actionListener="#{timeZoneBean.listen}"/> <h:commandButton id="GMTminus7" image="images/mountain.jpg" actionListener="#{timeZoneBean.listen}"/> <h:commandButton id="GMTminus6" image="images/central.jpg" actionListener="#{timeZoneBean.listen}"/> <h:commandButton id="GMTminus5" image="images/eastern.jpg" actionListener="#{timeZoneBean.listen}"/> <h:selectBooleanCheckbox id="Cminus10" required="false" immediate="true" valueChangeListener="#{timeZoneBean.timeZoneChanged}" /> <h:selectBooleanCheckbox id="Cminus9" required="false" immediate="true" valueChangeListener="#{timeZoneBean.timeZoneChanged}" /> <h:selectBooleanCheckbox id="Cminus8" required="false" immediate="true" valueChangeListener="#{timeZoneBean.timeZoneChanged}" /> <h:selectBooleanCheckbox id="Cminus7" required="false" immediate="true" valueChangeListener="#{timeZoneBean.timeZoneChanged}" /> <h:selectBooleanCheckbox id="Cminus6" required="false" immediate="true" valueChangeListener="#{timeZoneBean.timeZoneChanged}" /> <h:selectBooleanCheckbox id="Cminus5" required="false" immediate="true" valueChangeListener="#{timeZoneBean.timeZoneChanged}" /> </h:panelGrid> <h:dataTable value="#{timeZoneBean.checkedTimeZoneList}" var="checkedTimeZone" headerClass="tableHeader" width="100%" > 26

ICEfaces Tutorial: The TimeZone Application

<f:facet name="header"><h:outputText value="Checked Time Zones" /></f:facet> <h:column> <f:facet name="header"><h:outputText value="Time Zone" /></f:facet> <h:outputText value="#{checkedTimeZone.displayName}"/> </h:column> <h:column> <f:facet name="header"><h:outputText value="Location" /></f:facet> <h:outputText value="#{checkedTimeZone.id}"/> </h:column> <h:column> <f:facet name="header"><h:outputText value="Uses DST" /></f:facet> <h:outputText value="#{checkedTimeZone.useDaylightTime}"/> </h:column> <h:column> <f:facet name="header"><h:outputText value="In DST" /></f:facet> <h:outputText value="#{checkedTimeZone.inDaylightTime}"/> </h:column> <h:column> <f:facet name="header"><h:outputText value="Time" /></f:facet> <h:outputText styleClass="formLabel" value=" #{checkedTimeZone.time} "/> </h:column> </h:dataTable> </h:form> </div> </body> </html> </f:view>

There are two <div> elements applied to the page. The first helps create a page heading: <div id="headerDiv">. The second creates a container for the rest of the application: <div id=" timeZonePanel">. The class attribute is used to apply styles from the stylesheet to HTML elements:
<tr class="demoHeaderBkgnd" >.

The styleClass attribute is used to apply styles from the stylesheet to JSF elements:
<h:outputText styleClass="formLabel" value="#{timeZoneBean.serverTimeZoneName}"/>

The JSF panelGrid component has a rowClasses attribute that applies styles from the stylesheet to the rows of the table it creates:
<h:panelGrid columns="2" rowClasses="floatingDialogHeader, , " width="100%" >

27

ICEfaces Tutorial: The TimeZone Application

In this example, the floatingDialogHeader class is applied to the first row and the second and third rows are left blank, meaning no style is applied. The JSF dataTable component has a ìheaderClassî attribute that applies styles to all the headers in the table:
<h:dataTable value="#{timeZoneBean.checkedTimeZoneList}" var="checkedTimeZone" headerClass="tableHeader" width="100%" >

Building and Deploying timezone5
To run timezone5, navigate to the <icefaces-install-dir>/tutorial/timezone5 directory and type:
ant install

This should compile the source code, generate a .war file with all the required resources, and deploy it to a running Tomcat server. To interact with the application, point your web browser at the following URL, making adjustments for your environment as required.
http://localhost:8080/timezone5/timezone.iface

This version of TimeZone has the same functionality as timezone4, but should look completely different. Styles have been applied to the application through the stylesheet, which use images located in the web/images folder. With the finishing touches applied, the application is now ready to be presented to the world. For more information on this tutorial or other ICEsoft products, visit our Technical Support page at:
http://www.icesoft.com/support/index.html

28


								
To top