Contains the supporting classes for the {@link
com.arsdigita.bebop.Table} component. The Table
component
itself is part of the {@link com.arsdigita.bebop} package, but all its
parts are contained in this package.
The simplest way to construct a table is from static data contained in two arrays, one for the data and one for the header of the table:
String[] headers = { "Fruit", "Color" }; String[][] data = { { "banana", "yellow" }, { "orange", "orange" }, { "strawberry", "red" } }; Table table = new Table(data, headers);
This table
can now be added to a {@link
com.arsdigita.bebop.Page} and will produce output similar to this
table every time the page is rendered:
Fruit | Color |
---|---|
banana | yellow |
orange | orange |
strawberry | red |
Of course, the table component wouldn't be very useful if it could
only display static data in this manner. A table can also be used to
display data that is dynamically generated from database query. For
this, a {@link com.arsdigita.bebop.table.TableModelBuilder} needs to
be implemented. The TableModelBuilder
's
getModel
method is called by the table every time it
needs to render itself. For database-backed tables, the table model
builder will usually run a query and wrap the result of the query in
a TableModel
. The table then uses this table model as
the source for its data during rendering. It is very important to
note that the table does not cache the table model in any way - this
automatically ensures that the table always displays the latest data
available. If caching is needed for performance reasons, the table
model builder is responsible for implementing its own caching
strategy.
Another important feature of tables is that they make it easy to react with the user's interaction with the table data. By default, a table displays all its data by wrapping it in a {@link com.arsdigita.bebop.Label}, leading to the data being displayed as a string on the resulting HTML page. But many tables contain links in each row, as the following table shows (the links are non-functional):
Fruit | Color | Action |
---|---|---|
banana | yellow | ( peel ) |
orange | orange | ( peel ) |
strawberry | red | ( eat ) |
The code to set this table up from static data is not much more complicated than for the first table:
String[] headers = { "Fruit", "Color", "Action" }; String[][] data = { { "banana", "yellow", "peel" }, { "orange", "orange", "peel" }, { "strawberry", "red", "eat" } }; Table table = new Table(data, headers); table.getColumn(2).setCellRenderer(new DefaultTableCellRenderer(true));
All that has changed is that we added more entries to
headers
and data
and that we changed the
renderer for the last column (column number 2) of the table. We can
now add a {@link com.arsdigita.bebop.event.TableActionListener} to
the table and perform the necessary actions whenever the user clicks
on peel
or eat
:
table.addTableActionListener( new TableActionAdapter() { public void cellSelected(TableActionEvent e) { Object row = e.getRowKey(); if ( "2".equals(row) ) { System.out.println("User wants to eat a strawberry."); } else { System.out.print("User wants to peel"); if ( "0".equals(row) ) { System.out.println(" a banana."); } else { System.out.println(" a banana."); } } } });
A table consists of many parts. By default they are set to "reasonable" values that make the table behave in very simple ways. As the last example shows, small modifications to those defaults makes it possible to give a table more complex layout and/or behavior.
At a high level, a table consists of a header and some columns. Each {@link com.arsdigita.bebop.Table} maintains a list of its columns in a {@link com.arsdigita.bebop.table.TableColumnModel} and uses an implicit {@link com.arsdigita.bebop.table.TableHeader} object for rendering and receiving header-related events.
The columns are represented by a list of {@link
com.arsdigita.bebop.table.TableColumn}
objects. This list of columns is stored in the table's {@link
com.arsdigita.bebop.table.TableColumnModel}. Each
TableColumn
object stores
important display-related information about a table column, such as
the column header, the renderers for the column header and ordinary
cells in this column and from which column in the table model values
should be taken when rendering table cells.
FIXME: ... to be continued ...