Why is my cell event not triggered?

Tags: tablesiText 7

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

In iText 7 we create Cells like this:

Table table = new Table(2);
 
Cell leftCell = new Cell().add("I am left");
leftCell.setNextRenderer(new MyCellRenderer(leftCell));
table.addCell(leftCell);
 
Cell rightCell = new Cell().add("I am right");
table.addCell(rightCell);
rightCell.setNextRenderer(new MyCellRenderer(rightCell));
 
doc.add(table);

Where MyCellRenderer is the extension of the CellRenderer class:

protected class MyCellRenderer extends CellRenderer {
    public MyCellRenderer(Cell modelElement) {
        super(modelElement);
    }
    @Override
    public void draw(DrawContext drawContext) {
        System.out.println("Cell event was called");
    }
}

As you see there are no events anymore. We override CellRenderer’s methods to set the desired behavior of creating/drawing the cell. If you use setNextRenderer() method after adding a cell to the table, it would be triggered as well.

Click this link if you want to see how to answer this question in iText 5.