/**
* ===========================================
* LibLayout : a free Java layouting library
* ===========================================
*
* Project Info: http://reporting.pentaho.org/liblayout/
*
* (C) Copyright 2006-2007, by Pentaho Corporation and Contributors.
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------
* $Id: SeparateRowModel.java 6653 2008-12-02 14:53:40Z tmorgner $
* ------------
* (C) Copyright 2006-2007, by Pentaho Corporation.
*/
package org.jfree.layouting.renderer.model.table.rows;
import org.jfree.layouting.renderer.model.table.TableRenderBox;
import org.jfree.layouting.renderer.model.table.TableSectionRenderBox;
/**
* Creation-Date: 22.07.2006, 15:23:00
*
* @author Thomas Morgner
*/
public class SeparateRowModel extends AbstractRowModel
{
private long preferredSize;
private boolean validatedSize;
private long rowSpacing;
public SeparateRowModel(final TableSectionRenderBox tableSection)
{
super(tableSection);
}
public long getPreferredSize()
{
validateSizes();
return preferredSize;
}
public long getRowSpacing()
{
return rowSpacing;
}
public void validateSizes()
{
if (validatedSize)
{
return;
}
int maxRowSpan = 0;
final TableRow[] rows = getRows();
final int rowCount = rows.length;
for (int i = 0; i < rowCount; i++)
{
final TableRow row = rows[i];
final int cs = row.getMaximumRowSpan();
if (cs > maxRowSpan)
{
maxRowSpan = cs;
}
}
final TableRenderBox table = getTableSection().getTable();
rowSpacing = table.getRowSpacing().resolve(0);
preferredSize = (rowCount - 1) * rowSpacing;
// first, find out how much space is already used.
final long[] preferredSizes = new long[rowCount];
// For each rowspan ...
for (int rowspan = 1; rowspan <= maxRowSpan; rowspan += 1)
{
for (int rowIdx = 0; rowIdx < rowCount; rowIdx++)
{
final TableRow row = rows[rowIdx];
final long preferredSize = row.getPreferredSize(rowspan);
distribute(preferredSize, preferredSizes, rowIdx, rowspan);
}
}
for (int i = 0; i < rowCount; i++)
{
preferredSize += preferredSizes[i];
final TableRow row = rows[i];
row.setPreferredSize(preferredSizes[i]);
}
validatedSize = true;
}
public void validateActualSizes()
{
validateSizes();
int maxRowSpan = 0;
final TableRow[] rows = getRows();
final int rowCount = rows.length;
for (int i = 0; i < rowCount; i++)
{
final TableRow row = rows[i];
final int cs = row.getMaxValidatedRowSpan();
if (cs > maxRowSpan)
{
maxRowSpan = cs;
}
}
// first, find out how much space is already used.
// This follows the classical model.
final long[] trailingSizes = new long[rowCount];
// For each rowspan ...
for (int rowspan = 1; rowspan <= maxRowSpan; rowspan += 1)
{
for (int rowIdx = 0; rowIdx < trailingSizes.length; rowIdx++)
{
final TableRow row = rows[rowIdx];
final long size = row.getValidatedTrailingSize(rowspan);
distribute(size, trailingSizes, rowIdx, rowspan);
}
}
for (int i = 0; i < trailingSizes.length; i++)
{
final TableRow row = rows[i];
final long validateSize = trailingSizes[i] + row.getValidatedLeadingSize();
row.setValidateSize(Math.max (row.getPreferredSize(), validateSize));
}
}
private void distribute (final long usedSpace, final long[] allSpaces,
final int colIdx, final int colspanX)
{
final int maxColspan = Math.min (colIdx + colspanX, allSpaces.length) - colIdx;
long usedPrev = 0;
final int maxSize = Math.min(allSpaces.length, colIdx + maxColspan);
for (int i = colIdx; i < maxSize; i++)
{
usedPrev += allSpaces[i];
}
if (usedSpace <= usedPrev)
{
// no need to expand the cells.
return;
}
final long distSpace = (usedSpace - usedPrev);
final long delta = distSpace / maxColspan;
for (int i = 0; i < maxColspan - 1; i++)
{
allSpaces[colIdx + i] = delta;
}
// any uneven remainder gets added to the last column
allSpaces[colIdx + maxColspan - 1] = distSpace - ((maxColspan - 1) * delta);
}
public void clear()
{
final TableRow[] rows = getRows();
final int rowCount = rows.length;
for (int i = 0; i < rowCount; i++)
{
final TableRow row = rows[i];
row.clear();
}
}
}