Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 3
Listing 3
<t:commandLink action="#{employeeTable.viewEmployee}">
<t:graphicImage value="/resources/images/icons/edit_icon.gif"
border="0" alt="Click here to edit the record" />
<f:param name="selectedRowIndex" value="#{rowIndex}"/>
</t:commandLink>
The <t:commandLink> action attribute links the HTTP action to the EmployeeTable.viewEmployee method; we use the selected row index from the request parameter to retrieve the employee information from the employee list
collection. Listing 4 is a code snippet from the viewEmployee() method. You can achieve the same result using different approaches available in the MyFaces wiki.
Listing 4
public String viewEmployee()
{
setSelectedRowIndex(Integer.parseInt((String)getParameter("selectedRowIndex")));
setEmployee((Employee)(getEmployees().get(this.getSelectedRowIndex())));
setShowDetailView(true);
return "OK";
}
In EmployeeDetailTab.jsp, shown in the code below, employee detail information is divided into three sections presented by the <t:panelTabbedPane> component. Each nested <t:panelTab> includes a corresponding section of employee information. The content of the tabbed panel is simple and clean, but provides
powerful GUI presentation.
<t:panelTabbedPane
activeTabStyleClass="googleHouse_panelTabbedPane_activeHeaderCell"
tabContentStyleClass="googleHouse_panelTabbedPane"
activeSubStyleClass="googleHouse_panelTabbedPane_subHeaderCell_active" >
<t:panelTab label="General Information" style="width:35%" >
<f:subview id="ltinc1">
<jsp:include page="employeeInfo.jsp" flush="false"/>
</f:subview>
</t:panelTab>
<t:panelTab label="Contact" style="width:30%" >
<f:subview id="ltinc2">
<jsp:include page="employeeContact.jsp" flush="false"/>
</f:subview>
</t:panelTab>
<t:panelTab label="Work Information" style="width:35%" >
<f:subview id="ltinc3">
<jsp:include page="employeeWork.jsp" flush="false"/>
</f:subview>
</t:panelTab>
</t:panelTabbedPane>
Like any other Web frameworks, JSF also has the configuration file to deal with; it contains your managed bean information,
navigation rules, and your converter and validation classes. You can define your entire managed bean in one or more configuration
files to better organize the content of JSF configuration files. In this use-case, we have two MyFaces configuration files;
faces-config.xml and data-config.xml. The first one contains one EmployeeTable managed bean and one navigation rule, as shown in Listing 5; the second file has all the employee data information (see Listing
6):
Listing 5
<managed-bean>
<managed-bean-name>employeeTable</managed-bean-name>
<managed-bean-class>com.googlehouse.usecases.listtable.EmployeeTable</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>employees</property-name>
<property-class>java.util.List</property-class>
<list-entries>
<value-class>com.googlehouse.usecases.listtable.data.Employee</value-class>
<value>#{employee1}</value>
<value>#{employee2}</value>
<value>#{employee3}</value>
<value>#{employee4}</value>
<value>#{employee5}</value>
<value>#{employee6}</value>
<value>#{employee7}</value>
<value>#{employee8}</value>
<value>#{employee9}</value>
<value>#{employee10}</value>
</list-entries>
</managed-property>
</managed-bean>
<navigation-rule>
<navigation-case>
<from-outcome>home</from-outcome>
<to-view-id>/employee.jsp</to-view-id>
</navigation-case>
</navigation-rule>
Listing 6
<faces-config>
<managed-bean>
<managed-bean-name>employee1</managed-bean-name>
<managed-bean-class>com.googlehouse.usecases.listtable.data.Employee</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>address</property-name>
<property-class>com.googlehouse.usecases.listtable.data.Address</property-class>
<value>#{address1}</value>
</managed-property>
<managed-property>
<property-name>firstName</property-name>
<property-class>java.lang.String</property-class>
<value>Peter</value>
</managed-property>
<managed-property>
<property-name>lastName</property-name>
<property-class>java.lang.String</property-class>
<value>Wang</value>
</managed-property>
<managed-property>
<property-name>middleName</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>cellPhone</property-name>
<property-class>java.lang.String</property-class>
<value>678-923-2719</value>
</managed-property>
<managed-property>
<property-name>workPhone</property-name>
<property-class>java.lang.String</property-class>
<value>678-923-2719</value>
</managed-property>
<managed-property>
<property-name>title</property-name>
<property-class>java.lang.String</property-class>
<value>IT Manager</value>
</managed-property>
<managed-property>
<property-name>SSN</property-name>
<property-class>java.lang.String</property-class>
<value>678-93-2719</value>
</managed-property>
<managed-property>
<property-name>emailAddress</property-name>
<property-class>java.lang.String</property-class>
<value>pwang33@yahoo.com</value>
</managed-property>
<managed-property>
<property-name>workEmailAddress</property-name>
<property-class>java.lang.String</property-class>
<value>pwang@googlehouse.com</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>address1</managed-bean-name>
<managed-bean-class>com.googlehouse.usecases.listtable.data.Address</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>addressOne</property-name>
<property-class>java.lang.String</property-class>
<value>1234 Google House St</value>
</managed-property>
<managed-property>
<property-name>addressTwo</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>city</property-name>
<property-class>java.lang.String</property-class>
<value>Atlanta</value>
</managed-property>
<managed-property>
<property-name>state</property-name>
<property-class>java.lang.String</property-class>
<value>GA</value>
</managed-property>
<managed-property>
<property-name>zipCode</property-name>
<property-class>java.lang.String</property-class>
<value>30394</value>
</managed-property>
</managed-bean>
Thanks to <t:saveState>, we don't have to declare the EmployeeTable managed bean in the session scope, but in the request scope. The JSF framework injects the employee list content into EmployeeTable's employees attribute for you. This kind of injection is often called IoC, or Inversion of Control. In our case, JSF constructs a list
instance based on the <list-entries> value in the configuration file and calls EmployeeTable's setEmployees() method. We only need a navigation rule. When a user clicks on the Cancel button, JSF routes the return page to employee.jsp since the cancel() method returns home as the value:
Listing 7
public String cancel()
{
setSelectedRowIndex(-1);
setEmployee(null);
setShowDetailView(false);
return "home";
}
Now that we have done the code review, let’s see how we can run the application. With the help of a free version of the Exadel Studio Eclipse plug-in, you can create an empty JSF project easily. The following quick steps help you get there:
Figure 4. Exadel New Project's select-wizard window. Click on thumbnail to view full-sized image.
Figure 5. New JSF Project window. Click on thumbnail to view full-sized image.
To run our use-case in your Exadel Studio Eclipse environment, you can follow the steps below.
Figure 6. Import window. Click on thumbnail to view full-sized image.
Figure 7. Import JSF Project window. Click on thumbnail to view full-sized image.
Figure 8. Exadel Tomcat server console window. Click on thumbnail to view full-sized image.
Figure 9. View employee list. Click on thumbnail to view full-sized image.
With just a few MyFaces JSF components like <t:dataTable>, <t:dataScroller>, <t:panelTabbedPane>, and <t:saveState>, we have seen what JSF has promised: a simple and powerful component-based Web application framework. The developer now can
leave the details and complexity to the component builder and focus on what's important for the business.
In this article, I only demonstrate a small fraction of MyFaces components that are part of MyFaces Tomahawk. As of Tomahawk version 1.1.1, about 27 components are ready to use. These Tomahawk components are 100 percent compatible with other JSF 1.1 reference implementations like the Sun RI or MyFaces RI.
Archived Discussions (Read only)