BIRT report-layout event handlers

Each report-layout event handler provides access to a BIRT report element that is displayed in the report. We call this kind of element a report-layout element to distinguish it from an element that represents a data source or data set.

The distinguishing characteristics of the report-layout event handlers are as follows:
Consider the following event handler, which accepts a label element named remark_label and updates a BIRT report table that has a bound expression named account_balance.
function myLabelFunction( theLabel LabelInstance, theContext ReportContext ) 
   { eventType = onCreate, elementName = "remark_label" }
   balance float = theLabel.getRowData().getColumnValue("account_balance");
   if( balance > 0 )
      theLabel.text = "Balance Due";
      theLabel.getStyle().color = "red";
   end
end

The example does not use a report parameter, but uses the event-handler parameter theLabel to reference a bound expression named account_balance and to update the label remark_label. The names account_balance and remark_label are from the report-design file.

The content of a data element (such as account_balance) cannot be updated in a report-layout event handler; but as shown in the previous example, a label can be updated; and more generally, a report-layout event handler can set the style of one or more report-layout elements.

Each of the event-handler parameters (such as theLabel) is based on an EGL external type that represents a Java™ interface. The next table tells the type and purpose of each parameter in a report-layout event handler, along with the unqualified name of the related Java interface. The third column of the table indicates whether properties other than eventType and elementName may be specified.

EGL external type Purpose Properties (as described later) other than eventType and elementName Java interface
CellInstance To access a cell in a report grid or table When CellInstance is used for a grid, the available properties are columnNumber and rowNumber (both optional). When CellInstance is used for a table, the available properties are rowType (required); columnNumber and rowNumber (both optional); and groupName (required if the value of rowType is groupHeader or groupFooter) ICellInstance
DataInstance To access a field that contains data, whether from a data source or a computation   IDataItemInstance
DynamicTextInstance To access a field that contains character large object (CLOB) data such as the content of a memo   IDynamicTextInstance
GridInstance To access a field in a grid, which is a simple, table-like structure   IGridInstance
ImageInstance To access an image, which may be in a data set field, in a local file system, at a remote location, or embedded in the report-design file   IImageInstance
LabelInstance To access a label, which lacks HTML formatting and does not reflect a computed value   ILabelInstance
ListInstance To access a list   IListInstance
ReportContext To get or set report-parameter values   IReportContext
RowInstance To access a particular row in a report grid or table When RowInstance is used for a grid, the optional rowNumber property is available.When RowInstance is used for a table, the available properties are rowType (required), rowNumber (optional), and groupName (required if the value of rowType is groupHeader or groupFooter) IRowInstance
TableInstance To access a table   ITableInstance
TextInstance To access text, which may have HTML formatting or reflect a computed value   ITextItemInstance

The following table introduces four other external types used in report-layout event handlers.

EGL external type Purpose Java interface
ReportElementInstance To provide additional Java methods when you work with variables of any of the types listed in the previous table IReportElementInstance (a Java superclass)
ReportItemInstance To provide additional Java methods when you work with variables of any of the types (other than CellInstance and RowInstance) listed in the previous table IReportItemInstance (a Java superclass, subordinate to IReportElementInstance)
RowData To access the runtime values of a set of bound expressions; specifically, to accept the content returned by the ReportElementInstance function getRowData() IRowData
Style To access details on the styles in use; specifically, to accept the content returned by the ReportElementInstance function getStyle() IScriptStyle

For details on the external types and their capabilities, see "External types in a BIRT report-layout event handler."

You may never need to know the Java-specific details, but the Javadoc that describes each of the interfaces is in the BIRT Report Scripting API Reference, which is in your product help system under BIRT Programmer Reference > Reference > APIReference > BIRT Report Scripting API Reference. Each of the Java interfaces but two are in the package org.eclipse.birt.report.engine.api.script.instance. The exceptions (IRowData and IReportContext) are in org.eclipse.birt.report.engine.api.script.

Properties of event handlers

The next table describes the properties mentioned earlier.

Property Type Comment
columnNumber INT Identifies the column when you are processing a table (or grid) cell. This property is optional.
elementName STRING

For all layout-element types other than CellInstance and RowInstance, elementName is the name of the report element itself. For CellInstance and RowInstance, elementName is the name of the table or grid in which the cell or row resides. (The reason for the difference is that the BIRT designer does not let you name cells or rows.)

eventType EventTypeKind enumeration: beforeOpen, openEvent, and so forth As described in "EGL BIRT handler."
groupName STRING Identifies the group when the value of rowType is GroupHeader or GroupFooter, in which case the property is required.
rowNumber INT Identifies the row when you are processing a table (or grid) cell or row. This property is optional.
rowType RowTypeKind enumeration:
  • detail
  • header
  • footer
  • groupHeader
  • groupFooter
Specifies the type of row and is required for a table cell or row. This property is ignored if specified for a grid cell or row.
Here are additional details on the columnNumber and rowNumber properties, which are meaningful only for a row element or cell element:
  • Columns and rows are each numbered from 1 onward, not from 0.
  • For a grid row, the rowNumber property refers to a position within the grid. For a table row, the rowNumber property refers to a position within a given row type or within a given row type that has a specific group name. (Use of a group name is possible only if the row is of type groupHeader or groupFooter.) Here are examples:
    • If you specify row number 3 and the rowType property value is detail, the EGL runtime invokes the event handler whenever the third detail row is being created. Note that each detail row is itself a type of row and may occur multiple times in a given report. For example, if your database query retrieves a set of database rows that each include employee name, address, and title, you might define one report detail row for the name, one for the address, and one for the title. The event handler might boldface the third detail row, causing the following output:
      Sales:
      
         Mr. A
         100 Main Street, Someplace, NY
         Sales Manager
      
         Mr. B
         101 Main Street, Someplace, NY
         Sales Rep
      
      Marketing:
      
         Ms. X
         102 Main Street, Someplace, NY
         Marketing Manager
    • If you specify row number 2, rowType property groupHeader, and groupName element "Division", the invocation occurs during the creation of the second groupHeader row whenever the groupName is "Division". You might boldface the second row in this case also, causing the following output:
      Division A
      contains 2 departments:
      
         Sales
         Marketing
      
      Division B
      contains 3 departments:
      
         Sales
         Marketing
         Operations		
  • For an event handler that accepts an element of type RowInstance, the following rules apply:
    • If you specify rowNumber, the EGL runtime invokes the event handler when the specified row is being created, as suggested in the preceding examples.
    • If you do not specify rowNumber, the invocation occurs either when any row of the specified type is being created or, if the RowType value is groupHeader or groupFooter, when any row of the specified type (groupHeader or groupFooter) is being created for the specified group.
  • For an event handler that accepts an element of type CellInstance, the following rules apply:
    • If you specify both columnNumber and rowNumber, the EGL runtime invokes the event handler when the specified cell in the specified row is being created
    • If you specify rowNumber but not columnNumber, the invocation occurs when any cell in the specified row is being created.
    • If you specify columnNumber but not rowNumber, the invocation occurs when any cell in the specified column is being created. If you specify column number 2 when the rowType property value is detail, for example, the invocation occurs when the second column in any detail row is being created. Similarly, if you specify column number 2, rowType property groupHeader, and groupName element "Division," the invocation occurs during the creation of the second column in each groupHeader row for which the groupName is "Division".
    • If you specify neither columnNumber nor rowNumber, the invocation occurs either when any cell is being created for a specified type of row or, if the RowType value is groupHeader or groupFooter, when any cell in the specified row type (groupHeader or groupFooter) is being created for the specified group

The effect of order among event handlers for onCreate

When the value of the eventType property is onCreate, the order of report-layout event handlers is meaningful, with a later one taking precedence over earlier ones whenever multiple event handlers could apply to the creation of a given report-layout element. Consider the following functions, as listed:
function myEventHandler01( r RowInstance, theContext ReportContext )
{eventType = onCreate, elementName = "myReportTable", rowType = detail}
  r.getStyle().color = "red";
end

function myEventHandler02( r RowInstance, theContext ReportContext )
{eventType = onCreate, elementName = "myReportTable", rowType = detail, rowNumber = 2}
  r.getStyle().color = "green";
end
If the table myReportTable has 3 details rows, the effect at run time is as follows:
  • myEventHandler01 is invoked during the creation of row 1, which is made red
  • myEventHandler02 is invoked during the creation of row 2, which is made green
  • myEventHandler01 is invoked during the creation of row 3, which is made red

During the creation of row 2, either function could apply, but myEventHandler02 takes precedence and myEventHandler01 is not invoked for that row.

Consider the same functions in reverse order:
function myEventHandler02( r RowInstance, theContext ReportContext )
{eventType = onCreate, elementName = "myReportTable", rowType = detail, rowNumber = 2}
  r.getStyle().color = "green";
end

function myEventHandler01( r RowInstance, theContext ReportContext )
{eventType = onCreate, elementName = "myReportTable", rowType = detail}
  r.getStyle().color = "red";
end

During the creation of each row, myEventHandler01 takes precedence and myEventHandler02 is not invoked. Every row is made red.