Event handlers and renderers

Files: 
/**
 * Example written for JavaOne 2016.
 * Differences between iText 5 and iText 7 are discussed in the JavaOne talk
 * "Oops, I broke my API" by Raf Hens and Bruno Lowagie.
 * This is the iText 5 version of one of the examples.
 */
package javaone.edition16;
 
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import sandbox.WrapToTest;
 
@WrapToTest
public class Text2PdfPageEvents {
 
    class MyPageEvents extends PdfPageEventHelper {
 
        protected float startpos = -1;
        protected boolean title = true;
 
        public void setTitle(boolean title) {
            this.title = title;
        }
 
        @Override
        public void onEndPage(PdfWriter writer, Document document) {
            Rectangle pagesize = document.getPageSize();
            ColumnText.showTextAligned(
                writer.getDirectContent(),
                Element.ALIGN_CENTER,
                new Phrase(String.valueOf(writer.getPageNumber())),
                (pagesize.getLeft() + pagesize.getRight()) / 2,
                pagesize.getBottom() + 15,
                0);
            if (startpos != -1)
                onParagraphEnd(writer, document, pagesize.getBottom(document.bottomMargin()));
            startpos = pagesize.getTop(document.topMargin());
        }
 
        @Override
        public void onParagraph(PdfWriter writer, Document document, float paragraphPosition) {
            startpos = paragraphPosition;
        }
 
        @Override
        public void onParagraphEnd(PdfWriter writer, Document document, float paragraphPosition) {
            if (!title) return;
            PdfContentByte canvas = writer.getDirectContentUnder();
            Rectangle pagesize = document.getPageSize();
            canvas.saveState();
            canvas.setColorStroke(BaseColor.BLUE);
            canvas.rectangle(
                pagesize.getLeft(document.leftMargin()),
                paragraphPosition - 3,
                pagesize.getWidth() - document.leftMargin() - document.rightMargin(),
                startpos - paragraphPosition);
            canvas.stroke();
            canvas.restoreState();
        }
 
 
    }
 
    public static final String TEXT
        = "resources/text/jekyll_hyde.txt";
    public static final String DEST
        = "results/javaone/edition16/text2pdf_page_events.pdf";
 
    public static void main(String[] args)
    	throws DocumentException, IOException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
    	new Text2PdfPageEvents().createPdf(DEST);
    }
 
    public void createPdf(String dest)
	throws DocumentException, IOException {
        Document document = new Document();
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
        MyPageEvents events = new MyPageEvents();
        writer.setPageEvent(events);
        document.open();
        BufferedReader br = new BufferedReader(new FileReader(TEXT));
        String line;
        Paragraph p;
        Font normal = new Font(FontFamily.TIMES_ROMAN, 12);
        Font bold = new Font(FontFamily.TIMES_ROMAN, 12, Font.BOLD);
        boolean title = true;
        while ((line = br.readLine()) != null) {
            p = new Paragraph(line, title ? bold : normal);
            p.setAlignment(Element.ALIGN_JUSTIFIED);
            events.setTitle(title);
            document.add(p);
            title = line.isEmpty();
        }
        document.close();
    }
}
/**
 * Example written for JavaOne 2016.
 * Differences between iText 5 and iText 7 are discussed in the JavaOne talk
 * "Oops, I broke my API" by Raf Hens and Bruno Lowagie.
 * This is the iText 7 version of one of the examples.
 */
package com.itextpdf.sandbox.javaone16;
 
import com.itextpdf.io.font.FontConstants;
import com.itextpdf.kernel.color.Color;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.border.Border;
import com.itextpdf.layout.border.SolidBorder;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.test.annotations.WrapToTest;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
 
@WrapToTest
public class Text2PdfPageEvents1 {
    public static final String TEXT
        = "src/main/resources/txt/jekyll_hyde.txt";
    public static final String DEST
        = "results/javaone16/text2pdf_page_events1.pdf";
 
    public static void main(String[] args) throws IOException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
    	new Text2PdfPageEvents1().createPdf(DEST);
    }
 
    public void createPdf(String dest) throws IOException {
        PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
        pdf.addEventHandler(PdfDocumentEvent.END_PAGE, new Footer());
        Document document = new Document(pdf)
            .setTextAlignment(TextAlignment.JUSTIFIED);
        BufferedReader br = new BufferedReader(new FileReader(TEXT));
        String line;
        PdfFont normal = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN);
        PdfFont bold = PdfFontFactory.createFont(FontConstants.TIMES_BOLD);
        boolean title = true;
        Border border = new SolidBorder(Color.BLUE, 1);
        while ((line = br.readLine()) != null) {
            document.add(new Paragraph(line)
                .setFont(title ? bold : normal)
                .setBorder(title ? border : Border.NO_BORDER));
            title = line.isEmpty();
        }
        document.close();
    }
 
    protected class Footer implements IEventHandler {
 
        @Override
        public void handleEvent(Event event) {
            PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
            PdfDocument pdf = docEvent.getDocument();
            PdfPage page = docEvent.getPage();
            Rectangle pageSize = page.getPageSize();
            PdfCanvas pdfCanvas = new PdfCanvas(
                page.getLastContentStream(), page.getResources(), pdf);
            Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
            float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
            float y = pageSize.getBottom() + 15;
            canvas.showTextAligned(
                String.valueOf(pdf.getPageNumber(page)),
                x, y, TextAlignment.CENTER);
        }
    }
}
/**
 * Example written for JavaOne 2016.
 * Differences between iText 5 and iText 7 are discussed in the JavaOne talk
 * "Oops, I broke my API" by Raf Hens and Bruno Lowagie.
 * This is the iText 7 version of one of the examples.
 */
package com.itextpdf.sandbox.javaone16;
 
import com.itextpdf.io.font.FontConstants;
import com.itextpdf.kernel.color.Color;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.border.Border;
import com.itextpdf.layout.border.SolidBorder;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.renderer.DrawContext;
import com.itextpdf.layout.renderer.IRenderer;
import com.itextpdf.layout.renderer.ParagraphRenderer;
import com.itextpdf.test.annotations.WrapToTest;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
 
@WrapToTest
public class Text2PdfPageEvents2 {
    public static final String TEXT
        = "src/main/resources/txt/jekyll_hyde.txt";
    public static final String DEST
        = "results/javaone16/text2pdf_page_events2.pdf";
 
    public static void main(String[] args) throws IOException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
    	new Text2PdfPageEvents2().createPdf(DEST);
    }
 
    public void createPdf(String dest) throws IOException {
        PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
        pdf.addEventHandler(PdfDocumentEvent.END_PAGE, new Footer());
        Document document = new Document(pdf)
            .setTextAlignment(TextAlignment.JUSTIFIED);
        BufferedReader br = new BufferedReader(new FileReader(TEXT));
        String line;
        PdfFont normal = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN);
        boolean title = true;
        Border border = new SolidBorder(Color.BLUE, 1);
        while ((line = br.readLine()) != null) {
            if (title)
                document.add(new TitleParagraph(line));
            else
                document.add(new Paragraph(line).setFont(normal));
            title = line.isEmpty();
        }
        document.close();
    }
 
    protected class Footer implements IEventHandler {
 
        @Override
        public void handleEvent(Event event) {
            PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
            PdfDocument pdf = docEvent.getDocument();
            PdfPage page = docEvent.getPage();
            Rectangle pageSize = page.getPageSize();
            PdfCanvas pdfCanvas = new PdfCanvas(
                page.getLastContentStream(), page.getResources(), pdf);
            Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
            float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
            float y = pageSize.getBottom() + 15;
            canvas.showTextAligned(
                String.valueOf(pdf.getPageNumber(page)),
                x, y, TextAlignment.CENTER);
        }
    }
 
    public class TitleParagraph extends Paragraph {
 
        public TitleParagraph(String line) {
            super(line);
            try {
                setFont(PdfFontFactory.createFont(FontConstants.TIMES_BOLD));
            }
            catch (IOException ioe) {
            }
        }
 
        @Override
        protected IRenderer makeNewRenderer() {
            return new ParagraphRenderer(this) {
                @Override
                public void drawBorder(DrawContext drawContext) {
                    Rectangle occupiedAreaBBox = getOccupiedAreaBBox();
                    float[] margins = getMargins();
                    Rectangle rectangle = applyMargins(occupiedAreaBBox, margins, false);
                    PdfCanvas canvas = drawContext.getCanvas();
                    canvas.roundRectangle(rectangle.getX() - 1, rectangle.getY() - 1,
                    rectangle.getWidth() + 2, rectangle.getHeight() + 2, 5).stroke();
                }
            };
        } 
    }
}
Resources: 
File nameRaw URLUpdated
jekyll_hyde.txtjekyll_hyde.txt2016-09-02 11:10 am
jekyll_hyde.txtjekyll_hyde.txt2016-09-02 11:18 am