📄 table.java
字号:
int rowCount = aLocation.x + 1 - rows.size();
int i = 0;
if ( rowCount > 0 ) { //create new rows ?
for (; i < rowCount; i++) {
rows.add(new Row(columns));
}
}
((Row) rows.get(aLocation.x)).setElement(aTable,aLocation.y);
setCurrentLocationToNextValidPosition(aLocation);
}
/**
* Gives you the posibility to add columns.
*
* @param aColumns the number of columns to add
*/
public void addColumns(int aColumns) {
ArrayList newRows = new ArrayList(rows.size());
int newColumns = columns + aColumns;
Row row;
for (int i = 0; i < rows.size(); i++) {
row = new Row(newColumns);
for (int j = 0; j < columns; j++) {
row.setElement(((Row) rows.get(i)).getCell(j) ,j);
}
for (int j = columns; j < newColumns && i < curPosition.x; j++) {
row.setElement(null, j);
}
newRows.add(row);
}
// applied 1 column-fix; last column needs to have a width of 0
float [] newWidths = new float[newColumns];
System.arraycopy(widths, 0, newWidths, 0, columns);
for (int j = columns; j < newColumns ; j++) {
newWidths[j] = 0;
}
columns = newColumns;
widths = newWidths;
rows = newRows;
}
/**
* Deletes a column in this table.
*
* @param column the number of the column that has to be deleted
* @throws BadElementException
*/
public void deleteColumn(int column) throws BadElementException {
float newWidths[] = new float[--columns];
System.arraycopy(widths, 0, newWidths, 0, column);
System.arraycopy(widths, column + 1, newWidths, column, columns - column);
setWidths(newWidths);
System.arraycopy(widths, 0, newWidths, 0, columns);
widths = newWidths;
Row row;
int size = rows.size();
for (int i = 0; i < size; i++) {
row = (Row) rows.get(i);
row.deleteColumn(column);
rows.set(i, row);
}
if (column == columns) {
curPosition.setLocation(curPosition.x+1, 0);
}
}
/**
* Deletes a row.
*
* @param row the number of the row to delete
* @return boolean <CODE>true</CODE> if the row was deleted; <CODE>false</CODE> if not
*/
public boolean deleteRow(int row) {
if (row < 0 || row >= rows.size()) {
return false;
}
rows.remove(row);
curPosition.setLocation(curPosition.x-1, curPosition.y);
return true;
}
/**
* Deletes all rows in this table.
* (contributed by dperezcar@fcc.es)
*/
public void deleteAllRows() {
rows.clear();
rows.add(new Row(columns));
curPosition.setLocation(0, 0);
lastHeaderRow = -1;
}
/**
* Deletes the last row in this table.
*
* @return boolean <CODE>true</CODE> if the row was deleted; <CODE>false</CODE> if not
*/
public boolean deleteLastRow() {
return deleteRow(rows.size() - 1);
}
/**
* Will fill empty cells with valid blank <CODE>Cell</CODE>s
*/
public void complete() {
if (mTableInserted) {
mergeInsertedTables(); // integrate tables in the table
mTableInserted = false;
}
if (autoFillEmptyCells) {
fillEmptyMatrixCells();
}
}
// private helper classes
/**
* returns the element at the position row, column
* (Cast to Cell or Table)
*
* @param row
* @param column
* @return dimension
*/
private Object getElement(int row, int column) {
return ((Row) rows.get(row)).getCell(column);
}
/**
* 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;
}
}
/**
* adds new<CODE>Cell</CODE>'s to empty/null spaces.
*/
private void fillEmptyMatrixCells() {
try {
for (int i=0; i < rows.size(); i++) {
for (int j=0; j < columns; j++) {
if (!((Row) rows.get(i)).isReserved(j)) {
addCell(defaultLayout, new Point(i, j));
}
}
}
}
catch(BadElementException bee) {
throw new ExceptionConverter(bee);
}
}
/**
* 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 targetted 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;
}
/**
* Sets the unset cell properties to be the table defaults.
*
* @param aCell The cell to set to table defaults as necessary.
*/
private void assumeTableDefaults(Cell aCell) {
if (aCell.getBorder() == Rectangle.UNDEFINED) {
aCell.setBorder(defaultLayout.getBorder());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -