This demo combines the Invoice-Demo and the Advertising-Demo into a single report. For that we reuse the ideas from the 'MultiReport-Demo'.
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 an own band. The
HideElementByNameFunction
we use to alter the
bands visiblities expects the name of the band to match the
contents of the "TablePrefix" column. If the name defined
in the function parameter 'element' matches the column value
found in the 'field', all elements with that name will be
triggered visible. If the value does not match, the named
elements will be invisible. All other elements in the band
will not be affected by the function.
We added one function for every record type. The record types used are 'invoice' for the invoice data and 'ad' for the advertising attached to the invoice.
<function class="org.jfree.report.function.HideElementByNameFunction" name="hideInvoice"> <properties> <property name="element">invoice</property> <property name="field">TablePrefix</property> </properties> </function> <function class="org.jfree.report.function.HideElementByNameFunction" name="hideInvoice"> <properties> <property name="element">ad</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.