HOME > SUPPORT > REPORTMILL LISTENER

ReportMill Listener

 

Overview

ReportMill provides support to generate almost any document dynamically by configuring the template in the design application. However, it's impossible to anticipate every need or provide a switch to solve every problem. To address this, ReportMill provides a simple listener mechanism to make almost anything possible with a very simple API. This is done by passing a ReportMill.Listener to a given generateReport() call. Here's an example of calling generateReport() with a listener to paint a specific text field red when the value is negative.

// Imports
import com.reportmill.base.*;
import com.reportmill.shape.*;


// Generate report with a ReportMill.Listener
RMDocument report = template.generateReport(myJavaDataset, new RMListener());

// Create a ReportMill.Listener to color the "RevenueText" red when negative
public static class RMListener implements ReportMill.Listener {

  public void didFillShape(ReportMill aReportMill, RMShape aShape, RMShape aCopy) {

    if(aShape.getName().equals("RevenueText")) &&
      ((RMTextShape)aCopy).getText().startsWith("-"))
        aCopy.setColor(RMColor.red);
  }
}

The only thing necessary to work with a report element in this way is to name it. You can name a report element by filling in the "Name:" text field in the "General Inspector " (betwee the placement inspector and the animation inspector). As you can see from the code, this is necessary anyway to uniquely identify an element. However, note that didFillShape() will not even be called for shapes that do not have a name (for the sake of efficiency).

Also, note that the didFillShape() method is called with two shapes. The first is the shape in the template. The second is the "generated" shape that will appear in the final report. And although our example just shows a text field, it can often be useful to use this mechanism for table rows, tables or anything.

Example 1 - Adding a table column divider line

This listener adds a vertical line to a table starting from below the header row and running all the way down through the last row of the table.

public static class RMListener implements ReportMill.Listener {

  public void didFillShape(ReportMill aReportMill, RMShape aShape, RMShape aCopy) {
    if(aShape.getName().equals("MyTable")) {
      float y1 = aCopy.getChild(1).getY();
      float y2 = aCopy.getChildLast().getBounds().maxY();
      RMLineSegment line = new RMLineSegment(180, y1, 180, y2);
      aCopy.addChild(line);
    }
  }

}

Example 2 - Gray bar completion for tables with alternate rows

public class RMListener implements ReportMill.Listener {

public void didFillShape(ReportMill aReportMill, RMShape aShape, RMShape aCopy) {

  if(aShape.getName().equals("WhateverTable")) {
    while(aCopy.getChildLast().getBounds().maxY()+20 < aCopy.getHeight()) {
      RMRectangle rect = new RMRectangle();
      rect.setBounds(0, aCopy.getChildLast().getBounds().maxY(), aCopy.getWidth(), 20);
      if(aCopy.getChildCount()%2==0)
        rect.setColor(RMColor.lightGray);
        aCopy.addChild(rect);
    }
  }
}

}