Why is my cell event not triggered?

Tags: tablescell eventiText 5

Please take a look at my code. I am expecting the cell event to be triggered for two cells, but it only triggers on the first cell. The difference appears to be that the cell event of the first cell is added to the cell before adding the cell to the table.

Document doc = new Document(PageSize.A4);
float twocm = Utilities.millimetersToPoints(20f);
doc.setMargins(twocm, twocm, twocm, twocm);
PdfWriter.getInstance(doc, new FileOutputStream(new File("test.pdf")));
try {
    doc.open();
    PdfPTable table = new PdfPTable(2);
    table.setTotalWidth(doc.right() - doc.left());
    table.setLockedWidth(true);
    table.setWidths( new int[] { 50, 50 } );
    PdfPCell leftCell = new PdfPCell();
    leftCell.addElement(new Paragraph("I am the left"));
    //Event added to cell before adding cell to table, it works.
    leftCell.setCellEvent(new MyCellEvent());    
    PdfPCell rightCell = new PdfPCell();
    rightCell.addElement(new Paragraph( "I am the right"));
    table.addCell(leftCell);
    table.addCell(rightCell);
    //Event added to cell after adding cell to table, doesn't work.
    rightCell.setCellEvent(new MyCellEvent());
    doc.add(table);
}
finally {
    doc.close();
}
static final class MyCellEvent implements PdfPCellEvent {
    @Override
    public void cellLayout(
        PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
        System.out.println("Cell event was called");
    }
}
The reason why this matters is that I need to do some measurements of the table (and other things) and pass values into the constructor of the cell renderer. I can't take the table measurements until after I've added the cell to the table; which is why I need to set the cell renderer after the cell has been added to the table.

Posted on StackOverflow on Apr 2, 2014 by Richard

The cell parameter of the addCell() method is final and changing cell after it has been added to the PdfPTable has no effect, because the object is being copied using the PdfPCell copy constructor of either the PdfPHeaderCell class or the PdfPCell class. We work on a copy because as soon as a cell is added to a table, we perform different operations on that cell. Should we do these operations on the original cell, then that cell can't be reused (and that is what some people do: they create a cell once and then reuse it).

There may be a workaround for your problem though. You could retrieve the copied cell from the row:

PdfPRow row = table.getRow(0);
PdfPCell cell = row.getCells()[1];

And then add the cell event to that cell instance. It's not elegant, but it might work.

Thanks Bruno, good explanation. And the work-around does work. cheers for that.