Subversion Repository Public Repository

litesoft

Diff Revisions 282 vs 475 for /trunk/Java/GWT/Client/src/com/google/gwt/gen2/table/client/FixedWidthFlexTable.java

Diff revisions: vs.
  @@ -15,706 +15,801 @@
15 15 */
16 16 package com.google.gwt.gen2.table.client;
17 17
18 - import com.google.gwt.gen2.table.client.FixedWidthTableImpl.IdealColumnWidthInfo;
19 - import com.google.gwt.user.client.DOM;
20 - import com.google.gwt.user.client.Element;
21 - import com.google.gwt.user.client.ui.Widget;
22 -
23 - import java.util.ArrayList;
24 - import java.util.HashMap;
25 - import java.util.List;
26 - import java.util.Map;
18 + import java.util.*;
19 +
20 + import com.google.gwt.gen2.table.client.FixedWidthTableImpl.*;
21 + import com.google.gwt.user.client.*;
22 + import com.google.gwt.user.client.ui.*;
27 23
28 24 /**
29 25 * A variation of the {@link FlexTable} that supports smarter column resizing
30 26 * options. Unlike the {@link FlexTable}, columns resized in the
31 27 * {@link FixedWidthFlexTable} class are guaranteed to be resized correctly.
32 28 */
33 - public class FixedWidthFlexTable extends FlexTable {
34 - /**
35 - * FlexTable-specific implementation of
36 - * {@link com.google.gwt.user.client.ui.HTMLTable.CellFormatter}.
37 - */
38 - public class FixedWidthFlexCellFormatter extends FlexCellFormatter {
39 - /**
40 - * Sets the column span for the given cell. This is the number of logical
41 - * columns covered by the cell.
42 - *
43 - * @param row the cell's row
44 - * @param column the cell's column
45 - * @param colSpan the cell's column span
46 - * @throws IndexOutOfBoundsException
29 + public class FixedWidthFlexTable extends FlexTable
30 + {
31 + /**
32 + * FlexTable-specific implementation of
33 + * {@link com.google.gwt.user.client.ui.HTMLTable.CellFormatter}.
34 + */
35 + public class FixedWidthFlexCellFormatter extends FlexCellFormatter
36 + {
37 + /**
38 + * Sets the column span for the given cell. This is the number of logical
39 + * columns covered by the cell.
40 + *
41 + * @param row the cell's row
42 + * @param column the cell's column
43 + * @param colSpan the cell's column span
44 + *
45 + * @throws IndexOutOfBoundsException
46 + */
47 + @Override
48 + public void setColSpan( int row, int column, int colSpan )
49 + {
50 + colSpan = Math.max( 1, colSpan );
51 + int colSpanDelta = colSpan - getColSpan( row, column );
52 + super.setColSpan( row, column, colSpan );
53 +
54 + // Update the column counts
55 + int rowSpan = getRowSpan( row, column );
56 + for ( int i = row; i < row + rowSpan; i++ )
57 + {
58 + setNumColumnsPerRow( i, getNumColumnsPerRow( i ) + colSpanDelta );
59 + }
60 + }
61 +
62 + /**
63 + * Sets the row span for the given cell. This is the number of logical rows
64 + * covered by the cell.
65 + *
66 + * @param row the cell's row
67 + * @param column the cell's column
68 + * @param rowSpan the cell's row span
69 + *
70 + * @throws IndexOutOfBoundsException
71 + */
72 + @Override
73 + public void setRowSpan( int row, int column, int rowSpan )
74 + {
75 + rowSpan = Math.max( 1, rowSpan );
76 + int curRowSpan = getRowSpan( row, column );
77 + super.setRowSpan( row, column, rowSpan );
78 +
79 + // Update the column counts
80 + int colSpan = getColSpan( row, column );
81 + if ( rowSpan > curRowSpan )
82 + {
83 + for ( int i = row + curRowSpan; i < row + rowSpan; i++ )
84 + {
85 + setNumColumnsPerRow( i, getNumColumnsPerRow( i ) + colSpan );
86 + }
87 + }
88 + else if ( rowSpan < curRowSpan )
89 + {
90 + for ( int i = row + rowSpan; i < row + curRowSpan; i++ )
91 + {
92 + setNumColumnsPerRow( i, getNumColumnsPerRow( i ) - colSpan );
93 + }
94 + }
95 + }
96 +
97 + /**
98 + * UnsupportedOperation. Use ExtendedGrid.setColumnWidth(column, width)
99 + * instead.
100 + *
101 + * @param row the row of the cell whose width is to be set
102 + * @param column the cell whose width is to be set
103 + * @param width the cell's new width, in CSS units
104 + *
105 + * @throws UnsupportedOperationException
106 + */
107 + @Override
108 + public void setWidth( int row, int column, String width )
109 + {
110 + throw new UnsupportedOperationException( "setWidth is not supported. " + "Use ExtendedGrid.setColumnWidth(int, int) instead." );
111 + }
112 +
113 + /**
114 + * Gets the TD element representing the specified cell unsafely (meaning
115 + * that it doesn't ensure that the row and column are valid).
116 + *
117 + * @param row the row of the cell to be retrieved
118 + * @param column the column of the cell to be retrieved
119 + *
120 + * @return the column's TD element
121 + */
122 + @Override
123 + protected Element getRawElement( int row, int column )
124 + {
125 + return super.getRawElement( row + 1, column );
126 + }
127 + }
128 +
129 + /**
130 + * This class contains methods used to format a table's columns. It is limited
131 + * by the support cross-browser HTML support for column formatting.
132 + */
133 + public class FixedWidthFlexColumnFormatter extends ColumnFormatter
134 + {
135 + /**
136 + * UnsupportedOperation. Use ExtendedGrid.setColumnWidth(column, width)
137 + * instead.
138 + *
139 + * @param column the column of the cell whose width is to be set
140 + * @param width the cell's new width, in percentage or pixel units
141 + *
142 + * @throws UnsupportedOperationException
143 + */
144 + @Override
145 + public void setWidth( int column, String width )
146 + {
147 + throw new UnsupportedOperationException( "setWidth is not supported. " + "Use ExtendedGrid.setColumnWidth(int, int) instead." );
148 + }
149 + }
150 +
151 + /**
152 + * This class contains methods used to format a table's rows.
153 + */
154 + public class FixedWidthFlexRowFormatter extends RowFormatter
155 + {
156 + /**
157 + * Unsafe method to get a row element.
158 + *
159 + * @param row the row to get
160 + *
161 + * @return the row element
162 + */
163 + @Override
164 + protected Element getRawElement( int row )
165 + {
166 + return super.getRawElement( row + 1 );
167 + }
168 + }
169 +
170 + /**
171 + * The default width of a column in pixels.
172 + */
173 + public static final int DEFAULT_COLUMN_WIDTH = 80;
174 +
175 + /**
176 + * A mapping of column indexes to their widths in pixels.
177 + * <p/>
178 + * key = column index
179 + * <p/>
180 + * value = column width in pixels
181 + */
182 + private Map<Integer, Integer> colWidths = new HashMap<Integer, Integer>();
183 +
184 + /**
185 + * A mapping of rows to the number of raw columns (not cells) that they
186 + * contain.
187 + * <p/>
188 + * key = the row index
189 + * <p/>
190 + * value = the number of raw columns in the row
191 + */
192 + private List<Integer> columnsPerRow = new ArrayList<Integer>();
193 +
194 + /**
195 + * A mapping of raw columns counts to the number of rows with that column
196 + * count. For example, if three rows contain a raw column count of five, one
197 + * of the entries will be (5, 3);
198 + * <p/>
199 + * key = number of raw columns
200 + * <p/>
201 + * value = number of rows with that many raw columns
202 + */
203 + private Map<Integer, Integer> columnCountMap = new HashMap<Integer, Integer>();
204 +
205 + /**
206 + * The maximum number of raw columns in any single row.
207 + */
208 + private int maxRawColumnCount = 0;
209 +
210 + /**
211 + * The hidden, zero row used for sizing the columns.
212 + */
213 + private Element ghostRow;
214 +
215 + /**
216 + * The ideal widths of all columns (that are available).
217 + */
218 + private int[] idealWidths;
219 +
220 + /**
221 + * Info used to calculate ideal column width.
222 + */
223 + private IdealColumnWidthInfo idealColumnWidthInfo;
224 +
225 + /**
226 + * Constructor.
227 + */
228 + public FixedWidthFlexTable()
229 + {
230 + super();
231 + Element tableElem = getElement();
232 + DOM.setStyleAttribute( tableElem, "tableLayout", "fixed" );
233 + DOM.setStyleAttribute( tableElem, "width", "0px" );
234 +
235 + setCellFormatter( new FixedWidthFlexCellFormatter() );
236 + setColumnFormatter( new FixedWidthFlexColumnFormatter() );
237 + setRowFormatter( new FixedWidthFlexRowFormatter() );
238 +
239 + // Create the zero row for sizing
240 + ghostRow = FixedWidthTableImpl.get().createGhostRow();
241 + DOM.insertChild( getBodyElement(), ghostRow, 0 );
242 + }
243 +
244 + @Override
245 + public void clear()
246 + {
247 + super.clear();
248 + clearIdealWidths();
249 + }
250 +
251 + /**
252 + * @return the raw number of columns in this table.
253 + */
254 + public int getColumnCount()
255 + {
256 + return maxRawColumnCount;
257 + }
258 +
259 + /**
260 + * Return the column width for a given column index. If a width has not been
261 + * assigned, the default width is returned.
262 + *
263 + * @param column the column index
264 + *
265 + * @return the column width in pixels
266 + */
267 + public int getColumnWidth( int column )
268 + {
269 + Object colWidth = colWidths.get( new Integer( column ) );
270 + if ( colWidth == null )
271 + {
272 + return DEFAULT_COLUMN_WIDTH;
273 + }
274 + else
275 + {
276 + return ((Integer) colWidth).intValue();
277 + }
278 + }
279 +
280 + /**
281 + * <p>
282 + * Calculate the ideal width required to tightly wrap the specified column. If
283 + * the ideal column width cannot be calculated (eg. if the table is not
284 + * attached), -1 is returned.
285 + * </p>
286 + * <p>
287 + * Note that this method requires an expensive operation whenever the content
288 + * of the table is changed, so you should only call it after you've completely
289 + * modified the contents of your table.
290 + * </p>
291 + *
292 + * @return the ideal column width, or -1 if it is not applicable
293 + */
294 + public int getIdealColumnWidth( int column )
295 + {
296 + maybeRecalculateIdealColumnWidths();
297 + if ( idealWidths.length > column )
298 + {
299 + return idealWidths[column];
300 + }
301 + return -1;
302 + }
303 +
304 + /**
305 + * @see FlexTable
47 306 */
48 307 @Override
49 - public void setColSpan(int row, int column, int colSpan) {
50 - colSpan = Math.max(1, colSpan);
51 - int colSpanDelta = colSpan - getColSpan(row, column);
52 - super.setColSpan(row, column, colSpan);
53 -
54 - // Update the column counts
55 - int rowSpan = getRowSpan(row, column);
56 - for (int i = row; i < row + rowSpan; i++) {
57 - setNumColumnsPerRow(i, getNumColumnsPerRow(i) + colSpanDelta);
58 - }
308 + public Element insertCell( int beforeRow, int beforeColumn )
309 + {
310 + clearIdealWidths();
311 + Element td = super.insertCell( beforeRow, beforeColumn );
312 + DOM.setStyleAttribute( td, "overflow", "hidden" );
313 + setNumColumnsPerRow( beforeRow, getNumColumnsPerRow( beforeRow ) + 1 );
314 + return td;
315 + }
316 +
317 + /**
318 + * @see FlexTable
319 + */
320 + @Override
321 + public int insertRow( int beforeRow )
322 + {
323 + // Get the affected colSpan, which is the number of raw cells created by
324 + // row spanning cells in rows above the new row.
325 + FlexCellFormatter formatter = getFlexCellFormatter();
326 + int affectedColSpan = getNumColumnsPerRow( beforeRow );
327 + if ( beforeRow != getRowCount() )
328 + {
329 + int numCellsInRow = getCellCount( beforeRow );
330 + for ( int cell = 0; cell < numCellsInRow; cell++ )
331 + {
332 + affectedColSpan -= formatter.getColSpan( beforeRow, cell );
333 + }
334 + }
335 +
336 + // Specifically allow the row count as an insert position.
337 + if ( beforeRow != getRowCount() )
338 + {
339 + checkRowBounds( beforeRow );
340 + }
341 + Element tr = DOM.createTR();
342 + DOM.insertChild( getBodyElement(), tr, beforeRow + 1 );
343 + columnsPerRow.add( beforeRow, new Integer( 0 ) );
344 +
345 + // Make sure the column counts are still correct by iterating backward
346 + // through the rows looking for cells that span down into the newly
347 + // inserted row. Stop iterating when every raw column is accounted for.
348 + for ( int curRow = beforeRow - 1; curRow >= 0; curRow-- )
349 + {
350 + // No more affect of rowspan, so we are done
351 + if ( affectedColSpan <= 0 )
352 + {
353 + break;
354 + }
355 +
356 + // Look for cells that span into the new row
357 + int numCells = getCellCount( curRow );
358 + for ( int curCell = 0; curCell < numCells; curCell++ )
359 + {
360 + int affectedRow = curRow + formatter.getRowSpan( curRow, curCell );
361 + if ( affectedRow > beforeRow )
362 + {
363 + int colSpan = formatter.getColSpan( curRow, curCell );
364 + affectedColSpan -= colSpan;
365 + setNumColumnsPerRow( beforeRow, getNumColumnsPerRow( beforeRow ) + colSpan );
366 + setNumColumnsPerRow( affectedRow, getNumColumnsPerRow( affectedRow ) - colSpan );
367 + }
368 + }
369 + }
370 +
371 + // Return the new row index
372 + return beforeRow;
373 + }
374 +
375 + @Override
376 + public boolean remove( Widget widget )
377 + {
378 + if ( super.remove( widget ) )
379 + {
380 + clearIdealWidths();
381 + return true;
382 + }
383 + return false;
384 + }
385 +
386 + /**
387 + * @see FlexTable
388 + */
389 + @Override
390 + public void removeCell( int row, int column )
391 + {
392 + clearIdealWidths();
393 + int colSpan = getFlexCellFormatter().getColSpan( row, column );
394 + int rowSpan = getFlexCellFormatter().getRowSpan( row, column );
395 + super.removeCell( row, column );
396 +
397 + // Update the column counts
398 + for ( int i = row; i < row + rowSpan; i++ )
399 + {
400 + setNumColumnsPerRow( i, getNumColumnsPerRow( i ) - colSpan );
401 + }
402 + }
403 +
404 + /**
405 + * @see FlexTable
406 + */
407 + @Override
408 + public void removeRow( int row )
409 + {
410 + // Set the rowspan of everything in this row to 1
411 + FlexCellFormatter formatter = getFlexCellFormatter();
412 + int affectedColSpan = getNumColumnsPerRow( row );
413 + int numCellsInRow = getCellCount( row );
414 + for ( int cell = 0; cell < numCellsInRow; cell++ )
415 + {
416 + formatter.setRowSpan( row, cell, 1 );
417 + affectedColSpan -= formatter.getColSpan( row, cell );
418 + }
419 +
420 + // Actually remove the row
421 + super.removeRow( row );
422 + clearIdealWidths();
423 + setNumColumnsPerRow( row, -1 );
424 + columnsPerRow.remove( row );
425 +
426 + // Make sure the column counts are still correct by iterating backward
427 + // through the rows looking for cells that span down into the newly
428 + // inserted row. Stop iterating when every raw column is accounted for.
429 + for ( int curRow = row - 1; curRow >= 0; curRow-- )
430 + {
431 + // No more affects from rowspan, so we are done
432 + if ( affectedColSpan <= 0 )
433 + {
434 + break;
435 + }
436 +
437 + // Look for cells that span into the removed row
438 + int numCells = getCellCount( curRow );
439 + for ( int curCell = 0; curCell < numCells; curCell++ )
440 + {
441 + int affectedRow = curRow + formatter.getRowSpan( curRow, curCell ) - 1;
442 + if ( affectedRow >= row )
443 + {
444 + int colSpan = formatter.getColSpan( curRow, curCell );
445 + affectedColSpan -= colSpan;
446 + setNumColumnsPerRow( affectedRow, getNumColumnsPerRow( affectedRow ) + colSpan );
447 + }
448 + }
449 + }
450 + }
451 +
452 + @Override
453 + public void setCellPadding( int padding )
454 + {
455 + super.setCellPadding( padding );
456 +
457 + // Reset the width of all columns
458 + for ( Map.Entry<Integer, Integer> entry : colWidths.entrySet() )
459 + {
460 + setColumnWidth( entry.getKey(), entry.getValue() );
461 + }
462 + }
463 +
464 + @Override
465 + public void setCellSpacing( int spacing )
466 + {
467 + super.setCellSpacing( spacing );
468 +
469 + // Reset the width of all columns
470 + for ( Map.Entry<Integer, Integer> entry : colWidths.entrySet() )
471 + {
472 + setColumnWidth( entry.getKey(), entry.getValue() );
473 + }
59 474 }
60 475
61 476 /**
62 - * Sets the row span for the given cell. This is the number of logical rows
63 - * covered by the cell.
64 - *
65 - * @param row the cell's row
66 - * @param column the cell's column
67 - * @param rowSpan the cell's row span
477 + * Set the width of a column.
478 + *
479 + * @param column the index of the column
480 + * @param width the width in pixels
481 + *
68 482 * @throws IndexOutOfBoundsException
69 483 */
484 + public void setColumnWidth( int column, int width )
485 + {
486 + // Ensure that the indices are not negative.
487 + if ( column < 0 )
488 + {
489 + throw new IndexOutOfBoundsException( "Cannot access a column with a negative index: " + column );
490 + }
491 +
492 + // Add the width to the map
493 + width = Math.max( 1, width );
494 + colWidths.put( new Integer( column ), new Integer( width ) );
495 +
496 + // Update the cell width if possible
497 + int numGhosts = getGhostColumnCount();
498 + if ( column >= numGhosts )
499 + {
500 + return;
501 + }
502 +
503 + // Set the actual column width
504 + FixedWidthTableImpl.get().setColumnWidth( this, ghostRow, column, width );
505 + }
506 +
507 + @Override
508 + public void setHTML( int row, int column, String html )
509 + {
510 + super.setHTML( row, column, html );
511 + clearIdealWidths();
512 + }
513 +
70 514 @Override
71 - public void setRowSpan(int row, int column, int rowSpan) {
72 - rowSpan = Math.max(1, rowSpan);
73 - int curRowSpan = getRowSpan(row, column);
74 - super.setRowSpan(row, column, rowSpan);
75 -
76 - // Update the column counts
77 - int colSpan = getColSpan(row, column);
78 - if (rowSpan > curRowSpan) {
79 - for (int i = row + curRowSpan; i < row + rowSpan; i++) {
80 - setNumColumnsPerRow(i, getNumColumnsPerRow(i) + colSpan);
81 - }
82 - } else if (rowSpan < curRowSpan) {
83 - for (int i = row + rowSpan; i < row + curRowSpan; i++) {
84 - setNumColumnsPerRow(i, getNumColumnsPerRow(i) - colSpan);
85 - }
86 - }
87 - }
88 -
89 - /**
90 - * UnsupportedOperation. Use ExtendedGrid.setColumnWidth(column, width)
91 - * instead.
92 - *
93 - * @param row the row of the cell whose width is to be set
94 - * @param column the cell whose width is to be set
95 - * @param width the cell's new width, in CSS units
96 - * @throws UnsupportedOperationException
97 - */
98 - @Override
99 - public void setWidth(int row, int column, String width) {
100 - throw new UnsupportedOperationException("setWidth is not supported. "
101 - + "Use ExtendedGrid.setColumnWidth(int, int) instead.");
102 - }
103 -
104 - /**
105 - * Gets the TD element representing the specified cell unsafely (meaning
106 - * that it doesn't ensure that the row and column are valid).
107 - *
108 - * @param row the row of the cell to be retrieved
109 - * @param column the column of the cell to be retrieved
110 - * @return the column's TD element
111 - */
112 - @Override
113 - protected Element getRawElement(int row, int column) {
114 - return super.getRawElement(row + 1, column);
115 - }
116 - }
117 -
118 - /**
119 - * This class contains methods used to format a table's columns. It is limited
120 - * by the support cross-browser HTML support for column formatting.
121 - */
122 - public class FixedWidthFlexColumnFormatter extends ColumnFormatter {
123 - /**
124 - * UnsupportedOperation. Use ExtendedGrid.setColumnWidth(column, width)
125 - * instead.
126 - *
127 - * @param column the column of the cell whose width is to be set
128 - * @param width the cell's new width, in percentage or pixel units
129 - * @throws UnsupportedOperationException
130 - */
131 - @Override
132 - public void setWidth(int column, String width) {
133 - throw new UnsupportedOperationException("setWidth is not supported. "
134 - + "Use ExtendedGrid.setColumnWidth(int, int) instead.");
135 - }
136 - }
137 -
138 - /**
139 - * This class contains methods used to format a table's rows.
140 - */
141 - public class FixedWidthFlexRowFormatter extends RowFormatter {
142 - /**
143 - * Unsafe method to get a row element.
144 - *
145 - * @param row the row to get
146 - * @return the row element
147 - */
148 - @Override
149 - protected Element getRawElement(int row) {
150 - return super.getRawElement(row + 1);
151 - }
152 - }
153 -
154 - /**
155 - * The default width of a column in pixels.
156 - */
157 - public static final int DEFAULT_COLUMN_WIDTH = 80;
158 -
159 - /**
160 - * A mapping of column indexes to their widths in pixels.
161 - *
162 - * key = column index
163 - *
164 - * value = column width in pixels
165 - */
166 - private Map<Integer, Integer> colWidths = new HashMap<Integer, Integer>();
167 -
168 - /**
169 - * A mapping of rows to the number of raw columns (not cells) that they
170 - * contain.
171 - *
172 - * key = the row index
173 - *
174 - * value = the number of raw columns in the row
175 - */
176 - private List<Integer> columnsPerRow = new ArrayList<Integer>();
177 -
178 - /**
179 - * A mapping of raw columns counts to the number of rows with that column
180 - * count. For example, if three rows contain a raw column count of five, one
181 - * of the entries will be (5, 3);
182 - *
183 - * key = number of raw columns
184 - *
185 - * value = number of rows with that many raw columns
186 - */
187 - private Map<Integer, Integer> columnCountMap = new HashMap<Integer, Integer>();
188 -
189 - /**
190 - * The maximum number of raw columns in any single row.
191 - */
192 - private int maxRawColumnCount = 0;
193 -
194 - /**
195 - * The hidden, zero row used for sizing the columns.
196 - */
197 - private Element ghostRow;
198 -
199 - /**
200 - * The ideal widths of all columns (that are available).
201 - */
202 - private int[] idealWidths;
203 -
204 - /**
205 - * Info used to calculate ideal column width.
206 - */
207 - private IdealColumnWidthInfo idealColumnWidthInfo;
208 -
209 - /**
210 - * Constructor.
211 - */
212 - public FixedWidthFlexTable() {
213 - super();
214 - Element tableElem = getElement();
215 - DOM.setStyleAttribute(tableElem, "tableLayout", "fixed");
216 - DOM.setStyleAttribute(tableElem, "width", "0px");
217 -
218 - setCellFormatter(new FixedWidthFlexCellFormatter());
219 - setColumnFormatter(new FixedWidthFlexColumnFormatter());
220 - setRowFormatter(new FixedWidthFlexRowFormatter());
221 -
222 - // Create the zero row for sizing
223 - ghostRow = FixedWidthTableImpl.get().createGhostRow();
224 - DOM.insertChild(getBodyElement(), ghostRow, 0);
225 - }
226 -
227 - @Override
228 - public void clear() {
229 - super.clear();
230 - clearIdealWidths();
231 - }
232 -
233 - /**
234 - * @return the raw number of columns in this table.
235 - */
236 - public int getColumnCount() {
237 - return maxRawColumnCount;
238 - }
239 -
240 - /**
241 - * Return the column width for a given column index. If a width has not been
242 - * assigned, the default width is returned.
243 - *
244 - * @param column the column index
245 - * @return the column width in pixels
246 - */
247 - public int getColumnWidth(int column) {
248 - Object colWidth = colWidths.get(new Integer(column));
249 - if (colWidth == null) {
250 - return DEFAULT_COLUMN_WIDTH;
251 - } else {
252 - return ((Integer) colWidth).intValue();
253 - }
254 - }
255 -
256 - /**
257 - * <p>
258 - * Calculate the ideal width required to tightly wrap the specified column. If
259 - * the ideal column width cannot be calculated (eg. if the table is not
260 - * attached), -1 is returned.
261 - * </p>
262 - * <p>
263 - * Note that this method requires an expensive operation whenever the content
264 - * of the table is changed, so you should only call it after you've completely
265 - * modified the contents of your table.
266 - * </p>
267 - *
268 - * @return the ideal column width, or -1 if it is not applicable
269 - */
270 - public int getIdealColumnWidth(int column) {
271 - maybeRecalculateIdealColumnWidths();
272 - if (idealWidths.length > column) {
273 - return idealWidths[column];
274 - }
275 - return -1;
276 - }
277 -
278 - /**
279 - * @see FlexTable
280 - */
281 - @Override
282 - public Element insertCell(int beforeRow, int beforeColumn) {
283 - clearIdealWidths();
284 - Element td = super.insertCell(beforeRow, beforeColumn);
285 - DOM.setStyleAttribute(td, "overflow", "hidden");
286 - setNumColumnsPerRow(beforeRow, getNumColumnsPerRow(beforeRow) + 1);
287 - return td;
288 - }
289 -
290 - /**
291 - * @see FlexTable
292 - */
293 - @Override
294 - public int insertRow(int beforeRow) {
295 - // Get the affected colSpan, which is the number of raw cells created by
296 - // row spanning cells in rows above the new row.
297 - FlexCellFormatter formatter = getFlexCellFormatter();
298 - int affectedColSpan = getNumColumnsPerRow(beforeRow);
299 - if (beforeRow != getRowCount()) {
300 - int numCellsInRow = getCellCount(beforeRow);
301 - for (int cell = 0; cell < numCellsInRow; cell++) {
302 - affectedColSpan -= formatter.getColSpan(beforeRow, cell);
303 - }
304 - }
305 -
306 - // Specifically allow the row count as an insert position.
307 - if (beforeRow != getRowCount()) {
308 - checkRowBounds(beforeRow);
309 - }
310 - Element tr = DOM.createTR();
311 - DOM.insertChild(getBodyElement(), tr, beforeRow + 1);
312 - columnsPerRow.add(beforeRow, new Integer(0));
313 -
314 - // Make sure the column counts are still correct by iterating backward
315 - // through the rows looking for cells that span down into the newly
316 - // inserted row. Stop iterating when every raw column is accounted for.
317 - for (int curRow = beforeRow - 1; curRow >= 0; curRow--) {
318 - // No more affect of rowspan, so we are done
319 - if (affectedColSpan <= 0) {
320 - break;
321 - }
322 -
323 - // Look for cells that span into the new row
324 - int numCells = getCellCount(curRow);
325 - for (int curCell = 0; curCell < numCells; curCell++) {
326 - int affectedRow = curRow + formatter.getRowSpan(curRow, curCell);
327 - if (affectedRow > beforeRow) {
328 - int colSpan = formatter.getColSpan(curRow, curCell);
329 - affectedColSpan -= colSpan;
330 - setNumColumnsPerRow(beforeRow, getNumColumnsPerRow(beforeRow)
331 - + colSpan);
332 - setNumColumnsPerRow(affectedRow, getNumColumnsPerRow(affectedRow)
333 - - colSpan);
334 - }
335 - }
336 - }
337 -
338 - // Return the new row index
339 - return beforeRow;
340 - }
341 -
342 - @Override
343 - public boolean remove(Widget widget) {
344 - if (super.remove(widget)) {
345 - clearIdealWidths();
346 - return true;
347 - }
348 - return false;
349 - }
350 -
351 - /**
352 - * @see FlexTable
353 - */
354 - @Override
355 - public void removeCell(int row, int column) {
356 - clearIdealWidths();
357 - int colSpan = getFlexCellFormatter().getColSpan(row, column);
358 - int rowSpan = getFlexCellFormatter().getRowSpan(row, column);
359 - super.removeCell(row, column);
360 -
361 - // Update the column counts
362 - for (int i = row; i < row + rowSpan; i++) {
363 - setNumColumnsPerRow(i, getNumColumnsPerRow(i) - colSpan);
364 - }
365 - }
366 -
367 - /**
368 - * @see FlexTable
369 - */
370 - @Override
371 - public void removeRow(int row) {
372 - // Set the rowspan of everything in this row to 1
373 - FlexCellFormatter formatter = getFlexCellFormatter();
374 - int affectedColSpan = getNumColumnsPerRow(row);
375 - int numCellsInRow = getCellCount(row);
376 - for (int cell = 0; cell < numCellsInRow; cell++) {
377 - formatter.setRowSpan(row, cell, 1);
378 - affectedColSpan -= formatter.getColSpan(row, cell);
379 - }
380 -
381 - // Actually remove the row
382 - super.removeRow(row);
383 - clearIdealWidths();
384 - setNumColumnsPerRow(row, -1);
385 - columnsPerRow.remove(row);
386 -
387 - // Make sure the column counts are still correct by iterating backward
388 - // through the rows looking for cells that span down into the newly
389 - // inserted row. Stop iterating when every raw column is accounted for.
390 - for (int curRow = row - 1; curRow >= 0; curRow--) {
391 - // No more affects from rowspan, so we are done
392 - if (affectedColSpan <= 0) {
393 - break;
394 - }
395 -
396 - // Look for cells that span into the removed row
397 - int numCells = getCellCount(curRow);
398 - for (int curCell = 0; curCell < numCells; curCell++) {
399 - int affectedRow = curRow + formatter.getRowSpan(curRow, curCell) - 1;
400 - if (affectedRow >= row) {
401 - int colSpan = formatter.getColSpan(curRow, curCell);
402 - affectedColSpan -= colSpan;
403 - setNumColumnsPerRow(affectedRow, getNumColumnsPerRow(affectedRow)
404 - + colSpan);
405 - }
406 - }
407 - }
408 - }
409 -
410 - @Override
411 - public void setCellPadding(int padding) {
412 - super.setCellPadding(padding);
413 -
414 - // Reset the width of all columns
415 - for (Map.Entry<Integer, Integer> entry : colWidths.entrySet()) {
416 - setColumnWidth(entry.getKey(), entry.getValue());
417 - }
418 - }
419 -
420 - @Override
421 - public void setCellSpacing(int spacing) {
422 - super.setCellSpacing(spacing);
423 -
424 - // Reset the width of all columns
425 - for (Map.Entry<Integer, Integer> entry : colWidths.entrySet()) {
426 - setColumnWidth(entry.getKey(), entry.getValue());
427 - }
428 - }
429 -
430 - /**
431 - * Set the width of a column.
432 - *
433 - * @param column the index of the column
434 - * @param width the width in pixels
435 - * @throws IndexOutOfBoundsException
436 - */
437 - public void setColumnWidth(int column, int width) {
438 - // Ensure that the indices are not negative.
439 - if (column < 0) {
440 - throw new IndexOutOfBoundsException(
441 - "Cannot access a column with a negative index: " + column);
442 - }
443 -
444 - // Add the width to the map
445 - width = Math.max(1, width);
446 - colWidths.put(new Integer(column), new Integer(width));
447 -
448 - // Update the cell width if possible
449 - int numGhosts = getGhostColumnCount();
450 - if (column >= numGhosts) {
451 - return;
452 - }
453 -
454 - // Set the actual column width
455 - FixedWidthTableImpl.get().setColumnWidth(this, ghostRow, column, width);
456 - }
457 -
458 - @Override
459 - public void setHTML(int row, int column, String html) {
460 - super.setHTML(row, column, html);
461 - clearIdealWidths();
462 - }
463 -
464 - @Override
465 - public void setText(int row, int column, String text) {
466 - super.setText(row, column, text);
467 - clearIdealWidths();
468 - }
469 -
470 - @Override
471 - public void setWidget(int row, int column, Widget widget) {
472 - super.setWidget(row, column, widget);
473 - clearIdealWidths();
474 - }
475 -
476 - /**
477 - * @see FlexTable
478 - */
479 - @Override
480 - protected void addCells(int row, int num) {
481 - // Account for ghost row
482 - super.addCells(row + 1, num);
483 - clearIdealWidths();
484 - }
485 -
486 - @Override
487 - protected int getDOMCellCount(int row) {
488 - // Account for ghost row
489 - return super.getDOMCellCount(row + 1);
490 - }
491 -
492 - @Override
493 - protected int getDOMRowCount() {
494 - // Account for ghost row
495 - return super.getDOMRowCount() - 1;
496 - }
497 -
498 - /**
499 - * Returns the current number of ghost columns in existence.
500 - *
501 - * @return the number of ghost columns
502 - */
503 - protected int getGhostColumnCount() {
504 - return super.getDOMCellCount(0);
505 - }
506 -
507 - /**
508 - * @return the ghost row element
509 - */
510 - protected Element getGhostRow() {
511 - return ghostRow;
512 - }
513 -
514 - @Override
515 - protected int getRowIndex(Element rowElem) {
516 - int rowIndex = super.getRowIndex(rowElem);
517 - if (rowIndex < 0) {
518 - return rowIndex;
519 - }
520 - return rowIndex - 1;
521 - }
522 -
523 - @Override
524 - protected boolean internalClearCell(Element td, boolean clearInnerHTML) {
525 - clearIdealWidths();
526 - return super.internalClearCell(td, clearInnerHTML);
527 - }
528 -
529 - @Override
530 - protected void onAttach() {
531 - super.onAttach();
532 - clearIdealWidths();
533 - }
534 -
535 - @Override
536 - protected void prepareCell(int row, int column) {
537 - int curNumCells = 0;
538 - if (getRowCount() > row) {
539 - curNumCells = getCellCount(row);
540 - }
541 - super.prepareCell(row, column);
542 -
543 - // Add ghost columns as needed
544 - if (column >= curNumCells) {
545 - // Add ghost cells
546 - int cellsAdded = column - curNumCells + 1;
547 - setNumColumnsPerRow(row, getNumColumnsPerRow(row) + cellsAdded);
548 -
549 - // Set the new cells to hide overflow
550 - for (int cell = curNumCells; cell < column; cell++) {
551 - Element td = getCellFormatter().getElement(row, cell);
552 - DOM.setStyleAttribute(td, "overflow", "hidden");
553 - }
554 - }
555 - }
556 -
557 - /**
558 - * Recalculate the ideal column widths of each column in the data table.
559 - */
560 - protected void recalculateIdealColumnWidths() {
561 - // We need at least one cell to do any calculations
562 - int columnCount = getColumnCount();
563 - if (!isAttached() || getRowCount() == 0 || columnCount < 1) {
564 - idealWidths = new int[0];
565 - return;
566 - }
567 -
568 - recalculateIdealColumnWidthsSetup();
569 - recalculateIdealColumnWidthsImpl();
570 - recalculateIdealColumnWidthsTeardown();
571 - }
572 -
573 - /**
574 - * Clear the idealWidths field when the ideal widths change.
575 - */
576 - void clearIdealWidths() {
577 - idealWidths = null;
578 - }
579 -
580 - /**
581 - * @return true if the ideal column widths have already been calculated
582 - */
583 - boolean isIdealColumnWidthsCalculated() {
584 - return idealWidths != null;
585 - }
586 -
587 - /**
588 - * Recalculate the ideal column widths of each column in the data table. This
589 - * method assumes that the tableLayout has already been changed.
590 - */
591 - void recalculateIdealColumnWidthsImpl() {
592 - idealWidths = FixedWidthTableImpl.get().recalculateIdealColumnWidths(
593 - idealColumnWidthInfo);
594 - }
595 -
596 - /**
597 - * Setup to recalculate column widths.
598 - */
599 - void recalculateIdealColumnWidthsSetup() {
600 - idealColumnWidthInfo = FixedWidthTableImpl.get().recalculateIdealColumnWidthsSetup(
601 - this, getColumnCount(), 0);
602 - }
603 -
604 - /**
605 - * Tear down after recalculating column widths.
606 - */
607 - void recalculateIdealColumnWidthsTeardown() {
608 - FixedWidthTableImpl.get().recalculateIdealColumnWidthsTeardown(
609 - idealColumnWidthInfo);
610 - idealColumnWidthInfo = null;
611 - }
612 -
613 - /**
614 - * Get the number of columns in a row.
615 - *
616 - * @return the number of columns
617 - */
618 - private int getNumColumnsPerRow(int row) {
619 - if (columnsPerRow.size() <= row) {
620 - return 0;
621 - } else {
622 - return columnsPerRow.get(row).intValue();
623 - }
624 - }
625 -
626 - /**
627 - * Recalculate the ideal column widths of each column in the data table if
628 - * they have changed since the last calculation.
629 - */
630 - private void maybeRecalculateIdealColumnWidths() {
631 - if (idealWidths == null) {
632 - recalculateIdealColumnWidths();
633 - }
634 - }
635 -
636 - /**
637 - * Set the number of columns in a row. A negative value in numColumns means
638 - * the row should be removed.
639 - *
640 - * @param row the row index
641 - * @param numColumns the number of columns in the row
642 - */
643 - private void setNumColumnsPerRow(int row, int numColumns) {
644 - // Get the old number of raw columns in the row
645 - int oldNumColumns = getNumColumnsPerRow(row);
646 - if (oldNumColumns == numColumns) {
647 - return;
648 - }
649 -
650 - // Update the list of columns per row
651 - Integer numColumnsI = new Integer(numColumns);
652 - Integer oldNumColumnsI = new Integer(oldNumColumns);
653 - if (row < columnsPerRow.size()) {
654 - columnsPerRow.set(row, numColumnsI);
655 - } else {
656 - columnsPerRow.add(numColumnsI);
657 - }
658 -
659 - // Decrement the old number of columns
660 - boolean oldNumColumnsRemoved = false;
661 - if (columnCountMap.containsKey(oldNumColumnsI)) {
662 - int numRows = columnCountMap.get(oldNumColumnsI).intValue();
663 - if (numRows == 1) {
664 - columnCountMap.remove(oldNumColumnsI);
665 - oldNumColumnsRemoved = true;
666 - } else {
667 - columnCountMap.put(oldNumColumnsI, new Integer(numRows - 1));
668 - }
669 - }
670 -
671 - // Increment the new number of columns
672 - if (numColumns > 0) {
673 - if (columnCountMap.containsKey(numColumnsI)) {
674 - int numRows = columnCountMap.get(numColumnsI).intValue();
675 - columnCountMap.put(numColumnsI, new Integer(numRows + 1));
676 - } else {
677 - columnCountMap.put(numColumnsI, new Integer(1));
678 - }
679 - }
680 -
681 - // Update the maximum number of rows
682 - if (numColumns > maxRawColumnCount) {
683 - maxRawColumnCount = numColumns;
684 - } else if ((numColumns < oldNumColumns)
685 - && (oldNumColumns == maxRawColumnCount) && oldNumColumnsRemoved) {
686 - // Column count decreased from max count
687 - maxRawColumnCount = 0;
688 - for (Integer curNumColumns : columnCountMap.keySet()) {
689 - maxRawColumnCount = Math.max(maxRawColumnCount,
690 - curNumColumns.intValue());
691 - }
692 - }
693 -
694 - // Update the ghost row
695 - updateGhostRow();
696 - }
697 -
698 - /**
699 - * Add or remove ghost cells when the table size changes.
700 - */
701 - private void updateGhostRow() {
702 - int curNumGhosts = getGhostColumnCount();
703 - if (maxRawColumnCount > curNumGhosts) {
704 - // Add ghosts as needed
705 - super.addCells(0, maxRawColumnCount - curNumGhosts);
706 - for (int i = curNumGhosts; i < maxRawColumnCount; i++) {
707 - Element td = FixedWidthTableImpl.get().getGhostCell(ghostRow, i);
708 - FixedWidthTableImpl.get().createGhostCell(td);
709 - setColumnWidth(i, getColumnWidth(i));
710 - }
711 - } else if (maxRawColumnCount < curNumGhosts) {
712 - // Remove ghost rows as needed
713 - int cellsToRemove = curNumGhosts - maxRawColumnCount;
714 - for (int i = 0; i < cellsToRemove; i++) {
715 - DOM.removeChild(ghostRow, FixedWidthTableImpl.get().getGhostCell(
716 - ghostRow, maxRawColumnCount));
717 - }
515 + public void setText( int row, int column, String text )
516 + {
517 + super.setText( row, column, text );
518 + clearIdealWidths();
519 + }
520 +
521 + @Override
522 + public void setWidget( int row, int column, Widget widget )
523 + {
524 + super.setWidget( row, column, widget );
525 + clearIdealWidths();
526 + }
527 +
528 + /**
529 + * @see FlexTable
530 + */
531 + @Override
532 + protected void addCells( int row, int num )
533 + {
534 + // Account for ghost row
535 + super.addCells( row + 1, num );
536 + clearIdealWidths();
537 + }
538 +
539 + @Override
540 + protected int getDOMCellCount( int row )
541 + {
542 + // Account for ghost row
543 + return super.getDOMCellCount( row + 1 );
544 + }
545 +
546 + @Override
547 + protected int getDOMRowCount()
548 + {
549 + // Account for ghost row
550 + return super.getDOMRowCount() - 1;
551 + }
552 +
553 + /**
554 + * Returns the current number of ghost columns in existence.
555 + *
556 + * @return the number of ghost columns
557 + */
558 + protected int getGhostColumnCount()
559 + {
560 + return super.getDOMCellCount( 0 );
561 + }
562 +
563 + /**
564 + * @return the ghost row element
565 + */
566 + protected Element getGhostRow()
567 + {
568 + return ghostRow;
569 + }
570 +
571 + @Override
572 + protected int getRowIndex( Element rowElem )
573 + {
574 + int rowIndex = super.getRowIndex( rowElem );
575 + if ( rowIndex < 0 )
576 + {
577 + return rowIndex;
578 + }
579 + return rowIndex - 1;
580 + }
581 +
582 + @Override
583 + protected boolean internalClearCell( Element td, boolean clearInnerHTML )
584 + {
585 + clearIdealWidths();
586 + return super.internalClearCell( td, clearInnerHTML );
587 + }
588 +
589 + @Override
590 + protected void onAttach()
591 + {
592 + super.onAttach();
593 + clearIdealWidths();
594 + }
595 +
596 + @Override
597 + protected void prepareCell( int row, int column )
598 + {
599 + int curNumCells = 0;
600 + if ( getRowCount() > row )
601 + {
602 + curNumCells = getCellCount( row );
603 + }
604 + super.prepareCell( row, column );
605 +
606 + // Add ghost columns as needed
607 + if ( column >= curNumCells )
608 + {
609 + // Add ghost cells
610 + int cellsAdded = column - curNumCells + 1;
611 + setNumColumnsPerRow( row, getNumColumnsPerRow( row ) + cellsAdded );
612 +
613 + // Set the new cells to hide overflow
614 + for ( int cell = curNumCells; cell < column; cell++ )
615 + {
616 + Element td = getCellFormatter().getElement( row, cell );
617 + DOM.setStyleAttribute( td, "overflow", "hidden" );
618 + }
619 + }
620 + }
621 +
622 + /**
623 + * Recalculate the ideal column widths of each column in the data table.
624 + */
625 + protected void recalculateIdealColumnWidths()
626 + {
627 + // We need at least one cell to do any calculations
628 + int columnCount = getColumnCount();
629 + if ( !isAttached() || getRowCount() == 0 || columnCount < 1 )
630 + {
631 + idealWidths = new int[0];
632 + return;
633 + }
634 +
635 + recalculateIdealColumnWidthsSetup();
636 + recalculateIdealColumnWidthsImpl();
637 + recalculateIdealColumnWidthsTeardown();
638 + }
639 +
640 + /**
641 + * Clear the idealWidths field when the ideal widths change.
642 + */
643 + void clearIdealWidths()
644 + {
645 + idealWidths = null;
646 + }
647 +
648 + /**
649 + * @return true if the ideal column widths have already been calculated
650 + */
651 + boolean isIdealColumnWidthsCalculated()
652 + {
653 + return idealWidths != null;
654 + }
655 +
656 + /**
657 + * Recalculate the ideal column widths of each column in the data table. This
658 + * method assumes that the tableLayout has already been changed.
659 + */
660 + void recalculateIdealColumnWidthsImpl()
661 + {
662 + idealWidths = FixedWidthTableImpl.get().recalculateIdealColumnWidths( idealColumnWidthInfo );
663 + }
664 +
665 + /**
666 + * Setup to recalculate column widths.
667 + */
668 + void recalculateIdealColumnWidthsSetup()
669 + {
670 + idealColumnWidthInfo = FixedWidthTableImpl.get().recalculateIdealColumnWidthsSetup( this, getColumnCount(), 0 );
671 + }
672 +
673 + /**
674 + * Tear down after recalculating column widths.
675 + */
676 + void recalculateIdealColumnWidthsTeardown()
677 + {
678 + FixedWidthTableImpl.get().recalculateIdealColumnWidthsTeardown( idealColumnWidthInfo );
679 + idealColumnWidthInfo = null;
680 + }
681 +
682 + /**
683 + * Get the number of columns in a row.
684 + *
685 + * @return the number of columns
686 + */
687 + private int getNumColumnsPerRow( int row )
688 + {
689 + if ( columnsPerRow.size() <= row )
690 + {
691 + return 0;
692 + }
693 + else
694 + {
695 + return columnsPerRow.get( row ).intValue();
696 + }
697 + }
698 +
699 + /**
700 + * Recalculate the ideal column widths of each column in the data table if
701 + * they have changed since the last calculation.
702 + */
703 + private void maybeRecalculateIdealColumnWidths()
704 + {
705 + if ( idealWidths == null )
706 + {
707 + recalculateIdealColumnWidths();
708 + }
709 + }
710 +
711 + /**
712 + * Set the number of columns in a row. A negative value in numColumns means
713 + * the row should be removed.
714 + *
715 + * @param row the row index
716 + * @param numColumns the number of columns in the row
717 + */
718 + private void setNumColumnsPerRow( int row, int numColumns )
719 + {
720 + // Get the old number of raw columns in the row
721 + int oldNumColumns = getNumColumnsPerRow( row );
722 + if ( oldNumColumns == numColumns )
723 + {
724 + return;
725 + }
726 +
727 + // Update the list of columns per row
728 + Integer numColumnsI = new Integer( numColumns );
729 + Integer oldNumColumnsI = new Integer( oldNumColumns );
730 + if ( row < columnsPerRow.size() )
731 + {
732 + columnsPerRow.set( row, numColumnsI );
733 + }
734 + else
735 + {
736 + columnsPerRow.add( numColumnsI );
737 + }
738 +
739 + // Decrement the old number of columns
740 + boolean oldNumColumnsRemoved = false;
741 + if ( columnCountMap.containsKey( oldNumColumnsI ) )
742 + {
743 + int numRows = columnCountMap.get( oldNumColumnsI ).intValue();
744 + if ( numRows == 1 )
745 + {
746 + columnCountMap.remove( oldNumColumnsI );
747 + oldNumColumnsRemoved = true;
748 + }
749 + else
750 + {
751 + columnCountMap.put( oldNumColumnsI, new Integer( numRows - 1 ) );
752 + }
753 + }
754 +
755 + // Increment the new number of columns
756 + if ( numColumns > 0 )
757 + {
758 + if ( columnCountMap.containsKey( numColumnsI ) )
759 + {
760 + int numRows = columnCountMap.get( numColumnsI ).intValue();
761 + columnCountMap.put( numColumnsI, new Integer( numRows + 1 ) );
762 + }
763 + else
764 + {
765 + columnCountMap.put( numColumnsI, new Integer( 1 ) );
766 + }
767 + }
768 +
769 + // Update the maximum number of rows
770 + if ( numColumns > maxRawColumnCount )
771 + {
772 + maxRawColumnCount = numColumns;
773 + }
774 + else if ( (numColumns < oldNumColumns) && (oldNumColumns == maxRawColumnCount) && oldNumColumnsRemoved )
775 + {
776 + // Column count decreased from max count
777 + maxRawColumnCount = 0;
778 + for ( Integer curNumColumns : columnCountMap.keySet() )
779 + {
780 + maxRawColumnCount = Math.max( maxRawColumnCount, curNumColumns.intValue() );
781 + }
782 + }
783 +
784 + // Update the ghost row
785 + updateGhostRow();
786 + }
787 +
788 + /**
789 + * Add or remove ghost cells when the table size changes.
790 + */
791 + private void updateGhostRow()
792 + {
793 + int curNumGhosts = getGhostColumnCount();
794 + if ( maxRawColumnCount > curNumGhosts )
795 + {
796 + // Add ghosts as needed
797 + super.addCells( 0, maxRawColumnCount - curNumGhosts );
798 + for ( int i = curNumGhosts; i < maxRawColumnCount; i++ )
799 + {
800 + Element td = FixedWidthTableImpl.get().getGhostCell( ghostRow, i );
801 + FixedWidthTableImpl.get().createGhostCell( td );
802 + setColumnWidth( i, getColumnWidth( i ) );
803 + }
804 + }
805 + else if ( maxRawColumnCount < curNumGhosts )
806 + {
807 + // Remove ghost rows as needed
808 + int cellsToRemove = curNumGhosts - maxRawColumnCount;
809 + for ( int i = 0; i < cellsToRemove; i++ )
810 + {
811 + DOM.removeChild( ghostRow, FixedWidthTableImpl.get().getGhostCell( ghostRow, maxRawColumnCount ) );
812 + }
813 + }
718 814 }
719 - }
720 815 }