Revision: 9355
Author: jlaba...@google.com
Date: Fri Dec 3 05:16:36 2010
Log: Adding methods to insert columns, get the column count, and get
columns by index in a CellTable. Thesemethods are very useful for changing
the visible Columns. Currently, users must remove all columns, then re-add
them just to insert a single column.
Review at http://gwt-code-reviews.appspot.com/1181801
Review by: sbruba...@google.com
http://code.google.com/p/google-web-toolkit/source/detail?r=9355
Modified:
/trunk/user/src/com/google/gwt/user/cellview/client/CellTable.java
/trunk/user/test/com/google/gwt/user/cellview/client/CellTableTest.java
=======================================
--- /trunk/user/src/com/google/gwt/user/cellview/client/CellTable.java Wed
Dec 1 05:40:20 2010
+++ /trunk/user/src/com/google/gwt/user/cellview/client/CellTable.java Fri
Dec 3 05:16:36 2010
@@ -592,91 +592,59 @@
}
/**
- * Adds a column to the table.
+ * Adds a column to the end of the table.
*
* @param col the column to be added
*/
public void addColumn(Column<T, ?> col) {
- addColumn(col, (Header<?>) null, (Header<?>) null);
+ insertColumn(getColumnCount(), col);
}
/**
- * Adds a column to the table with an associated header.
+ * Adds a column to the end of the table with an associated header.
*
* @param col the column to be added
* @param header the associated {...@link Header}
*/
public void addColumn(Column<T, ?> col, Header<?> header) {
- addColumn(col, header, null);
+ insertColumn(getColumnCount(), col, header);
}
/**
- * Adds a column to the table with an associated header and footer.
+ * Adds a column to the end of the table with an associated header and
footer.
*
* @param col the column to be added
* @param header the associated {...@link Header}
* @param footer the associated footer (as a {...@link Header} object)
*/
public void addColumn(Column<T, ?> col, Header<?> header, Header<?>
footer) {
- headers.add(header);
- footers.add(footer);
- columns.add(col);
- boolean wasinteractive = isInteractive;
- updateDependsOnSelection();
-
- // Move the keyboard selected column if the current column is not
- // interactive.
- if (!wasinteractive && isInteractive) {
- keyboardSelectedColumn = columns.size() - 1;
- }
-
- // Sink events used by the new column.
- Set<String> consumedEvents = new HashSet<String>();
- {
- Set<String> cellEvents = col.getCell().getConsumedEvents();
- if (cellEvents != null) {
- consumedEvents.addAll(cellEvents);
- }
- }
- if (header != null) {
- Set<String> headerEvents = header.getCell().getConsumedEvents();
- if (headerEvents != null) {
- consumedEvents.addAll(headerEvents);
- }
- }
- if (footer != null) {
- Set<String> footerEvents = footer.getCell().getConsumedEvents();
- if (footerEvents != null) {
- consumedEvents.addAll(footerEvents);
- }
- }
- CellBasedWidgetImpl.get().sinkEvents(this, consumedEvents);
-
- redraw();
+ insertColumn(getColumnCount(), col, header, footer);
}
/**
- * Adds a column to the table with an associated String header.
+ * Adds a column to the end of the table with an associated String
header.
*
* @param col the column to be added
* @param headerString the associated header text, as a String
*/
public void addColumn(Column<T, ?> col, String headerString) {
- addColumn(col, new TextHeader(headerString), null);
+ insertColumn(getColumnCount(), col, headerString);
}
/**
- * Adds a column to the table with an associated {...@link SafeHtml} header.
+ * Adds a column to the end of the table with an associated {...@link
SafeHtml}
+ * header.
*
* @param col the column to be added
* @param headerHtml the associated header text, as safe HTML
*/
public void addColumn(Column<T, ?> col, SafeHtml headerHtml) {
- addColumn(col, new SafeHtmlHeader(headerHtml), null);
+ insertColumn(getColumnCount(), col, headerHtml);
}
/**
- * Adds a column to the table with an associated String header and
footer.
+ * Adds a column to the end of the table with an associated String
header and
+ * footer.
*
* @param col the column to be added
* @param headerString the associated header text, as a String
@@ -684,12 +652,12 @@
*/
public void addColumn(Column<T, ?> col, String headerString,
String footerString) {
- addColumn(col, new TextHeader(headerString), new
TextHeader(footerString));
+ insertColumn(getColumnCount(), col, headerString, footerString);
}
/**
- * Adds a column to the table with an associated {...@link SafeHtml} header
and
- * footer.
+ * Adds a column to the end of the table with an associated {...@link
SafeHtml}
+ * header and footer.
*
* @param col the column to be added
* @param headerHtml the associated header text, as safe HTML
@@ -697,8 +665,7 @@
*/
public void addColumn(Column<T, ?> col, SafeHtml headerHtml,
SafeHtml footerHtml) {
- addColumn(col, new SafeHtmlHeader(headerHtml), new SafeHtmlHeader(
- footerHtml));
+ insertColumn(getColumnCount(), col, headerHtml, footerHtml);
}
/**
@@ -721,6 +688,26 @@
int height = getClientHeight(tbody);
return height;
}
+
+ /**
+ * Get the column at the specified index.
+ *
+ * @param col the index of the column to retrieve
+ * @return the {...@link Column} at the index
+ */
+ public Column<T, ?> getColumn(int col) {
+ checkColumnBounds(col);
+ return columns.get(col);
+ }
+
+ /**
+ * Get the number of columns in the table.
+ *
+ * @return the column count
+ */
+ public int getColumnCount() {
+ return columns.size();
+ }
/**
* Return the height of the table header.
@@ -747,6 +734,138 @@
NodeList<TableRowElement> rows = tbody.getRows();
return rows.getLength() > row ? rows.getItem(row) : null;
}
+
+ /**
+ * Inserts a column into the table at the specified index.
+ *
+ * @param beforeIndex the index to insert the column
+ * @param col the column to be added
+ */
+ public void insertColumn(int beforeIndex, Column<T, ?> col) {
+ insertColumn(beforeIndex, col, (Header<?>) null, (Header<?>) null);
+ }
+
+ /**
+ * Inserts a column into the table at the specified index with an
associated
+ * header.
+ *
+ * @param beforeIndex the index to insert the column
+ * @param col the column to be added
+ * @param header the associated {...@link Header}
+ */
+ public void insertColumn(int beforeIndex, Column<T, ?> col, Header<?>
header) {
+ insertColumn(beforeIndex, col, header, null);
+ }
+
+ /**
+ * Inserts a column into the table at the specified index with an
associated
+ * header and footer.
+ *
+ * @param beforeIndex the index to insert the column
+ * @param col the column to be added
+ * @param header the associated {...@link Header}
+ * @param footer the associated footer (as a {...@link Header} object)
+ * @throws IndexOutOfBoundsException if the index is out of range
+ */
+ public void insertColumn(int beforeIndex, Column<T, ?> col, Header<?>
header,
+ Header<?> footer) {
+ // Allow insert at the end.
+ if (beforeIndex != getColumnCount()) {
+ checkColumnBounds(beforeIndex);
+ }
+
+ headers.add(beforeIndex, header);
+ footers.add(beforeIndex, footer);
+ columns.add(beforeIndex, col);
+ boolean wasinteractive = isInteractive;
+ updateDependsOnSelection();
+
+ // Move the keyboard selected column if the current column is not
+ // interactive.
+ if (!wasinteractive && isInteractive) {
+ keyboardSelectedColumn = beforeIndex;
+ }
+
+ // Sink events used by the new column.
+ Set<String> consumedEvents = new HashSet<String>();
+ {
+ Set<String> cellEvents = col.getCell().getConsumedEvents();
+ if (cellEvents != null) {
+ consumedEvents.addAll(cellEvents);
+ }
+ }
+ if (header != null) {
+ Set<String> headerEvents = header.getCell().getConsumedEvents();
+ if (headerEvents != null) {
+ consumedEvents.addAll(headerEvents);
+ }
+ }
+ if (footer != null) {
+ Set<String> footerEvents = footer.getCell().getConsumedEvents();
+ if (footerEvents != null) {
+ consumedEvents.addAll(footerEvents);
+ }
+ }
+ CellBasedWidgetImpl.get().sinkEvents(this, consumedEvents);
+
+ redraw();
+ }
+
+ /**
+ * Inserts a column into the table at the specified index with an
associated
+ * String header.
+ *
+ * @param beforeIndex the index to insert the column
+ * @param col the column to be added
+ * @param headerString the associated header text, as a String
+ */
+ public void insertColumn(int beforeIndex, Column<T, ?> col,
+ String headerString) {
+ insertColumn(beforeIndex, col, new TextHeader(headerString), null);
+ }
+
+ /**
+ * Inserts a column into the table at the specified index with an
associated
+ * {...@link SafeHtml} header.
+ *
+ * @param beforeIndex the index to insert the column
+ * @param col the column to be added
+ * @param headerHtml the associated header text, as safe HTML
+ */
+ public void insertColumn(int beforeIndex, Column<T, ?> col,
+ SafeHtml headerHtml) {
+ insertColumn(beforeIndex, col, new SafeHtmlHeader(headerHtml), null);
+ }
+
+ /**
+ * Inserts a column into the table at the specified index with an
associated
+ * String header and footer.
+ *
+ * @param beforeIndex the index to insert the column
+ * @param col the column to be added
+ * @param headerString the associated header text, as a String
+ * @param footerString the associated footer text, as a String
+ */
+ public void insertColumn(int beforeIndex, Column<T, ?> col,
+ String headerString, String footerString) {
+ insertColumn(beforeIndex, col, new TextHeader(headerString),
+ new TextHeader(footerString));
+ }
+
+ /**
+ * Inserts a column into the table at the specified index with an
associated
+ * {...@link SafeHtml} header and footer.
+ *
+ * @param beforeIndex the index to insert the column
+ * @param col the column to be added
+ * @param headerHtml the associated header text, as safe HTML
+ * @param footerHtml the associated footer text, as safe HTML
+ */
+ public void insertColumn(int beforeIndex, Column<T, ?> col,
+ SafeHtml headerHtml, SafeHtml footerHtml) {
+ insertColumn(beforeIndex, col, new SafeHtmlHeader(headerHtml),
+ new SafeHtmlHeader(footerHtml));
+ }
/**
* Redraw the table's footers.
@@ -1196,6 +1315,19 @@
void setLoadingState(LoadingState state) {
setLoadingIconVisible(state == LoadingState.LOADING);
}
+
+ /**
+ * Check that the specified column is within bounds.
+ *
+ * @param col the column index
+ * @throws IndexOutOfBoundsException if the column is out of bounds
+ */
+ private void checkColumnBounds(int col) {
+ if (col < 0 || col >= getColumnCount()) {
+ throw new IndexOutOfBoundsException("Column index is out of bounds: "
+ + col);
+ }
+ }
/**
* Render the header or footer.
@@ -1357,8 +1489,7 @@
* Fire an event to the Cell within the specified {...@link
TableCellElement}.
*/
private <C> void fireEventToCell(Event event, String eventType,
- TableCellElement tableCell, T value, Context context,
- Column<T, C> column) {
+ TableCellElement tableCell, T value, Context context, Column<T, C>
column) {
Cell<C> cell = column.getCell();
if (cellConsumesEventType(cell, eventType)) {
C cellValue = column.getValue(value);
=======================================
--- /trunk/user/test/com/google/gwt/user/cellview/client/CellTableTest.java
Wed Dec 1 05:40:20 2010
+++ /trunk/user/test/com/google/gwt/user/cellview/client/CellTableTest.java
Fri Dec 3 05:16:36 2010
@@ -15,6 +15,7 @@
*/
package com.google.gwt.user.cellview.client;
+import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
@@ -25,6 +26,7 @@
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.dom.client.TableSectionElement;
import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellTable.Resources;
import com.google.gwt.user.cellview.client.CellTable.Style;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
@@ -38,6 +40,28 @@
* Tests for {...@link CellTable}.
*/
public class CellTableTest extends AbstractHasDataTestBase {
+
+ /**
+ * A concrete column that implements a getter that always returns null.
+ *
+ * @param <T> the row type
+ * @param <C> the column type
+ */
+ private static class MockColumn<T, C> extends Column<T, C> {
+
+ public MockColumn() {
+ super(new AbstractCell<C>() {
+ @Override
+ public void render(Context context, C value, SafeHtmlBuilder sb) {
+ }
+ });
+ }
+
+ @Override
+ public C getValue(T object) {
+ return null;
+ }
+ }
/**
* Test that calls to addColumn results in only one redraw.
@@ -137,6 +161,38 @@
RootPanel.get().remove(table);
}
+
+ public void testGetColumnOutOfBounds() {
+ CellTable<String> table = new CellTable<String>();
+
+ // Get column when there are no columns.
+ try {
+ table.getColumn(0);
+ fail("Expected IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+
+ // Add some columns.
+ table.addColumn(new MockColumn<String, String>());
+ table.addColumn(new MockColumn<String, String>());
+
+ // Negative index.
+ try {
+ table.getColumn(-1);
+ fail("Expected IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+
+ // Index too high.
+ try {
+ table.getColumn(2);
+ fail("Expected IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+ }
public void testGetRowElement() {
CellTable<String> table = createAbstractHasData(new TextCell());
@@ -145,6 +201,55 @@
// Ensure that calling getRowElement() flushes all pending changes.
assertNotNull(table.getRowElement(9));
}
+
+ public void testInsertColumn() {
+ CellTable<String> table = new CellTable<String>();
+ assertEquals(0, table.getColumnCount());
+
+ // Insert first column.
+ Column<String, ?> a = new MockColumn<String, String>();
+ table.insertColumn(0, a);
+ assertEquals(1, table.getColumnCount());
+ assertEquals(a, table.getColumn(0));
+
+ // Insert column at beginning.
+ Column<String, ?> b = new MockColumn<String, String>();
+ table.insertColumn(0, b);
+ assertEquals(2, table.getColumnCount());
+ assertEquals(b, table.getColumn(0));
+ assertEquals(a, table.getColumn(1));
+
+ // Insert column at end.
+ Column<String, ?> c = new MockColumn<String, String>();
+ table.insertColumn(2, c);
+ assertEquals(3, table.getColumnCount());
+ assertEquals(b, table.getColumn(0));
+ assertEquals(a, table.getColumn(1));
+ assertEquals(c, table.getColumn(2));
+
+ // Insert column in middle.
+ Column<String, ?> d = new MockColumn<String, String>();
+ table.insertColumn(1, d);
+ assertEquals(4, table.getColumnCount());
+ assertEquals(b, table.getColumn(0));
+ assertEquals(d, table.getColumn(1));
+ assertEquals(a, table.getColumn(2));
+ assertEquals(c, table.getColumn(3));
+
+ // Insert column at invalid index.
+ try {
+ table.insertColumn(-1, d);
+ fail("Expected IndexOutOfBoundsExecltion");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+ try {
+ table.insertColumn(6, d);
+ fail("Expected IndexOutOfBoundsExecltion");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+ }
/**
* Test headers that span multiple columns.
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors