 | Level: Intermediate Joe Sam Shirah (joesam@conceptgo.com), Developer and Principal, conceptGO
25 Mar 2008 Today's clients want and have begun to expect desktop features in
browser-based applications. RichFaces is one of a new breed of user interface
component suites available for Java™ Server Faces (JSF). Among other
benefits, RichFaces provides built-in JavaScript and Ajax capabilities to meet those
expectations. Joe Sam Shirah adds some new tools to your kit based on experiences
with a recent field project, including general setup for using RichFaces with
Facelets, and several specific component examples.
Recently a client engaged my company for what I considered to be a dream project.
They had no on-staff developers and asked us to design and develop their first
production application involving a server with a browser client. The application
would run over their local-area network (LAN) and over the Internet, using a
virtual private network (VPN). It's not unusual for me to take a project from an
idea through implementation and training, but this was a rare opportunity to
specify virtually everything involved in the project. One major, if unstated,
aspect of the project was that everyone was accustomed to desktop applications.
They would probably not particularly notice the inclusion of similar features in
the browser user interface, but I had no doubt there would be many complaints if
those features were missing. The primary page for the initial phase of the
project, for example, would collect selection criteria for dynamic queries.
Several input sections called for client-side operations, and at least one needed
Ajax functionality. In the end I selected the RichFaces component suite, which is
built on and merged with Ajax4jsf (see Resources).
 |
Choices, choices
This article's intent is not to promote a specific product or component suite.
Rather, it's to give you enough information to get started with RichFaces and
some background to use for comparison when you develop your own RIA or rich Web
client. I encourage you to check out the possibilities, using this and other
articles for pointers, and to come to your own conclusions.
A good place to start your research is the JSF AJAX Component Library Feature
Matrix (see Resources). Be sure to review any comments
at the bottom of that page, because the matrix is updated infrequently and this
area changes rapidly. My own short list quickly reduced to RichFaces, Woodstock,
and IceFaces (see Resources).
|
|
In addition to Rich Internet Application (RIA) capabilities and Ajax, my needs
included:
- Open source, LGPL or Apache-style license, if possible
- Works with JSF and Facelets
- Works in conjunction with JSF Reference Implementation (RI) components
- Flexible but consistent look-and-feel or theme
- Large enough set of components to cover most application requirements
- Reasonably easy to work with, without show stoppers
- Dynamic creation ability, with available API
- Active development and community
To this point, RichFaces has met these criteria, and the components have been
valuable in creating effective and functional applications. As always, your
criteria and mileage may vary.
This article explores several useful RichFaces components and includes code for
a demonstration application (see Download). Before we
begin to look over RichFaces, however, there are some necessary infrastructure
elements to cover.
From the beginning
Although in the initial phase the client's application could run using just a
servlet container, future work would require additional support and would likely
include projects for other corporate subsidiaries. To keep things as standard as
possible, I chose the open source Glassfish Application Server V2, which supports
JEE 5, and used Java SE 6 as the underlying runtime. For the Web framework, JSF
and Facelets were my choice. As a bonus, JSF support is included in Java EE 5; for
Glassfish V2, WebSphere Application Server Community Edition V2, and others, the
JSF version supported is 1.2. Facelets (or similar) support is a goal for JSF 2.0,
and the primary Facelets developer is on the JSF Expert Group.
This article assumes readers have a basic knowledge of these areas. The example
code download includes everything you need for Tomcat 6.0.16 and Glassfish, and
has been tested on both. The online version (see
Resources) runs on Glassfish V2. If you need more
background on these technologies, see Resources for
appropriate links.
Not small faces
Facelets, despite its name, is not a smaller version of JSF; instead, at its
core, Facelets provides an alternative to JSP as a JSF
ViewHandler, and that's what we'll use it for here.
When I first researched JSF, I ran across Hans Bergsten's article "Improving JSF
by Dumping JSP" (see Resources). Shortly thereafter, I
discovered Facelets and have never looked back. Facelets supports all of the JSF
UI components and builds its own component tree, reflecting the view for a JSF
application. Although both JSP and JSF technologies have been improved to work
together better, Facelets just works, completely eliminating the issues noted in
Bergsten's article.
I prefer keeping things as clean and straightforward as possible. In the example
project, you'll see that virtually all of the code (as opposed to markup) is
composed of Expression Language (EL) expressions for getters, setters, and method
bindings. Although more complex projects may call for more complex expressions, in
general Facelets makes it easy to keep Java code separate from your Web page
markup.
The primary differences you'll notice here from "normal" JSF development using
JSP are:
- You'll need jsf-facelets.jar.
- Some notations in web.xml and faces-config.xml.
- Web pages are XHTML documents.
- XML namespaces are used rather than JSP taglibs.
As far as formatting goes, other than the initial portions (see
Listing 1), everything in the Web page should look
familiar. I view that aspect as an understated Facelets feature. For this
article's project, and many others where the primary use of Facelets is for
handling the view, that's really all you need to know. Facelets also includes a
number of other useful features, such as easy templating and elements to make life
easier for Web page designers. For readers interested in learning more about
Facelets, I recommend starting with "Inside Facelets Part 1: An Introduction" (see
Resources).
Listing 1. Initial portion of a Facelets XHTML document
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html" >
|
The demonstration components
RichFaces can seem overwhelming; the average component has over 20 specific
attributes, plus general attributes that can be overridden. However, most
attributes have reasonable defaults, and in typical usage, the components are not
difficult to set up. There are several flashy components that handle various
effects like Google Maps and Virtual Earth. You may want to use them to excite
your user base, but here I am going to focus on components that will be useful
across many applications. That's exciting enough for me.
The primary components demonstrated in this article are:
We'll also use a Panel Bar for instructions. Figure 5 shows
an example:
Figure 5. RichFaces Panel Bar
component
And we'll use Simple Toggle Panels for results. Figure 6
shows an example:
Figure 6. RichFaces Simple Toggle
Panel component
As I mentioned earlier, RichFaces is built on Ajax4jsf. Thanks to that
foundation, any component can be Ajax-enabled in several different ways. The
example application uses Ajax capabilities for the Suggestion Box and Simple
Toggle Panel components.
My brave face
The dWRFDemo1 example application is minimal; its
only real purpose is to demonstrate setup and usage of the selected components.
For that reason, all it does is collect and display input data. I'll leave to your
imagination how to use the data and components in a production application. Aside
from necessary JARs, images, a properties file used as a resource bundle, and a
Cascading Style Sheets (CSS) file, the application consists of two XHTML pages and
two Java classes. This simplicity also allows the code to be IDE agnostic. In
fact, I purposely created it with just a Java editor, Wordpad for the files,
javac, and the jar command.
The URL for the input page displayed in Figure 7, assuming
default setup for Tomcat or Glassfish, is
http://localhost:8080/dWRichFacesDemo1.
The input
page allows you to select a date using the Calendar component. The Order
By List Shuttle component lets you move and reorder the available items. The
City Suggestion Box lets you key in a city name. City is Ajax-enabled;
if you
press the space bar, all available cities are shown. If you key city names
beginning with an A or a J, lists of the appropriate cities are shown. The
available cities on the list narrow as you key more characters. You can click on
the Panel Bar items on the left for very basic component instructions.
Figure 7.
dWRFDemo1 input page
Once you've made your entries, click the Submit button.
The application is so minimal that no editing is performed. Because manual input
is disabled for the Calendar component, you can't even enter an invalid date. The
Submit button causes the results page to display, as shown in
Figure 8:
Figure 8.
dWRFDemo1 Result page
On the results page, click on the Result tab, then click the appropriate Simple
Toggle Panel item to see the input value. Click the Edit button to return to the
input page.
Set me up
The very first things necessary for an application are the JSF, Facelets, and
RichFaces enablers — that is, the JARs that implement the capabilities.
These JARs, with the versions noted in the lists below, are included in the lib
directory of the downloadable WAR (see Download). The list
assumes your Web container supports current EL and servlet API versions. If you
have issues running the demonstration, check JSF, Facelets, and RichFaces
requirements (see Resources.) You should also review the
Download note.
- JSF 1.2 (as included in Glassfish V2)
- Facelets 1.1.14
- RichFaces
- richfaces-api-3.1.4.GA.jar
- richfaces-impl-3.1.4.GA.jar
- richfaces-ui-3.1.4.GA.jar
- Although they are not noted as explicit requirements, RichFaces assumes the
following JARs are also available:
- commons-beanutils-1.7.0.jar
- commons-collections-3.2.jar
- commons-digester-1.8.jar
- commons-logging-1.0.4.jar
- jhighlight-1.0.jar
Next are web.xml entries, shown in Listing 2, needed to
enable JSF:
Listing 2. Minimum JSF entries required in web.xml
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
|
Listing 3 shows another web.xml entry needed for Facelets.
The entry overrides the .jsp default suffix. Normally, Facelets requires another
overriding entry for the view handler in faces-config.xml, but the RichFaces
setup, as you'll see below, includes the override in web.xml.
Listing 3. web.xml entry for Facelets suffix
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
|
Listing 4 shows the elements needed in web.xml to enable
RichFaces:
Listing 4. web.xml entries to enable RichFaces
<context-param>
<param-name>org.richfaces.SKIN</param-name>
<param-value>classic</param-value>
</context-param>
<context-param>
<param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
<param-value>com.sun.facelets.FaceletViewHandler</param-value>
</context-param>
<filter>
<display-name>RichFaces Filter</display-name>
<filter-name>richfaces</filter-name>
<filter-class>org.ajax4jsf.Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>richfaces</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
|
I'll explain the elements in Listing 4 in the order that makes things operable,
rather than the order in which they appear in web.xml:
-
<filter>
and
<filter-mapping>
RichFaces uses a filter to process code received on Ajax requests. These
elements define the filter class
(org.ajax4jsf.Filter) and map it to the JSF Faces
Servlet defined in Listing 2.
-
<context-param>
and
<param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
RichFaces needs to know that Facelets will be used in the application. These
elements perform that task and also effectively replace the normal Facelets
entry in faces-config.xml. Notice that the Facelets view handler class is
com.sun.facelets.FaceletViewHandler.
-
<context-param>
and
<param-name>org.richfaces.SKIN</param-name>
RichFaces has several built-in color schemes or skins. These elements define
the skin you want to use in your application. The
classic skin is a moderate blue.
The good news about the entries in Listings 2, 3, and 4 is that they are
virtually the same in all of your applications and essentially boilerplate code.
While we're at it, let's dispense with one more piece that you'll see in every
application: Listing 5 is a modification of
Listing 1 to include the RichFaces namespace in
application XHTML pages:
Listing 5. Initial portion of a Facelets/RichFaces XHTML document
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich" >
|
Ready to rock
We are now ready to use RichFaces components. I'll begin with a Panel Bar and
Panel Bar Items (see Figure 5). You probably won't use these
very often, but they are easy to work with and provide a good first use case for
RichFaces syntax.
The idea here is that a Panel Bar is a container for Panel Bar Items. A Panel
Bar Item has a label and can contain any other component. Panel Bar Items stack on
top of one another; the actual content is shown when the bar for the item is
clicked. Only one item's content is shown at a time. In this case, as you can see
from Listing 6, we're just using text. Notice that all
components have a rich: prefix, which refers to the
namespace entry included in Listing 5.
Listing 6. RichFaces Panel Bar component
<rich:panelBar height="192" width="256">
<rich:panelBarItem label="#{dWRFD1.calComp} #{dWRFD1.info}">
<h:outputText value="#{dWRFD1.calCompText}" style="font: menu;" />
</rich:panelBarItem>
<rich:panelBarItem label="#{dWRFD1.lsComp} #{dWRFD1.info}">
<h:outputText value="#{dWRFD1.lsCompText}" style="font: menu;" />
</rich:panelBarItem>
<rich:panelBarItem label="#{dWRFD1.sbComp} #{dWRFD1.info}">
<h:outputText value="#{dWRFD1.sbCompText}" style="font: menu;" />
</rich:panelBarItem>
</rich:panelBar>
|
 |
Where's
<f:loadBundle>?
In JSF 1.2, you can define a properties-based resource bundle in
faces-config.xml, so there's no longer a need for
<f:loadBundle> on every page. The
definition is similar to entries for managed beans, but specific to resource
bundles. Example:
<resource-bundle>
<base-name>dWRFDemo1</base-name>
<var>dWRFD1</var>
</resource-bundle>
|
|
|
The basic <rich:panelBarItem /> element
doesn't require much more than a label, which is pulled here from a resource
bundle using an EL expression.
The actual content for the demonstration Panel Bar Items is just an
<h:outputText /> element, again with text
from the resource bundle. I use a font style element
for consistent readability, but also to show that RichFaces allows CSS
flexibility.
Notice that no programmer involvement with the generated JavaScript is
necessary. In just a few steps you can create a nice-looking, multipanel,
clickable component; this is one of RichFaces' great strengths. Even components as
simple as this one allow active/inactive styles, events, and more.
Let's make a date
The Calendar component (see Figure 1) should be familiar;
date selection was probably one of the earliest JavaScript enhancements to Web
pages. The RichFaces Calendar has over 80 available attributes but, as you can see
from Listing 7, you can generally make do with fewer:
Listing 7. RichFaces Calendar component
<label for="CalendarID" >#{dWRFD1.calendar}:</label>
<rich:calendar name="Calendar" id="CalendarID"
value="#{dWRFD1Handler.selectedDate}"
timeZone="#{dWRFD1Handler.timeZone}"
datePattern="#{dWRFD1.datePattern}" >
</rich:calendar>
|
The datePattern attribute wants a standard date
pattern as defined by java.text.SimpleDateFormat. The
example again uses the resource bundle for the value, which defines the
datePattern key as
yyyy-MM-dd
. The value
and timeZone attributes are loaded using methods from a
managed bean, which is defined as shown in Listing 8:
Listing 8. Managed bean definition for dWRFD1Handler
<managed-bean>
<managed-bean-name>dWRFD1Handler</managed-bean-name>
<managed-bean-class>com.dW.dWRFD1Handler</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
|
The com.dW.dWRFD1Handler class is basic, consisting
mostly of an initializer, getters, and setters, and it should not require much
further discussion. The getSelectedDate() and
setSelectedDate() methods expect a
java.util.Date. The
getTimeZone() method just returns
java.util.TimeZone.getDefault(); whether that is
appropriate in production depends on your application requirements.
If you also want to allow the user to key in date values, set the
enableManualInput attribute to
true. If you just want to show the Calendar, set the
popup attribute to false.
Obviously many other settings are available, but that's about all you need for
basic Calendar functionality.
One way or another
The List Shuttle component (see Figure 2) is ideal for
selecting and ordering items from an initial group.
Listing 9 demonstrates that it is also easier to use than
you might initially think:
Listing 9. RichFaces List Shuttle component
<label for="OrderByID">#{dWRFD1.orderBy}:</label>
<rich:listShuttle sourceValue="#{dWRFD1Handler.orderBySource}"
name="OrderBy" id="OrderByID"
targetValue="#{dWRFD1Handler.orderByTarget}" var="items"
<h:column>
<h:outputText value="#{items}"></h:outputText>
</h:column>
</rich:listShuttle>
|
The actual XHTML markup in the example code includes additional attributes to
override some default labels, but typical usage requires only the
sourceValue, targetValue,
var, and column attributes.
The sourceValue and
targetValue values are
java.util.List classes containing any type of object.
As with the demo code, you'll probably use lists containing
Strings most of the time. Other than the initialization
of the sourceValue, Listing 10
shows all of the Java code related to the example List Shuttle:
Listing 10. Relevant dWRFD1Handler List Shuttle code
private List<String> lOrderBySource = new ArrayList<String>(),
lOrderByTarget = new ArrayList<String>();
...
public List getOrderBySource()
{
return lOrderBySource;
}
public List getOrderByTarget()
{
return lOrderByTarget;
}
...
public void setOrderBySource( List<String> orderBySource )
{
lOrderBySource = orderBySource;
}
public void setOrderByTarget( List<String> orderByTarget )
{
lOrderByTarget = orderByTarget;
}
|
The var attribute declares a variable that will be
used to iterate over the list, a pattern often used by JSF components. You
actually can have multiple columns if the objects in your lists support multiple
fields. In that case, the notation changes from
value="#{items}" to
value="#{items.getterMethodName}", which should be no
big surprise. Here we have a list of String classes and
so only one column. After the user has made the desired choices, on submittal your
handler receives the ordered target list containing the choices.
Tell me to my face
If you frequent forums and mailing lists, sooner or later you will see a
question that asks how to handle downloading thousands or millions of entries to a
drop-down list. The Suggestion Box component (see Figure 3)
offers a way to show valid selections without attempting that unworkable extreme.
In fact, that concern was a major reason I began investigating RichFaces and
similar suites, because several entry items in the application, such as cities,
had too many possibilities for a drop-down list to make sense. The Suggestion Box
functionality is similar to the familiar auto-complete components available in
many desktop applications. It should be apparent that Ajax submittals would
probably have to be involved for that sort of capability to have any chance of
working efficiently in a Web application.
Listing 11 shows three distinct component parts needed
for effective functionality: the label and input text (notice that these are
standard JSF RI components),
<a4j:region>, and
<rich:suggestionbox>. The
<h:inputText> uses
getCity() and setCity()
methods for its values in conjunction with the managed bean. The field's input is
either keyed or selected from the Suggestion Box.
Listing 11. RichFaces Suggestion Box component
<label for="CityID">#{dWRFD1.city}:</label>
<h:inputText name="City" id="CityID" size="10"
value="#{dWRFD1Handler.city}" />
<a4j:region renderRegionOnly="true">
<rich:suggestionbox id="citySuggestionBoxId" for="CityID"
suggestionAction="#{dWRFD1City.suggest}" var="result"
eventsQueue="foo" ignoreDupResponses="true"
selectedClass="selCtl" >
<h:column>
<h:outputText value="#{result}" style="font: menu;" />
</h:column>
</rich:suggestionbox>
</a4j:region>
|
<a4j:region> denotes an area that is sent
on an Ajax submit. You need to be aware that, in general, if no region is
included, RichFaces assumes a default region from
<f:view> to
</f:view>. That's essentially the entire
page. When I first used
<rich:suggestionbox>, everything worked,
but stepping through debug showed that all the other fields were submitted as
well, with validation, conversion, and passing through the whole JSF life cycle.
To put it mildly, that's not a good situation for something that responds to every
key press. An excerpt from the RichFaces Developer Guide (see
Resources) discussing another form of Ajax submittal
applies in general, and should drive the point home:
Note, that "ajaxSingle"="true" reduces the upcoming traffic, but does
not prevent decoding other input components on the server side. Some JSF
components, such as <h:selectOneMenu> do recognize the missing data
in the request map value as a null value and try to pass the validation process
with a failed result. Thus, use <a4j:region> to limit a part of the
component tree that will be processed on the server side when it is required.
As for the renderRegionOnly attribute, the RichFaces
Developer Guide describes it this way:
Flag to disable rendering in AJAX responses content outside of active
region. If this attribute set to "true", no one of the components outside of
region will be included to AJAX response. If set to "false", search for components
to include in response will be performed on all tree. Default "false".
In this case, the only element we want to go back to the server is the
suggestionAction method request along with its
Object argument (the current keyed input
String). On return, only the Suggestion Box content
should be updated and rendered.
The minimum attributes required for the Suggestion Box itself are
suggestionAction, var, and
at least one column to display results. The
suggestionAction method is
suggest() in another managed bean based on the second
Java class in the demo code, com.dW.City. The method
signature is: public List suggest(Object anObject).
In the demo code, a list of cities beginning with A and J is created on
initialization. If the user presses the space bar in the City text field, the
entire list is returned. If A is pressed, a sublist containing the cities starting
with A is returned; J cities are handled in the same way. Results are narrowed
with each keystroke. In your own code, you can do anything you want that is
appropriate to the input. In the real application, the results come from a limited
database set, which is probably most typical. If you are familiar with the data,
you can probably take steps in the method to optimize results. I have cases, for
example, where certain keystrokes can be ignored, so the method just returns,
eliminating a trip to the database.
The var attribute defines an iteration variable used
in outputting the column content. It's the same concept used and discussed for the
List Shuttle component's var attribute.
The eventsQueue attribute is not required, but I
recommend you treat it as such. You only need to add the attribute and supply a
name. It performs two important services:
- The method calls (events) are queued, guaranteeing order; the next method
request in the queue is not sent until the previous one returns.
- If multiple events of the same type are in the queue, only the latest is
sent. Suggestion Box, for example, sends a request on every keystroke. If
several keystroke requests are in the queue when a previous request returns,
only the last will go to the server. Keep in mind that although the request is
sent on each keystroke, the argument sent is the entire content of the input
text component.
The purpose of the ignoreDupResponses attribute
should be self-evident.
selectedClass is a CSS class to be applied to the
component. RichFaces uses the skins concept. This is carried through to the
selection bar on components. My own application had several RI drop-down lists
that used the system color for the bar. The Suggestion Box used the
classic skin color, which made things appear
inconsistent. The SelCtl class tells the Suggestion Box
to use the system highlight colors instead.
Keeping tabs
The Tab Panel component (see Figure 4) is straightforward to
use. The typical RichFaces attributes are available, but the primary one you will
use is switchType. The default is
server, and you'll probably most often want
client. ajax is also
available. As you can see from Listing 12, a typical
RichFaces "sandwich" of <rich:tabPanel>
elements and stacked "sandwiches" of
<rich:tab> elements are used to make a
set of tabbed pages:
Listing 12. RichFaces Tab Panel component
<rich:tabPanel switchType="client" >
<rich:tab label="#{dWRFD1.info}">
#{dWRFD1.resultText}
</rich:tab>
<rich:tab label="#{dWRFD1.result}">
</rich:tab>
</rich:tabPanel>
|
A label attribute is used for each tab's display
name. In the demo code, as usual, the label value is
pulled from the resource bundle. Similarly to Panel Bar Items, a tab can contain
any kind of component. For the demo, I used resource bundle text for the Info tab
content, and Simple Toggle Panels for the Result tab content.
Whenever I see your smiling face
I suspect you are thinking, "Not much to that last one," and you're right. Once
you understand the basics of RichFaces, simple usage for most components is just
that: simple. For that reason, I'm going to leave most of the Simple Toggle Panel
(see Figure 6 and Listing 13) as an
exercise for you.
Listing 13. RichFaces Simple Toggle Panel component
<h:panelGrid columns="1" width="50%">
<rich:simpleTogglePanel switchType="ajax"
label="#{dWRFD1.calComp} #{dWRFD1.value}" opened="false" >
#{dWRFD1Handler.selectedDate}
</rich:simpleTogglePanel>
<rich:simpleTogglePanel switchType="ajax"
label="#{dWRFD1.lsComp} #{dWRFD1.value}" opened="false" >
#{dWRFD1Handler.orderByTarget}
</rich:simpleTogglePanel>
<rich:simpleTogglePanel switchType="ajax"
label="#{dWRFD1.sbComp} #{dWRFD1.value}" opened="false" >
#{dWRFD1Handler.city}
</rich:simpleTogglePanel>
<rich:simpleTogglePanel switchType="ajax"
label="#{dWRFD1.face}" opened="false" >
<img src="images/myphoto.jpg"
height="80" width="64"/>
</rich:simpleTogglePanel>
</h:panelGrid>
|
Simple Toggle Panel consists of a bar and a content display, which can be any
component. The content is shown or hidden by clicking on the bar, acting very much
like a Panel Bar with only one item. Notice that the
switchType attribute makes a reappearance. The
opened attribute determines whether the content is
shown on first display. For the demo, I've put several Simple Toggle Panels in a
JSF RI <h:panelGrid>, which is placed in
a Tab, which is placed in a Tab Panel.
Wrap it up
RichFaces provides a large number of JSF components for building RIA and
Ajax-enabled Web applications. This article has demonstrated only a few, but you
should have gotten a feel for how things work under RichFaces, and seen several
components that could be useful in many applications. An online demo of all of the
components available in the suite, documentation, and other resources are
available from the "Most Important Links" section on the RichFaces home page (see
Resources.)
If you choose to use RichFaces, I encourage you to dig deeply into the
a4j: components and processing discussed in the
documentation to understand how to apply the concepts to the other RichFaces
components. My clients sometimes get frustrated when I say this is Yet Another
Area where Slower Is Faster, but the research time invested will pay multiple
dividends in your development process and run-time performance.
RichFaces 3.2, with additional components, is scheduled for release at the end
of March 2008. Regardless of which RIA component set you use, this kind of stiff
competition should help increase the stability and productivity of them all.
Download | Description | Name | Size | Download method |
|---|
| Demonstration WAR for this article1 | j-RichFacesDemo1.zip | 5.5MB | HTTP |
|---|
Note -
Because the source and WAR files differ by only two items — the Java
files — I've included the Java sources in the WAR file. As a result,
there is only one file download. For instruction on using the WAR files, see the
readme.txt file included with the download.
Resources Learn
-
Demo application: Interact
with an online demo of this article's sample application.
-
RichFaces: The RichFaces site
— especially the "Most Important Links" section — has links to
information, documentation, the online demo, and downloads.
-
RichFaces
Developer Guide (RedHat, 2007): Find further information about RichFaces
-
JSF technology: Find out
more about JSF and how to apply it in your applications.
-
"Improving JSF by Dumping JSP"
(Hans Bergsten, OnJava.com, June 2004): This article focuses on the problematic
use of JSP technology for creating JSF views.
-
"Inside Facelets Part 1: An Introduction"
(Jacob Hookom, JSF Central, August 2005): The Facelets project's founder explains
Facelets features.
-
"Facelets fits JSF like a glove"
and
"Advanced Facelets
programming"
(Richard Hightower, developerWorks, February/May 2006): Read this popular one-two
punch on Facelets.
-
Facelets: The Facelets site has links
to information and downloads.
-
Facelets Wiki: Find
the Facelets FAQ, articles, and examples.
-
The JSF AJAX Component Library Feature Matrix:
Compare JSF component libraries.
-
Project Woodstock: Another
project developing Web UI components.
-
ICEfaces.org: A project focused on Ajax for
Java EE.
-
The Rich Faces Cookbook:
Find and contribute community solutions to common RichFaces issues.
-
Apache Tomcat: Information on the Tomcat
servlet container.
-
Glassfish: Information on the
Glasshfish application server.
-
WebSphere Application Server Community Edition, V2:
A free, lightweight Java EE 5 application server.
-
developerWorks: Hundreds of
articles about every aspect of Java programming.
- Browse the
technology bookstore
for books on these and other technical topics.
Get products and technologies
Discuss
About the author  | 
|  | Joe Sam Shirah is a principal and developer at
conceptGO. While trying to keep clients
happy, he has authored several tutorials for developerWorks and the Sun Developer
site and is a winner of the Java Community Award. He is also the moderator of the
developerWorks
Java filter
forum and has managed jGuru's JDBC, I18N, and Java400 FAQs. |
Rate this page
|  |