fr.opensagres.xdocreport.itext.extension.ExtendedPdfPTable.java Source code

Java tutorial

Introduction

Here is the source code for fr.opensagres.xdocreport.itext.extension.ExtendedPdfPTable.java

Source

/**
 * Copyright (C) 2011-2015 The XDocReport Team <xdocreport@googlegroups.com>
 *
 * All rights reserved.
 *
 * Permission is hereby granted, free  of charge, to any person obtaining
 * a  copy  of this  software  and  associated  documentation files  (the
 * "Software"), to  deal in  the Software without  restriction, including
 * without limitation  the rights to  use, copy, modify,  merge, publish,
 * distribute,  sublicense, and/or sell  copies of  the Software,  and to
 * permit persons to whom the Software  is furnished to do so, subject to
 * the following conditions:
 *
 * The  above  copyright  notice  and  this permission  notice  shall  be
 * included in all copies or substantial portions of the Software.
 *
 * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
 * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
 * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package fr.opensagres.xdocreport.itext.extension;

import com.lowagie.text.Element;
import com.lowagie.text.Image;
import com.lowagie.text.Phrase;
import com.lowagie.text.Table;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPRow;
import com.lowagie.text.pdf.PdfPTable;

public class ExtendedPdfPTable extends PdfPTable implements IITextContainer {
    private IITextContainer container;

    private boolean empty;

    private PdfPCell wrapperCell;

    private PdfPTable wrapperTable;

    public ExtendedPdfPTable(int numColumns) {
        super(numColumns);
        super.setSpacingBefore(0f);
        this.empty = true;
        super.setLockedWidth(true);
        super.setHorizontalAlignment(Element.ALIGN_LEFT);
    }

    public void addElement(Element element) {
        if (element instanceof PdfPCell) {
            addCell((PdfPCell) element);
        }
    }

    public IITextContainer getITextContainer() {
        return container;
    }

    public void setITextContainer(IITextContainer container) {
        this.container = container;
    }

    public float getRowHeight(int idx) {
        return getRowHeight(idx, false);
    }

    /**
     * Gets the height of a particular row.
     *
     * @param idx the row index (starts at 0)
     * @param firsttime is this the first time the row heigh is calculated?
     * @return the height of a particular row
     * @since 3.0.0
     */
    public float getRowHeight(int idx, boolean firsttime) {
        if (totalWidth <= 0 || idx < 0 || idx >= rows.size())
            return 0;
        PdfPRow row = (PdfPRow) rows.get(idx);
        if (row == null)
            return 0;
        if (firsttime)
            row.setWidths(absoluteWidths);
        float height = row.getMaxHeights();
        PdfPCell cell;
        PdfPRow tmprow;
        for (int i = 0; i < relativeWidths.length; i++) {
            if (!rowSpanAbove(idx, i))
                continue;
            int rs = 1;
            while (rowSpanAbove(idx - rs, i)) {
                rs++;
            }
            tmprow = (PdfPRow) rows.get(idx - rs);
            cell = tmprow.getCells()[i];
            float tmp = 0;
            // AZERR patch : sometimes cell is null????
            // LP : cell may be null if colspan/rowspan occurs
            // create a dummy cell to avoid NullPointerException
            if (cell == null) {
                cell = new PdfPCell();
                tmprow.getCells()[i] = cell;
            }
            if (cell.getRowspan() == rs + 1) {
                tmp = cell.getMaxHeight();
                while (rs > 0) {
                    tmp -= getRowHeight(idx - rs);
                    rs--;
                }
            }
            if (tmp > height)
                height = tmp;
        }
        row.setMaxHeights(height);
        return height;
    }

    /**
     * Checks if there are rows above belonging to a rowspan.
     *
     * @param currRow the current row to check
     * @param currCol the current column to check
     * @return true if there's a cell above that belongs to a rowspan
     * @since 2.1.6
     */
    @SuppressWarnings("all")
    boolean rowSpanAbove(int currRow, int currCol) {
        if ((currCol >= getNumberOfColumns()) || (currCol < 0) || (currRow == 0))
            return false;

        int row = currRow - 1;
        PdfPRow aboveRow = (PdfPRow) rows.get(row);
        if (aboveRow == null)
            return false;
        PdfPCell aboveCell = (PdfPCell) aboveRow.getCells()[currCol];
        while ((aboveCell == null) && (row > 0)) {
            aboveRow = (PdfPRow) rows.get(--row);
            if (aboveRow == null)
                return false;
            aboveCell = (PdfPCell) aboveRow.getCells()[currCol];
        }

        int distance = currRow - row;

        if (aboveCell == null) {
            int col = currCol - 1;
            aboveCell = (PdfPCell) aboveRow.getCells()[col];
            while ((aboveCell == null) && (row > 0))
                aboveCell = (PdfPCell) aboveRow.getCells()[--col];
            return aboveCell != null && aboveCell.getRowspan() > distance;
        }

        if ((aboveCell.getRowspan() == 1) && (distance > 1)) {
            int col = currCol - 1;
            aboveRow = (PdfPRow) rows.get(row + 1);
            distance--;
            aboveCell = (PdfPCell) aboveRow.getCells()[col];
            while ((aboveCell == null) && (col > 0))
                aboveCell = (PdfPCell) aboveRow.getCells()[--col];
        }

        return aboveCell != null && aboveCell.getRowspan() > distance;
    }

    @Override
    public void addCell(Image image) {
        this.empty = false;
        super.addCell(image);
    }

    @Override
    public void addCell(PdfPCell cell) {
        this.empty = false;
        super.addCell(cell);
    }

    @Override
    public void addCell(PdfPTable table) {
        this.empty = false;
        super.addCell(table);
    }

    @Override
    public void addCell(Phrase phrase) {
        this.empty = false;
        super.addCell(phrase);
    }

    @Override
    public void addCell(String text) {
        this.empty = false;
        super.addCell(text);
    }

    public boolean isEmpty() {
        return empty;
    }

    /**
     * Sets the padding of the contents in the cell (space between content and border).
     *
     * @param padding
     */
    public void setPadding(float padding) {
        getWrapperCell().setPadding(padding);
    }

    /**
     * Setter for property paddingLeft.
     *
     * @param paddingLeft New value of property paddingLeft.
     */
    public void setPaddingLeft(float paddingLeft) {
        getWrapperCell().setPaddingLeft(paddingLeft);
    }

    /**
     * Setter for property paddingRight.
     *
     * @param paddingRight New value of property paddingRight.
     */
    public void setPaddingRight(float paddingRight) {
        getWrapperCell().setPaddingRight(paddingRight);
    }

    /**
     * Setter for property paddingBottom.
     *
     * @param paddingBottom New value of property paddingBottom.
     */
    public void setPaddingBottom(float paddingBottom) {
        getWrapperCell().setPaddingBottom(paddingBottom);
    }

    /**
     * Setter for property paddingTop.
     *
     * @param paddingTop New value of property paddingTop.
     */
    public void setPaddingTop(float paddingTop) {
        getWrapperCell().setPaddingTop(paddingTop);
    }

    private PdfPCell createCell() {
        PdfPCell cell = new PdfPCell();
        cell.setBorder(Table.NO_BORDER);
        cell.setPadding(0.0f);
        cell.setUseBorderPadding(true);
        return cell;
    }

    private PdfPTable createTable(PdfPCell cell) {
        PdfPTable table = new PdfPTable(1);
        table.setSpacingBefore(this.spacingBefore());
        table.setSpacingAfter(this.spacingAfter());
        table.setHorizontalAlignment(this.getHorizontalAlignment());
        table.setTotalWidth(cell.getPaddingLeft() + this.getTotalWidth() + cell.getPaddingRight());
        table.setLockedWidth(true);
        table.setSplitLate(false);
        table.addCell(cell);
        return table;
    }

    private PdfPCell getWrapperCell() {
        if (wrapperCell == null) {
            wrapperCell = createCell();
        }
        return wrapperCell;
    }

    public Element getElement() {
        if (wrapperTable != null) {
            return wrapperTable;
        } else if (wrapperCell != null) {
            wrapperCell.addElement(this);
            wrapperTable = createTable(wrapperCell);
            return wrapperTable;
        }
        return this;
    }
}