Joined Version of the Advertising and Invoice Demo.

This demo combines the Invoice-Demo and the Advertising-Demo into a single report. For that we reuse the ideas from the 'MultiReport-Demo'.

The Joining TableModel

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

General Structure

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.

Groups

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.