This demo introduces the JoiningTableModel and shows how to use this class to print reports with multiple table models.
We use the JoiningTableModel to join both tablemodels. That tablemodel behaves like a primitive version of an SQL-Union operation.
The Joining Tablemodel combines two independent Tables into one large tablemodel. The resulting tablemodel contains all columns of the both models and an additional column called 'TablePrefix'. The column namess of the original table models are preceeded by the value stored in the TablePrefix column.
Assume we have the following table models:
TableModel modelA = new DefaultTableModel();
Contents:
T1C1 | T1C2 |
---|---|
A | B |
C | D |
TableModel modelB = new DefaultTableModel();
Contents:
T2C1 | T2C2 |
---|---|
1 | 2 |
3 | 4 |
We join the tablemodels with the following code:
JoinedTableModel joinedTable = new JoinedTableModel(); joinedTable.add ("t_1", modelA); joinedTable.add ("t_2", modelB);
The resulting tablemodel contents will be:
TablePrefix | t_1.T1C1 | t_1.T1C2 | t_2.T2C1 | t_2.T2C2 |
---|---|---|---|---|
t_1 | A | B | - | - |
t_1 | C | D | - | - |
t_2 | - | - | 1 | 2 |
t_2 | - | - | 3 | 4 |
When printing the report we have to alter the visibility of those bands, which should not be printed for the current row type.
For that task, we add a function, that preforms that task for
us. To make things easier for the function and to increase
maintainability of the report definition, we put all elements
for a certain row type into separate bands. The
HideElementByNameFunction
we use to alter the
bands visiblities expects the name of the band, that should be changed by
the function, to match the contents of the "TablePrefix" column.
We added one function for every record type. The record types used are 'fruit' for the fruit table data and 'color' for the color table.
<function class="org.jfree.report.function.HideElementByNameFunction" name="hideColors"> <properties> <property name="element">color</property> <property name="field">TablePrefix</property> </properties> </function> <function class="org.jfree.report.function.HideElementByNameFunction" name="hideFruits"> <properties> <property name="element">fruit</property> <property name="field">TablePrefix</property> </properties> </function>
When comparing the combined report agains the single reports, you will notice that all table column references have the name of the table (as specified in the JoinedTableModel.add(..) method) added as prefix to the column name.
To separate the two reports, we introduce a group level that separates the reports by it's "TablePrefix" column.
That top-level group only has an empty Group-header which is used to force a pagebreak between the two reports.
Within the invoice and advertising reports, all group field definitions have been extended to contain the "TablePrefix" column as group column.
To get a defined order of the reports, the joined version of the advertising report needs to add all fields from the deepest group of the invoice report. Technically, the advertising report is now a child report of the invoice report. As the HideElementByNameFunction hides the invoice report contents whenever 'Advertising' contents are printed, that dependency is hidden and has no visual representation to the user.
Although the report definition is split into separate files, this is no requirement to generate this kind of reports. The separate files are used only for the purpose to mirror the logically separation on a physical level.