fc.extensions.itext.smart.SmartTable.java Source code

Java tutorial

Introduction

Here is the source code for fc.extensions.itext.smart.SmartTable.java

Source

/**
 * $Id$ [$Rev$]
 * $Author$
 * $Date$
 * $URL$
 *
 * Copyright (c) 2009 by Andersen (F.C. Huang).
 *
 * The contents of this file is available under the MIT License.
 *
 * 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 fc.extensions.itext.smart;

import com.itextpdf.text.DocumentException;
import fc.extensions.itext.Writer;
import com.itextpdf.text.pdf.PdfPTable;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.beanutils.locale.LocaleBeanUtils;

/**
 * A PdfPTable wrapper supports more functions.
 * 
 * @author Administrator
 */
public final class SmartTable {

    private boolean created = false, flushed = false;
    private float borderWidth = 0f;
    private int columns = 0;
    private int rows = 0;
    private PdfPTable table = null;
    private Writer writer = null;
    private int[] columnWidthsScale = null;

    private int cellCounter = 0;
    private Position position = null;
    private Position replicatorPosition = null;
    private int rowFixedHeight = 14;
    private int cellFontSize = 9;
    private boolean autoFlush = true;

    public SmartTable(Writer client, Position position, int columns, int rows, int cellFontSize, float borderWidth)
            throws Exception {
        this(client, position, columns, rows, cellFontSize, borderWidth, null);
    }

    public SmartTable(Writer client, Position position, int columns, int rows, int cellFontSize, float borderWidth,
            int[] columnWidthsScale) throws Exception {
        this.writer = client;
        this.position = position;
        this.columns = columns;
        this.rows = rows;
        this.borderWidth = borderWidth;
        this.cellFontSize = cellFontSize;

        if (columnWidthsScale != null) {
            if (columnWidthsScale.length != this.columns) {
                throw new Exception("the number of widths is different than the number of columns");
            }
            this.columnWidthsScale = columnWidthsScale;
        }
    }

    public SmartTable(SmartTable tableObject) throws Exception {
        LocaleBeanUtils.copyProperties(this, tableObject);
        this.position = new Position(tableObject.getPosition());
    }

    public boolean isAutoFlush() {
        return autoFlush;
    }

    public void setAutoFlush(boolean autoFlush) {
        this.autoFlush = autoFlush;
    }

    public Writer getWriter() {
        return writer;
    }

    public void setWriter(Writer Writer) {
        this.writer = Writer;
    }

    public int getDefaultFontSize() {
        return cellFontSize;
    }

    public void setDefaultFontSize(int defaultFontSize) {
        this.cellFontSize = defaultFontSize;
    }

    public int getRowFixedHeight() {
        return rowFixedHeight;
    }

    public void setRowFixedHeight(int rowFixedHeight) {
        this.rowFixedHeight = rowFixedHeight;
    }

    public void setReplicatorPosition(Position position) {
        this.replicatorPosition = position;
    }

    public boolean isCreated() {
        return created;
    }

    public void setCreated(boolean created) {
        this.created = created;
    }

    public boolean isFlushed() {
        return flushed;
    }

    public void setFlushed(boolean flushed) {
        this.flushed = flushed;
    }

    public Position getPosition() {
        return position;
    }

    public void setPosition(Position position) {
        this.position = position;
    }

    public float getBorderWidth() {
        return borderWidth;
    }

    public void setBorderWidth(float borderWidth) {
        this.borderWidth = borderWidth;
    }

    public int getColumns() {
        return columns;
    }

    public void setColumns(int columns) {
        this.columns = columns;
    }

    public int getRows() {
        return rows;
    }

    public void setRows(int rows) {
        this.rows = rows;
    }

    public int[] getColumnWidthsScale() {
        return columnWidthsScale;
    }

    public void setColumnWidthsScale(int[] columnWidthsScale) {
        this.columnWidthsScale = columnWidthsScale;
    }

    private void create() {
        if (!created) {
            if (columnWidthsScale == null || columnWidthsScale.length == 0) {
                columnWidthsScale = new int[columns];
                Arrays.fill(columnWidthsScale, 1);
            }
            try {
                table = this.writer.createTable(columns, position.getWidth(), columnWidthsScale);
            } catch (DocumentException ex) {
                Logger.getLogger(SmartTable.class.getName()).log(Level.SEVERE, null, ex);
            }
            table.getDefaultCell().setBorderWidth(borderWidth);
            table.getDefaultCell().setFixedHeight(rowFixedHeight);
            table.getDefaultCell().setPadding(0.2F);
            created = true;
        }
    }

    private void checkFlush() {
        if (autoFlush) {
            if (cellCounter > columns * rows) {
                Logger.getLogger(SmartTable.class.getName()).log(Level.SEVERE,
                        "this case shouldn't be happened. cellCounter: " + cellCounter + ",columns: " + columns
                                + ",rows:" + rows,
                        new TableFlushedException());
                return;
            }
            if (!flushed && cellCounter == columns * rows) {
                flush();
            }
        }
    }

    private boolean isFull() {
        if (autoFlush) {
            if (flushed) {
                return true;
            }
            if (cellCounter > columns * rows) {
                flush();
                return true;
            }
        }
        return false;
    }

    private void checkCreate() {
        if (!created) {
            create();
        }
    }

    /**
     * add an empty cell
     *
     * @throws TableWasFullException
     */
    public void addEmptyCell() throws TableWasFullException {
        checkCreate();
        this.writer.addEmptyCell(table, borderWidth);
        cellCounter++;
        checkFlush();
    }

    /**
     * add a cell with DBCS content, use table's borderwidth, fontsize and etc,.
     * 
     * @param content
     * @throws TableWasFullException
     */
    public void addCell(String content) throws TableWasFullException {
        checkCreate();
        if (isFull()) {
            throw new TableWasFullException();
        } else {
            cellCounter++;
            this.writer.addCell(table, content, cellFontSize, borderWidth, 1);
            checkFlush();
        }
    }

    /**
     * add a cell with ANSI char content, use table's borderwidth, fontsize and etc,.
     *
     * @param content
     * @throws TableWasFullException
     */
    public void addAnsiCell(String content) throws TableWasFullException {
        checkCreate();
        if (isFull()) {
            throw new TableWasFullException();
        } else {
            cellCounter++;
            this.writer.addAnsiCell(table, content, cellFontSize, borderWidth, 1);
            checkFlush();
        }
    }

    /**
     * add a cell by Cell object, use it's attributes.
     *
     * @param cell
     * @throws TableWasFullException
     */
    public void addCell(Cell cell) throws TableWasFullException {
        checkCreate();
        cellCounter += cell.getColspan();
        if (isFull()) {
            throw new TableWasFullException();
        } else {
            this.writer.addCell(table, cell);
            checkFlush();
        }
    }

    /**
     * add a cell, wrap the content into next row.
     *
     * @param content
     * @param maxCellWidth
     * @throws TableWasFullException
     */
    public void addCrossRowCell(String content, float maxCellWidth) throws TableWasFullException {
        Cell cell = new Cell(content);
        cell.setColspan(1);
        cell.setMaxWidth(maxCellWidth);
        checkCreate();
        float stringWidth = writer.getStringWidth(cell.getContent(), cell.getFontSize());
        if (stringWidth > cell.getMaxWidth()) {
            cellCounter += (1 + (int) (stringWidth / cell.getMaxWidth()) * this.columns);
        } else {
            cellCounter++;
        }
        if (isFull()) {
            throw new TableWasFullException();
        } else {
            this.writer.addCell(table, cell);
            checkFlush();
        }
    }

    /**
     * render this table.
     */
    public void flush() {
        if (!flushed) {
            float bottom = this.writer.flushTable(table, position.getLeft(), position.getTop());
            position.setTop(bottom);
            if (replicatorPosition != null) {
                replicatorPosition.setTop(Math.min(replicatorPosition.getTop(), position.getTop()));
            }
            flushed = true;
        }
    }

}