User Interface Design in ICEfaces 1.8: Part 2

Exclusive offer: get 50% off this eBook here
ICEfaces 1.8: Next Generation Enterprise Web Development

ICEfaces 1.8: Next Generation Enterprise Web Development — Save 50%

Build Web 2.0 Applications using AJAX Push, JSF, Facelets, Spring and JPA

$29.99    $15.00
by Rainer Eschen | November 2009 | AJAX Java Web Development

This is the second part of the article series on User Interface Design in ICEfaces 1.8. This article will cover facelets templating and templating in ICEfusion. Read User Interface Design in ICEfaces 1.8: Part 1 here.

Facelets templating

To implement the layout design, we use the Facelets templating that is officially a part of the JSF specification since release 2.0. This article will only have a look at certain parts of the Facelets technology. So, we will not discuss how to configure a web project to use Facelets. You can study the source code examples of this article, or have a look at the developer documentation (https://facelets.dev.java.net/nonav/docs/dev/docbook.html) and the articles section of the Facelets wiki (http://wiki.java.net/bin/view/Projects/FaceletsArticles)for further details.

The page template

First of all, we define a page template that follows our mockup design. For this, we reuse the HelloWorld(Facelets) application. You can import the WAR file now if you did not create a Facelets project.

For importing a WAR file, use the menu File | Import | Web | WAR file. In the dialog box, click on the Browse button and select the corresponding WAR file. Click on the Finish button to start the import. The run configuration is done. However, you do not have to configure the Jetty server again. Instead, it can be simply selected as your target.

We start coding with a new XHTML file in the WebContent folder. Use the menu File | New | Other | Web | HTML Page and click on the Next button. Use page-template.xhtml for File name in the next dialog. Click on the Next button again and choose New ICEfaces Facelets.xhtml File (.xhtml). Click on the Finish button to create the file.

The ICEfaces plugin creates this code:

<!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:ice="http://www.icesoft.com/icefaces/component">
<head>
<title>
<ui:insert name="title">
Default title
</ui:insert>
</title>
</head>
<body>
<div id="header">
<ui:include src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="/header.xhtml">
<ui:param name="param_name" value="param_value"/>
</ui:include>
</div>
<div id="content">
<ice:form>
</ice:form>
</div>
</body>
</html>

The structure of the page is almost pure HTML. This is an advantage when using Facelets. The handling of pages is easier and can even be done with a standard HTML editor.

The generated code is not what we need. If you try to run this, you will get an error because the header.xhtml file is missing in the project. So, we delete the code between the <body> tags and add the basic structure for the templating. The changed code looks like this:

<!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:ice="http://www.icesoft.com/icefaces/component">
<head>
<title>
<ui:insert name="title">
Default title
</ui:insert>
</title>
</head>
<body>
<table align="center" cellpadding="0" cellspacing="0">
<tr><td><!-- header --></td></tr>
<tr><td><!-- main navigation --></td></tr>
<tr><td><!-- content --></td></tr>
<tr><td><!-- footer --></td></tr>
</table>
</body>
</html>

We change the <body> part to a table structure. You may wonder why we use a <table> for the layout, and even the align attribute, when there is a <div> tag and CSS. The answer is pragmatism. We do not follow the doctrine because we want to get a clean code and keep things simple. If you have a look at the insufficient CSS support of the Internet Explorer family and the necessary waste of time to get things running, it makes no sense to do so. The CSS support in Internet Explorer is a good example of the violation of user expectations.

We define four rows in the table to follow our layout design. You may have recognized that the <title> tag still has its <ui:insert> definition. This is the Facelets tag we use to tell the templating where we want to insert our page-specific code. To separate the different insert areas from each other, the <ui:insert> has a name attribute.

We substitute the comments with the <ui:insert> definitions, so that the templating can do the replacements:

<!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:ice="http://www.icesoft.com/icefaces/component">
<head>
<title>
<ui:insert name="title">
Default title
</ui:insert>
</title>
</head>
<body>
<table align="center" cellpadding="0" cellspacing="0">
<tr><td><ui:insert name="header"/></td></tr>
<tr><td><ui:insert name="mainNavigation"/></td></tr>
<tr><td><ui:insert name="content"/></td></tr>
<tr><td><ui:insert name="footer"/></td></tr>
</table>
</body>
</html>

The <ui:insert> tag allows us to set defaults that are used if we do not define something for replacement. Everything defined between <ui:insert> and </ui:insert> will then be shown instead. We will use this to define a standard behavior of a page that can be overwritten, if necessary. Additionally, this allows us to give hints in the rendering output if something that should be defined in a page is missing.

Here is the code showing both aspects:

<!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:ice="http://www.icesoft.com/icefaces/component">
<head>
<ice:outputStyle href="/xmlhttp/css/royale/royale.css" />
<title>
<ui:insert name="title">
Please, define a title.
</ui:insert>
</title>
</head>
<body>
<table align="center" cellpadding="0" cellspacing="0">
<tr><td>
<ui:insert name="header">
<ice:graphicImage url="/logo.png" />
</ui:insert>
</td></tr>
<tr><td>
<ui:insert name="mainNavigation">
<ice:form>
<ice:menuBar noIcons="true">
<ice:menuItem value="Menu 1"/>
<ice:menuItem value="Menu 2"/>
<ice:menuItem value="Menu 3"/>
</ice:menuBar>
</ice:form>
</ui:insert>
</td></tr>
<tr><td>
<ui:insert name="content">
Please, define some content.
</ui:insert>
</td></tr>
<tr><td>
<ui:insert name="footer">
<ice:outputText
value="&#169; 2009 by The ICEcubes." />
</ui:insert>
</td></tr>
</table>
</body>
</html>

The header, the main navigation, and the footer now have defaults. For the page title and the page content, there are messages that ask for an explicit definition. The header has a reference to an image. Add any image you like to the WebContent and adapt the url attribute of the <ice:graphicImage> tag, if necessary. The example project for this article will show the ICEcube logo. It is the logo that is shown in the mockup above. The <ice:menuBar> tag has to be surrounded by a <ice:form> tag, so that the JSF actions of the menu entries can be processed. Additionally, we need a reference to one of the ICEfaces default skins in the <head> tag to get a correct menu presentation. We take the Royale skin here.

If you do not know what the Royale skin looks like, you can have a look at the ICEfaces Component Showcase (http://component-showcase.icefaces.org) and select it in the combo box on the top left. After your selection, all components present themselves in this skin definition.

Using the template

A productive page template has a lot more to define and is also different in its structure. References to your own CSS, JavaScript, or FavIcon files are missing here. The page template would be unmaintainable soon if we were to manage the pull-down menu this way.

However, we will primarily look at the basics here. So, we keep the page template for now. Next, we adapt the existing ICEfacesPage1.xhtml to use the page template for its rendering.

Here is the original code:

<?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:ice="http://www.icesoft.com/icefaces/component">
<head>
<title>
<ui:insert name="title">
Default title
</ui:insert>
</title>
</head>
<body>
<div id="header">
<!--
<ui:include src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="/header.xhtml" >
<ui:param name="param_name" value="param_value" />
</ui:include>
-->
</div>
<div id="content">
<ice:form>
<ice:outputText value="Hello World!"/>
<!--
drop ICEfaces components here
-->
</ice:form>
</div>
</body>
</html>

We keep the Hello World! output and use the new page template to give some decoration to it. First of all, we need a reference to the page template so that the templating knows that it has to manage the page. As the page template defines the page structure, we no longer need a <head> tag definition.

You may recognize <ui:insert> in the <title> tag. This is indeed the code we normally use in a page template. Facelets has rendered the content in between because it did not find a replacement tag. Theoretically, you are free to define such statements in any location of your code. However, this is not recommended. Facelets has a look at the complete code base and matches pairs of corresponding name attribute definitions between <ui:insert name="..."> and <ui:define name="..."> tags.

Here is the adapted code:

<?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:ice="http://www.icesoft.com/icefaces/component">
<body>
<ui:composition template="/page-template.xhtml">
<div id="content">
<ice:form>
<ice:outputText value="Hello World!"/>
</ice:form>
</div>
</ui:composition>
</body>
</html>

This code creates the following output:

ICEfaces 1.8: Next Generation Enterprise Web Development

We can see our friendly reminders for the missing title and the missing content. The header, the main navigation, and the footer are rendered as expected. The structure of the template seems to be valid, although we recognize that a CSS fle is necessary to define some space between the rows of our layout table.

However, something is wrong. Any idea what it is? If you have a look at the hello-world.xhtml again, you can find our Hello World! output; but this cannot be found in the rendering result. As we use the page template, we have to tell the templating where something has to be rendered in the page. However, we did not do this for our Hello World! output.

The following code defines the missing <ui:define> tag and skips the <div> and <ice:form> tags that are not really necessary here:

<!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:ice="http://www.icesoft.com/icefaces/component">
<body>
<ui:composition template="/page-template.xhtml">
<ui:define name="title">
Hello World on Facelets
</ui:define>
<ui:define name="content">
<ice:outputText value="Hello World!"/>
</ui:define>
</ui:composition>
</body>
</html>
ICEfaces 1.8: Next Generation Enterprise Web Development Build Web 2.0 Applications using AJAX Push, JSF, Facelets, Spring and JPA
Published: November 2009
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

The code shows that Facelets supports textual output in two ways:

  • Using a tag as we do with the Hello World! output
  • Without a tag as we do with the <title> tag

The next screenshot shows the rendering result:

ICEfaces 1.8: Next Generation Enterprise Web Development

The templating in ICEfusion

ICEfusion already delivers a standardized templating. This is based on experiences from productive development. We will use this for ICEcube and extend it. To familiarize you with the ideas, we will first have a look at some of the implementation details.

Running ICEfusion

There is a ZIP archive for this article that delivers release 1.0.1 of ICEfusion. You can use this distribution for the following source code studies. For this, take care that the MySQL server is already running.

You can use the following command in Maven 2 to build the project in the pom.xml folder (or run first-time-run.bat):

mvn install

Ignore the errors that are shown during running the tests. The important thing with this run is the initialization of the database. After this, you can run Maven 2 again using the following command (or run run.bat):

mvn clean install jetty:run-war -Dmaven.test.skip=true

The tests will be skipped to prevent the errors and the Maven 2 internal Jetty is used for deployment. Use http://localhost:8080 in your web browser to have a look at the application.

The ICEfusion files

The ICEfusion project follows the Maven 2 conventions. So, the ICEfusion extensions to AppFuse can be found in /icefusion/src/main/webapp/icefusion/. In this folder, you can find the Spring configuration files. Additionally, there are folders for JavaScripts (/scripts/), ICEfaces skins (/styles/), and the Facelets templating (/taglibs/). The folder names follow the AppFuse conventions.

The page layout files can be found in /icefusion/src/main/webapp/icefusion/taglibs/commons/. We'll have a look at the page template first (/icefusion/src/main/webapp/icefusion/taglibs/commons/page.xhtml).

<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html 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:ice="http://www.icesoft.com/icefaces/component"
xmlns:t="http://myfaces.apache.org/tomahawk"
xmlns:icefusion="http://icefusion.googlecode.com/icefusion">
<f:view locale="#{context.locale}">
<f:loadBundle basename="icefusion.icefusion"
var="icefusion"/>
<head>
<ice:outputStyle href="#{iceFusionConsts.skinBase}/
#{context.skin}/page.css" />
<ice:outputStyle href="#{iceFusionConsts.skinBase}/
#{context.skin}/icefaces.css" />
<ice:outputStyle href="#{iceFusionConsts.skinBase}/
#{context.skin}/style.css" />
<script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original=
"#{iceFusionConsts.contextPath}
#{iceFusionConsts.scriptBase}/connectionStatus.js" >
</script>
<script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original=
"#{iceFusionConsts.contextPath}
#{iceFusionConsts.scriptBase}/icefusion.js" />
<link rel="shortcut icon" href=
"#{iceFusionConsts.contextPath}
#{iceFusionConsts.skinBase}/#{context.skin}/
images/page.ico"/>
<title>
#{iceFusionConsts.application}
#{iceFusionConsts.release} - <ui:insert name="title">
This page has no title.</ui:insert>
</title>
</head>
<body>
<icefusion:connectionStatus />
<table align="center" cellpadding="0" cellspacing="0"
class="layout">
<tr><td class="header">
<ui:insert name="header">
<icefusion:header/>
</ui:insert>
</td></tr>
<tr><td class="navigation">
<ui:insert name="navigation">
<icefusion:navigation/>
</ui:insert>
</td></tr>
<tr><td class="content">
<ui:insert name="content">
This page has no content.
</ui:insert>
</td></tr>
<tr><td class="footer">
<ui:insert name="footer">
<icefusion:footer/>
</ui:insert>
</td></tr>
</table>
<ui:debug/>
</body>
</f:view>
</html>

The code is similar to our example above. However, it references skin definitions that are varied via an Expression Language reference to a Spring bean, context.skin. The bean delivers a folder name. Each of the possible skin folders has the same folder and file structure. This allows us to switch between them without any adaptation in the templating.

Another variation is the use of custom Facelets tags. We use these to define the different sections in the page layout. This is primarily done for maintenance purposes. In contrast to our Facelets example, the menu can then be managed in a dedicated file.

The new tags are managed via a Facelets tag library. We use the icefusion namespace to reference the tags.

Next, we will look at the code of the icefusion tags. The header can be found at /icefusion/src/main/webapp/icefusion/taglibs/commons/header.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ice="http://www.icesoft.com/icefaces/component"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:icefusion=
"http://icefusion.googlecode.com/icefusion">
<body>
<ui:component>
<ice:graphicImage url="#{iceFusionConsts.skinBase}/
#{context.skin}/images/logo.png" />
</ui:component>
</body>
</html>

This looks almost like our example, although the logo is managed via the skin selection. You may recognize the <ui:component> tag. This describes where the code for a Facelets tag starts and stops. Everything outside this tag is ignored.

The main navigation is defined in /icefusion/src/main/webapp/icefusion/taglibs/commons/navigation.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ice="http://www.icesoft.com/icefaces/component"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:icefusion=
"http://icefusion.googlecode.com/icefusion">
<body>
<ui:component>
<c:if test="#{context.dynamicMenu}">
<icefusion:dynamicMenu/>
</c:if>
<c:if test="#{!context.dynamicMenu}">
<icefusion:menu/>
</c:if>
<icefusion:menuIcons />
</ui:component>
</body>
</html>

The navigation tag already considers the mockup design. We have definitions for menu and additional menu icons. The menu definition allows you to choose between a static menu definition and a dynamic one.

The corresponding code for the static menu tag can be found in /icefusion/src/main/webapp/icefusion/taglibs/commons/menu.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ice="http://www.icesoft.com/icefaces/component"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:icefusion=
"http://icefusion.googlecode.com/icefusion">
<body>
<ui:component>
<ice:form>
<ice:menuBar noIcons="true">
<!-- Add your menu items here -->
<!-- ICEfusion standard entries -->
<ice:menuItem value=
"#{icefusion['application.menu.extra']}">
<ice:menuItem value="#{icefusion[
'application.menu.extra.settings']}"
action="settings"/>
<ice:menuItem value="#{icefusion[
'application.menu.extra.about']}"
action="about"/>
</ice:menuItem>
</ice:menuBar>
</ice:form>
</ui:component>
</body>
</html>

The code for the dynamic menu is defined in /icefusion/src/main/webapp/icefusion/taglibs/commons/dynamicMenu.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ice="http://www.icesoft.com/icefaces/component"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:icefusion=
"http://icefusion.googlecode.com/icefusion">
<body>
<ui:component>
<ice:panelGrid columns="2">
<ice:form>
<ice:menuBar noIcons="true">
<ice:menuItems value="#{dynamicMenu.menuModel}" />
</ice:menuBar>
</ice:form>
</ice:panelGrid>
</ui:component>
</body>
</html>

The menu entries are created by a special backing bean. The dynamic menu creates the same presentation as the static menu does.

The menu icons are defined in /icefusion/src/main/webapp/icefusion/taglibs/commons/menuIcons.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ice="http://www.icesoft.com/icefaces/componen
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:icefusion=
"http://icefusion.googlecode.com/icefusion">
<body>
<ui:component>
<div class="menuIcons">
<ice:form>
<ice:panelGroup columns="2">
<ice:commandLink action="#{menuIcons.switchToEn}">
<ice:graphicImage url=
"#{iceFusionConsts.skinBase}/
#{menuIcons.skin}/images/locale/en.png" />
</ice:commandLink>
<ice:commandLink action="#{menuIcons.switchToDe}">
<ice:graphicImage url=
"#{iceFusionConsts.skinBase}/
#{menuIcons.skin}/images/locale/de.png" />
</ice:commandLink>
</ice:panelGroup>
</ice:form>
</div>
</ui:component>
</body>
</html>

Last but not the least, we will have a look at the footer code that can be found at /icefusion/src/main/webapp/icefusion/taglibs/commons/footer.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ice="http://www.icesoft.com/icefaces/component"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:icefusion=
"http://icefusion.googlecode.com/icefusion">
<body>
<ui:component>
<ice:outputLink value="http://icefusion.googlecode.co
target="_blank">
<ice:outputText value="ICEfusion" />
</ice:outputLink>
<ice:outputText value=" &#169; 2009 Rainer Eschen |
AppFuse &#169; 2004-2008 Matt Raible et al." /><br/
<ice:outputLink value=
"http://www.apache.org/licenses/LICENSE-2.0"
target="_blank">
<ice:outputText value="Apache License 2.0" />
</ice:outputLink>
</ui:component>
</body>
</html>

This footer also defines a copyright hint. It is extended with a link to the license text.

The following screenshot shows how the rendered result looks:

ICEfaces 1.8: Next Generation Enterprise Web Development

We would adapt the ICEfusion code base to create our ICEcube base from it. The ICEcube code base will then be iteratively extended with the sample code.

Summary

The creation of desktop-like web applications is a challenging task. Following the principles of ergonomics is an important part on our way to a useful interface design. However, we have to expect several iterations before we get a suitable result. During this process, a mockup tool can help us develop page designs in a fast and easy way.The Facelets templating can be used to implement fexible and maintainable page designs. With ICEfusion, we get a production-ready templating implementation that can be used for the creation of ICEcube.

[ 1 | 2 ]

If you have read this article you may be interested to view :


ICEfaces 1.8: Next Generation Enterprise Web Development Build Web 2.0 Applications using AJAX Push, JSF, Facelets, Spring and JPA
Published: November 2009
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

About the Author :


Rainer Eschen

Rainer Eschen has a degree in computer science. He looks back on more than 20 years of programming experience. Since 1994 he works as an IT professional with a focus on consulting and architecture. He has also been part of “the source” for three years, working as Sun Sales Support Engineer and Sun Java Center Architect at Sun Microsystems, Germany.

Books From Packt

JBoss AS 5 Development
JBoss AS 5 Development

GlassFish Administration
GlassFish Administration

JBoss RichFaces 3.3
JBoss RichFaces 3.3

RESTful Java Web Services
RESTful Java Web Services

DWR Java AJAX Applications
DWR Java AJAX Applications

Spring Persistence with Hibernate
Spring Persistence with Hibernate

Pentaho Reporting 3.5 for Java Developers
Pentaho Reporting 3.5 for Java Developers

JasperReports 3.5 for Java Developers
JasperReports 3.5 for Java Developers

Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software