Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Rapid Java Web Application Development with Tapestry : Page 4

Tapestry is a powerful and innovative framework for developing component-based Web applications. With Tapestry 4, things get even better.


WEBINAR: On-demand Event

Unleash Your DevOps Strategy by Synchronizing Application and Database Changes REGISTER >

Working with Links and Listeners

One of the major innovations of Tapestry (and other more recent frameworks such as JSF) is that HTML links, submit buttons, and the like are mapped directly to arbitrary Java class methods. In Tapestry, navigation logic and data submission are placed in these "listener" methods or, for simpler cases, directly configured in the Tapestry component itself.

For example, suppose you want to add a button that redisplays the Home screen with a new featured destination. Defining links to other pages is an important part of any Web application, and Tapestry provides several convenient ways of doing so. The easiest is to simply create a link to another Tapestry page, using the PageLink component, as shown here:

<a href="#" jwcid="@PageLink" page="Home">Show another feature destination!</a>

This will generate a correct href reference to the application Home page. One of the nice things about links in Tapestry is that you almost never have to worry about the exact form of the URL. In this case, you don't even need to add a method to the page class.

Now suppose you want to add a "Show Details" button to your Home page. You would need to add a link to the details page and provide a parameter that indicates which offer to display. Rather than forcing you to painstakingly building the URL yourself, Tapestry uses a more object-oriented approach: invoking listener methods. To use this function, you add a new method (say, showDetails()) to the Home Java class with the following signature:

public IPage showDetails(DestinationOffer destination)

Then you call this method using the DirectLink component and indicate where the method parameters should be with the parameters attribute:

<a href="#" jwcid="@DirectLink" listener="listener:showDetails" parameters="ognl:{ featureDestination }">Show Details</a>

Tapestry 4 is very flexible about listener methods. A listener method can be just an ordinary Java method, with or without parameters or a return type.

In this case, you want the method to go to the ShowDetails page. To do this, the method must return an instance of the IPage interface, which each Tapestry page implements. Using Java 5, you can use Tapestry 4 annotations to inject an appropriate getter method to reference the target page, as follows:

@InjectPage("ShowDetails") public abstract ShowDetails getShowDetailsPage(); public IPage showDetails(DestinationOffer destination) { ShowDetails showDetailsPage = getShowDetailsPage(); showDetailsPage.setOffer(destination); return showDetailsPage; }

In a nutshell, this method will initialize the ShowDetails Page with the selected offer and then transfer control to this page.

Working with Lists

Tapestry provides an impressive number of useful components out of the box. To illustrate these standard components, suppose you now want a page that lists all your feature destinations. Each feature destination should have a link to the Details page. To do this, you would use the Tapestry For component, as illustrated here:

<table cellspacing="6"> <tr> <td>Destination</td> <td>Price</td> <td></td> </tr> <tr> <td colspan="3"><hr/></td> </tr> <tr jwcid="@For" source="ognl:featureDestinationOffers" value="ognl:offer" element="tr"> <td><span jwcid="@Insert" value="ognl:offer.destination"/></td> <td>$<span jwcid="@Insert" value="ognl:offer.price"/></td> <td> <a href="#" jwcid="@DirectLink" listener="listener:showDetails" parameters="ognl:{ offer }">Show Details</a> </td> </tr> <tr jwcid="$remove$"> <td>Paris</td> <td>199</td> <td><a href="#">Show Details</a></td> </tr> <tr jwcid="$remove$"> <td>Rome</td> <td>299</td> </tr> </table>

The source attribute specifies the collection or list of objects to be iterated. The value attribute specifies a placeholder variable used to store the current object value for each iteration.

Astute readers will notice two lines at the end of the table containing dummy data and a strange looking $remove$ component. The remove component allows a Web designer to add HTML tags that can be used for previewing, but which will be discarded during page rendering. This is very useful for correctly formatting and previewing large tables.

The corresponding Java class has to provide getters and setters for the attributes used in the For component. You will also need a showDetails() method for the DirectLink component, similar to the one you used in the Home page. The following is the full class:

public abstract class FeatureDestinationList extends BasePage implements PageBeginRenderListener { public abstract List<DestinationOffer> getFeatureDestinationOffers(); public abstract void setFeatureDestinationOffers(List<DestinationOffer> offers); public abstract DestinationOffer getOffer(); public abstract void setOffer(DestinationOffer offer); public void pageBeginRender(PageEvent event) { setFeatureDestinationOffers(BusinessFactory .getFeatureDestinations() .getFeatureDestinationOffers()); } @InjectPage("ShowDetails") public abstract ShowDetails getShowDetailsPage(); public IPage showDetails(DestinationOffer destination) { ShowDetails showDetailsPage = getShowDetailsPage(); showDetailsPage.setOffer(destination); return showDetailsPage; } }

Figure 4 shows the final page.

Click to enlarge 
Figure 4. A List Page

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date