How to add a border to a paragraph?
Posted on StackOverflow on May 5, 2015 by Amit Das
Please take a look at the BorderForParagraph example. It shows how to add a border for a paragraph like this:
A paragraph with a border
There is no method that allows you to create a border for a Paragraph
, but you can create a PdfPageEvent
implementation that allows you to draw a rectangle based on the start and end position of the Paragraph
:
class ParagraphBorder extends PdfPageEventHelper {
public boolean active = false;
public void setActive(boolean active) {
this.active = active;
}
public float offset = 5;
public float startPosition;
@Override
public void onParagraph(
PdfWriter writer, Document document, float paragraphPosition) {
this.startPosition = paragraphPosition;
}
@Override
public void onParagraphEnd(
PdfWriter writer, Document document, float paragraphPosition) {
if (active) {
PdfContentByte cb = writer.getDirectContentUnder();
cb.rectangle(document.left(), paragraphPosition - offset,
document.right() - document.left(),
startPosition - paragraphPosition);
cb.stroke();
}
}
}
As you can see, I introduced a boolean
parameter named active
. By default, I've set this parameter to false
. I also create an offset
(change this value to fine-tune the result) and a startPosition
parameter.
Each time iText starts rendering a Paragraph
object, the startPosition
value is updated. Each time iText ends rendering a Paragraph
, a rectangle is drawn if active
is true
(otherwise nothing happens).
We use this event like this:
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter writer =
PdfWriter.getInstance(document, new FileOutputStream(dest));
ParagraphBorder border = new ParagraphBorder();
writer.setPageEvent(border);
document.open();
document.add(new Paragraph("Hello,"));
document.add(new Paragraph("In this document, we'll add several paragraphs that will trigger page events. As long as the event isn't activated, nothing special happens, but let's make the event active and see what happens:"));
border.setActive(true);
document.add(new Paragraph("This paragraph now has a border. Isn't that fantastic? By changing the event, we can even provide a background color, change the line width of the border and many other things. Now let's deactivate the event."));
border.setActive(false);
document.add(new Paragraph("This paragraph no longer has a border."));
document.close();
}
As you can see, we declare the event to the PdfWriter
using the setPageEvent()
method. We activate the event like this:
border.setActive(true);
and we deactivate it like this:
border.setActive(false);
This is only a proof of concept! You will need to implement the onStartPage()
and onEndPage()
method if you want this to work for paragraphs that span more than one page. That's shown in BorderForParagraph2:
A paragraph distributed over 2 pages
The onStartPage()
and onEndPage()
implementation is a no-brainer:
class ParagraphBorder extends PdfPageEventHelper {
public boolean active = false;
public void setActive(boolean active) {
this.active = active;
}
public float offset = 5;
public float startPosition;
@Override
public void onStartPage(PdfWriter writer, Document document) {
startPosition = document.top();
}
@Override
public void onParagraph(PdfWriter writer, Document document,
float paragraphPosition) {
this.startPosition = paragraphPosition;
}
@Override
public void onEndPage(PdfWriter writer, Document document) {
if (active) {
PdfContentByte cb = writer.getDirectContentUnder();
cb.rectangle(document.left(), document.bottom() - offset,
document.right() - document.left(),
startPosition - document.bottom());
cb.stroke();
}
}
@Override
public void onParagraphEnd(PdfWriter writer, Document document,
float paragraphPosition) {
if (active) {
PdfContentByte cb = writer.getDirectContentUnder();
cb.rectangle(document.left(), paragraphPosition - offset,
document.right() - document.left(),
startPosition - paragraphPosition);
cb.stroke();
}
}
}