|
Page 2 of 6
Finally, inside <t:parameter>, you can see an expansion displaying the name of the
current celebrity and surrounding it with the PageLink component that has for its
context the ID of the current celebrity.
Run the application, and you should see that we have achieved what we wanted:

Click on the last name of a celebrity, and you should see the Details page with the
appropriate details on it.
All that is left now is to remove the unwanted Id column and to change the order of
the remaining columns. For this, we'll use two properties of the Grid—remove and
reorder. Modify the component's de finition in the page template to look like this:
<t:grid t:source="celebritySource" rowsPerPage="5"
row="celebrity"
remove="id"
reorder="lastName,firstName,occupation,dateOfBirth">
<t:parameter name="lastNameCell">
<t:pagelink t:page="details" t:context="celebrity.id">
${celebrity.lastName}
</t:pagelink>
</t:parameter>
</t:grid>
Please note that re-ordering doesn't delete columns. If you omit some
columns while specifying their order, they will simply end up last
in the table.
Now, if you run the application, you should see that the table with a collection of
celebrities is displayed exactly as we wanted:

Changing the Column Titles
Column titles are currently generated by Tapestry automatically. What if we
want to have different titles? Say we want to have the title, Birth Date, instead of
Date Of Birth.
The easiest and the most ef ficient way to do this is to use the message catalog, the
same one that we used while working with the Select component in the previous
chapter. Add the following line to the app.properties file:
dateOfBirth-label=Birth Date
Run the application, and you will see that the column title has changed
appropriately. This way, appending -label to the name of the property displayed
by the column, you can create the key for a message catalog entry, and thus change
the title of any column.
Right now, we are using the root message catalog, which is common for
all the pages of the application. Later, in Chapter 7, you will see how to
create a message catalog for every page.
Now you should be able to adjust the Grid component to most of the possible
requirements and to display with its help many different kinds of objects. However,
one scenario can still raise a problem.
Add an output statement to the getAllCelebrities method in the ShowAll page
class, like this:
public List<Celebrity> getAllCelebrities()
{
System.out.println("Getting all celebrities...");
return dataSource.getAllCelebrities();
}
The purpose of this is simply to be aware when the method is called. Run the
application, log in, and as soon as the table with celebrities is shown, you will see the
output, as : Getting all celebrities...
The Grid component has the allCelebrities property de fined as its source, so
it invokes the getAllCelebrities method to obtain the content to display. Note
however that Grid, after invoking this method, receives a list containing all 15
celebrities in collection, but displays only the first five.
Click on the pager to view the second page—the same output will appear again.
Grid requested for the whole collection again, and this time displayed only the
second portion of five celebrities from it. Whenever we view another page, the whole
collection is requested from the data source, but only one page of data is displayed.
This is not too ef ficient but works for our purpose.
Imagine, however, that our collection contains as many as 10,000 celebrities, and it's
stored in a remote database. Requesting for the whole collection would put a lot of
strain on our resources, especially if we are going to have 2,000 pages.
We need to have the ability to request the celebrities, page-by-page—only the first
five for the first page, only the second five for the second page and so on. This ability
is supported by Tapestry. All we need to do is to provide an implementation of the
GridDataSource interface.
Here is a somewhat simpli fied example of such an implementation.
Using GridDataSource
First of all, let's modify the IDataSource interface, adding to it a method for
returning a selected range of celebrities:
public interface IDataSource
{
List<Celebrity> getAllCelebrities();
Celebrity getCelebrityById(long id);
void addCelebrity(Celebrity c);
List<Celebrity> getRange(int indexFrom, int indexTo);
}
Next, we need to implement this method in the available implementation of this
interface. Add the following method to the MockDataSource class:
public List<Celebrity> getRange(int indexFrom, int indexTo)
{
List<Celebrity> result = new ArrayList<Celebrity>();
for (int i = indexFrom; i <= indexTo; i++)
{
result.add(celebrities.get(i));
}
return result;
}
Page 2 Of 6 -
Advanced Components from the book "Tapestry 5 - Building Web Applications"
|