/** * check if <CODE>Cell</CODE> 'fits' the table. * * <p> * * <UL> * <LI>rowspan/colspan not beyond borders * <LI>spanned cell don't overlap existing cells * </UL> * * @param aCell the cell that has to be checked * @param aLocation the location where the cell has to be placed * @return true if the location was valid */ private boolean isValidLocation(Cell aCell, Point aLocation) { // rowspan not beyond last column if (aLocation.x < rows .size()) // if false : new location is already at new, not-yet-created area so no check { if ((aLocation.y + aCell.getColspan()) > columns) { return false; } int difx = ((rows.size() - aLocation.x) > aCell.getRowspan()) ? aCell.getRowspan() : rows.size() - aLocation.x; int dify = ((columns - aLocation.y) > aCell.getColspan()) ? aCell.getColspan() : columns - aLocation.y; // no other content at cells targeted by rowspan/colspan for (int i = aLocation.x; i < (aLocation.x + difx); i++) { for (int j = aLocation.y; j < (aLocation.y + dify); j++) { if (((Row) rows.get(i)).isReserved(j)) { return false; } } } } else { if ((aLocation.y + aCell.getColspan()) > columns) { return false; } } return true; }
/** * Adds a <CODE>Cell</CODE> to the <CODE>Table</CODE> at a certain location. * * @param aCell The <CODE>Cell</CODE> to add * @param aLocation The location where the <CODE>Cell</CODE> will be added * @throws BadElementException */ public void addCell(Cell aCell, Point aLocation) throws BadElementException { if (aCell == null) throw new NullPointerException( MessageLocalization.getComposedMessage("addcell.cell.has.null.value")); if (aLocation == null) throw new NullPointerException( MessageLocalization.getComposedMessage("addcell.point.has.null.value")); if (aCell.isTable()) insertTable((Table) aCell.getElements().next(), aLocation); if (aLocation.x < 0) throw new BadElementException( MessageLocalization.getComposedMessage("row.coordinate.of.location.must.be.gt.eq.0")); if ((aLocation.y <= 0) && (aLocation.y > columns)) throw new BadElementException( MessageLocalization.getComposedMessage( "column.coordinate.of.location.must.be.gt.eq.0.and.lt.nr.of.columns")); if (!isValidLocation(aCell, aLocation)) throw new BadElementException( MessageLocalization.getComposedMessage( "adding.a.cell.at.the.location.1.2.with.a.colspan.of.3.and.a.rowspan.of.4.is.illegal.beyond.boundaries.overlapping", String.valueOf(aLocation.x), String.valueOf(aLocation.y), String.valueOf(aCell.getColspan()), String.valueOf(aCell.getRowspan()))); if (aCell.getBorder() == UNDEFINED) aCell.setBorder(defaultCell.getBorder()); aCell.fill(); placeCell(rows, aCell, aLocation); setCurrentLocationToNextValidPosition(aLocation); }
/** * Adds a <CODE>Cell</CODE> to the <CODE>Table</CODE>. * * <p>This is a shortcut for <CODE>addCell(Cell cell, Point location)</CODE>. The <CODE>Phrase * </CODE> will be converted to a <CODE>Cell</CODE>. * * @param content a <CODE>Phrase</CODE> * @param location a <CODE>Point</CODE> * @throws BadElementException this should never happen */ public void addCell(Phrase content, Point location) throws BadElementException { Cell cell = new Cell(content); cell.setBorder(defaultCell.getBorder()); cell.setBorderWidth(defaultCell.getBorderWidth()); cell.setBorderColor(defaultCell.getBorderColor()); cell.setBackgroundColor(defaultCell.getBackgroundColor()); cell.setHorizontalAlignment(defaultCell.getHorizontalAlignment()); cell.setVerticalAlignment(defaultCell.getVerticalAlignment()); cell.setColspan(defaultCell.getColspan()); cell.setRowspan(defaultCell.getRowspan()); addCell(cell, location); }
/** * Inserts a Cell in a cell-array and reserves cells defined by row-/colspan. * * @param someRows some rows * @param aCell the cell that has to be inserted * @param aPosition the position where the cell has to be placed */ private void placeCell(ArrayList someRows, Cell aCell, Point aPosition) { int i; Row row = null; int rowCount = aPosition.x + aCell.getRowspan() - someRows.size(); assumeTableDefaults(aCell); if ((aPosition.x + aCell.getRowspan()) > someRows.size()) { for (i = 0; i < rowCount; i++) { row = new Row(columns); someRows.add(row); } } // reserve cell in rows below for (i = aPosition.x + 1; i < (aPosition.x + aCell.getRowspan()); i++) { if (!((Row) someRows.get(i)).reserve(aPosition.y, aCell.getColspan())) { // should be impossible to come here :-) throw new RuntimeException( MessageLocalization.getComposedMessage("addcell.error.in.reserve")); } } row = (Row) someRows.get(aPosition.x); row.addElement(aCell, aPosition.y); }
/** Integrates all added tables and recalculates column widths. */ private void mergeInsertedTables() { int i = 0, j = 0; float[] lNewWidths = null; int[] lDummyWidths = new int[columns]; // to keep track in how many new cols this one will be split float[][] lDummyColumnWidths = new float[columns][]; // bugfix Tony Copping int[] lDummyHeights = new int[rows.size()]; // to keep track in how many new rows this one will be split ArrayList newRows = null; boolean isTable = false; int lTotalRows = 0, lTotalColumns = 0; int lNewMaxRows = 0, lNewMaxColumns = 0; Table lDummyTable = null; // first we'll add new columns when needed // check one column at a time, find maximum needed nr of cols // Search internal tables and find one with max columns for (j = 0; j < columns; j++) { lNewMaxColumns = 1; // value to hold in how many columns the current one will be split float[] tmpWidths = null; for (i = 0; i < rows.size(); i++) { if (Table.class.isInstance(((Row) rows.get(i)).getCell(j))) { isTable = true; lDummyTable = ((Table) ((Row) rows.get(i)).getCell(j)); if (tmpWidths == null) { tmpWidths = lDummyTable.widths; lNewMaxColumns = tmpWidths.length; } else { int cols = lDummyTable.getDimension().width; float[] tmpWidthsN = new float[cols * tmpWidths.length]; float tpW = 0, btW = 0, totW = 0; int tpI = 0, btI = 0, totI = 0; tpW += tmpWidths[0]; btW += lDummyTable.widths[0]; while (tpI < tmpWidths.length && btI < cols) { if (btW > tpW) { tmpWidthsN[totI] = tpW - totW; tpI++; if (tpI < tmpWidths.length) { tpW += tmpWidths[tpI]; } } else { tmpWidthsN[totI] = btW - totW; btI++; if (Math.abs(btW - tpW) < 0.0001) { tpI++; if (tpI < tmpWidths.length) { tpW += tmpWidths[tpI]; } } if (btI < cols) { btW += lDummyTable.widths[btI]; } } totW += tmpWidthsN[totI]; totI++; } /*if( tpI<tmpWidths.length) { System.arraycopy(tmpWidths, tpI, tmpWidthsN, totI, tmpWidths.length-tpI); totI +=tmpWidths.length-tpI; } else if(btI<cols) { System.arraycopy(lDummyTable.widths, btI, tmpWidthsN, totI, lDummyTable.widths.length-btI); totI +=lDummyTable.widths.length-btI; }*/ tmpWidths = new float[totI]; System.arraycopy(tmpWidthsN, 0, tmpWidths, 0, totI); lNewMaxColumns = totI; } /*if ( lDummyTable.getDimension().width > lNewMaxColumns ) { lNewMaxColumns = lDummyTable.getDimension().width; lDummyColumnWidths[j] = lDummyTable.widths; // bugfix Tony Copping }*/ } } lDummyColumnWidths[j] = tmpWidths; lTotalColumns += lNewMaxColumns; lDummyWidths[j] = lNewMaxColumns; } // next we'll add new rows when needed for (i = 0; i < rows.size(); i++) { lNewMaxRows = 1; // holds value in how many rows the current one will be split for (j = 0; j < columns; j++) { if (Table.class.isInstance(((Row) rows.get(i)).getCell(j))) { isTable = true; lDummyTable = (Table) ((Row) rows.get(i)).getCell(j); if (lDummyTable.getDimension().height > lNewMaxRows) { lNewMaxRows = lDummyTable.getDimension().height; } } } lTotalRows += lNewMaxRows; lDummyHeights[i] = lNewMaxRows; } if ((lTotalColumns != columns) || (lTotalRows != rows.size()) || isTable) // NO ADJUSTMENT { // ** WIDTH // set correct width for new columns // divide width over new nr of columns // Take new max columns of internal table and work out widths for each col lNewWidths = new float[lTotalColumns]; int lDummy = 0; for (int tel = 0; tel < widths.length; tel++) { if (lDummyWidths[tel] != 1) { // divide for (int tel2 = 0; tel2 < lDummyWidths[tel]; tel2++) { // lNewWidths[lDummy] = widths[tel] / lDummyWidths[tel]; lNewWidths[lDummy] = widths[tel] * lDummyColumnWidths[tel][tel2] / 100f; // bugfix Tony Copping lDummy++; } } else { lNewWidths[lDummy] = widths[tel]; lDummy++; } } // ** FILL OUR NEW TABLE // generate new table // set new widths // copy old values newRows = new ArrayList(lTotalRows); for (i = 0; i < lTotalRows; i++) { newRows.add(new Row(lTotalColumns)); } int lDummyRow = 0, lDummyColumn = 0; // to remember where we are in the new, larger table Object lDummyElement = null; for (i = 0; i < rows.size(); i++) { lDummyColumn = 0; lNewMaxRows = 1; for (j = 0; j < columns; j++) { if (Table.class.isInstance( ((Row) rows.get(i)).getCell(j))) // copy values from embedded table { lDummyTable = (Table) ((Row) rows.get(i)).getCell(j); // Work out where columns in table table correspond to columns in current table int colMap[] = new int[lDummyTable.widths.length + 1]; int cb = 0, ct = 0; for (; cb < lDummyTable.widths.length; cb++) { colMap[cb] = lDummyColumn + ct; float wb; wb = lDummyTable.widths[cb]; float wt = 0; while (ct < lDummyWidths[j]) { wt += lDummyColumnWidths[j][ct++]; if (Math.abs(wb - wt) < 0.0001) break; } } colMap[cb] = lDummyColumn + ct; // need to change this to work out how many cols to span for (int k = 0; k < lDummyTable.getDimension().height; k++) { for (int l = 0; l < lDummyTable.getDimension().width; l++) { lDummyElement = lDummyTable.getElement(k, l); if (lDummyElement != null) { int col = lDummyColumn + l; if (Cell.class.isInstance(lDummyElement)) { Cell lDummyC = (Cell) lDummyElement; // Find col to add cell in and set col span col = colMap[l]; int ot = colMap[l + lDummyC.getColspan()]; lDummyC.setColspan(ot - col); } ((Row) newRows.get(k + lDummyRow)) .addElement( lDummyElement, col); // use addElement to set reserved status ok in row } } } } else // copy others values { Object aElement = getElement(i, j); if (Cell.class.isInstance(aElement)) { // adjust spans for cell ((Cell) aElement) .setRowspan( ((Cell) ((Row) rows.get(i)).getCell(j)).getRowspan() + lDummyHeights[i] - 1); ((Cell) aElement) .setColspan( ((Cell) ((Row) rows.get(i)).getCell(j)).getColspan() + lDummyWidths[j] - 1); // most likely this cell covers a larger area because of the row/cols splits : define // not-to-be-filled cells placeCell(newRows, ((Cell) aElement), new Point(lDummyRow, lDummyColumn)); } } lDummyColumn += lDummyWidths[j]; } lDummyRow += lDummyHeights[i]; } // Set our new matrix columns = lTotalColumns; rows = newRows; this.widths = lNewWidths; } }