com.google.gwt.cell.client

## Class AbstractCell<C>

- java.lang.Object
- - com.google.gwt.cell.client.AbstractCell<C>

- Type Parameters:
    `C` - the type that this Cell represents
  All Implemented Interfaces:
    Cell<C>
  Direct Known Subclasses:
    AbstractEditableCell, AbstractSafeHtmlCell, ActionCell, ButtonCellBase, CompositeCell, DateCell, ImageCell, ImageLoadingCell, ImageResourceCell, NumberCell, SafeHtmlCell, SafeImageCell

      public abstract class AbstractCell<C>
      extends java.lang.Object
      implements Cell<C>

  A default implementation of the `Cell` interface.

  ### Examples

  Read only cell

    >     public class CellExample implements EntryPoint {

    >       /**
    >        * A custom {@link Cell} used to render a string that contains the name of a
    >        * color.
    >        */
    >       static class ColorCell extends AbstractCell<String> {

    >         /**
    >          * The HTML templates used to render the cell.
    >          */
    >         interface Templates extends SafeHtmlTemplates {
    >           /**
    >            * The template for this Cell, which includes styles and a value.
    >            *
    >            * @param styles the styles to include in the style attribute of the div
    >            * @param value the safe value. Since the value type is {@link SafeHtml},
    >            *          it will not be escaped before including it in the template.
    >            *          Alternatively, you could make the value type String, in which
    >            *          case the value would be escaped.
    >            * @return a {@link SafeHtml} instance
    >            */
    >           @SafeHtmlTemplates.Template("<div style=\"{0}\">{1}</div>")
    >           SafeHtml cell(SafeStyles styles, SafeHtml value);
    >         }

    >         /**
    >          * Create a singleton instance of the templates used to render the cell.
    >          */
    >         private static Templates templates = GWT.create(Templates.class);

    >         @Override
    >         public void render(Context context, String value, SafeHtmlBuilder sb) {
    >           /*
    >            * Always do a null check on the value. Cell widgets can pass null to
    >            * cells if the underlying data contains a null, or if the data arrives
    >            * out of order.
    >            */
    >           if (value == null) {
    >             return;
    >           }

    >           // If the value comes from the user, we escape it to avoid XSS attacks.
    >           SafeHtml safeValue = SafeHtmlUtils.fromString(value);

    >           // Use the template to create the Cell's html.
    >           SafeStyles styles = SafeStylesUtils.forTrustedColor(safeValue.asString());
    >           SafeHtml rendered = templates.cell(styles, safeValue);
    >           sb.append(rendered);
    >         }
    >       }

    >       /**
    >        * The list of data to display.
    >        */
    >       private static final List<String> COLORS = Arrays.asList("red", "green", "blue", "violet",
    >           "black", "gray");

    >       @Override
    >       public void onModuleLoad() {
    >         // Create a cell to render each value.
    >         ColorCell cell = new ColorCell();

    >         // Use the cell in a CellList.
    >         CellList<String> cellList = new CellList<String>(cell);

    >         // Push the data into the widget.
    >         cellList.setRowData(0, COLORS);

    >         // Add it to the root panel.
    >         RootPanel.get().add(cellList);
    >       }
    >     }

  Cell with events

    >     public class CellWithEventsExample implements EntryPoint {

    >       /**
    >        * A custom {@link Cell} used to render a string that contains the name of a
    >        * color.
    >        */
    >       static class ColorCell extends AbstractCell<String> {

    >         /**
    >          * The HTML templates used to render the cell.
    >          */
    >         interface Templates extends SafeHtmlTemplates {
    >           /**
    >            * The template for this Cell, which includes styles and a value.
    >            *
    >            * @param styles the styles to include in the style attribute of the div
    >            * @param value the safe value. Since the value type is {@link SafeHtml},
    >            *          it will not be escaped before including it in the template.
    >            *          Alternatively, you could make the value type String, in which
    >            *          case the value would be escaped.
    >            * @return a {@link SafeHtml} instance
    >            */
    >           @SafeHtmlTemplates.Template("<div style=\"{0}\">{1}</div>")
    >           SafeHtml cell(SafeStyles styles, SafeHtml value);
    >         }

    >         /**
    >          * Create a singleton instance of the templates used to render the cell.
    >          */
    >         private static Templates templates = GWT.create(Templates.class);

    >         public ColorCell() {
    >           /*
    >            * Sink the click and keydown events. We handle click events in this
    >            * class. AbstractCell will handle the keydown event and call
    >            * onEnterKeyDown() if the user presses the enter key while the cell is
    >            * selected.
    >            */
    >           super("click", "keydown");
    >         }

    >         /**
    >          * Called when an event occurs in a rendered instance of this Cell. The
    >          * parent element refers to the element that contains the rendered cell, NOT
    >          * to the outermost element that the Cell rendered.
    >          */
    >         @Override
    >         public void onBrowserEvent(Context context, Element parent, String value, NativeEvent event,
    >             ValueUpdater<String> valueUpdater) {
    >           // Let AbstractCell handle the keydown event.
    >           super.onBrowserEvent(context, parent, value, event, valueUpdater);

    >           // Handle the click event.
    >           if ("click".equals(event.getType())) {
    >             // Ignore clicks that occur outside of the outermost element.
    >             EventTarget eventTarget = event.getEventTarget();
    >             if (parent.getFirstChildElement().isOrHasChild(Element.as(eventTarget))) {
    >               doAction(value, valueUpdater);
    >             }
    >           }
    >         }

    >         @Override
    >         public void render(Context context, String value, SafeHtmlBuilder sb) {
    >           /*
    >            * Always do a null check on the value. Cell widgets can pass null to
    >            * cells if the underlying data contains a null, or if the data arrives
    >            * out of order.
    >            */
    >           if (value == null) {
    >             return;
    >           }

    >           // If the value comes from the user, we escape it to avoid XSS attacks.
    >           SafeHtml safeValue = SafeHtmlUtils.fromString(value);

    >           // Use the template to create the Cell's html.
    >           SafeStyles styles = SafeStylesUtils.forTrustedColor(safeValue.asString());
    >           SafeHtml rendered = templates.cell(styles, safeValue);
    >           sb.append(rendered);
    >         }

    >         /**
    >          * onEnterKeyDown is called when the user presses the ENTER key will the
    >          * Cell is selected. You are not required to override this method, but its a
    >          * common convention that allows your cell to respond to key events.
    >          */
    >         @Override
    >         protected void onEnterKeyDown(Context context, Element parent, String value, NativeEvent event,
    >             ValueUpdater<String> valueUpdater) {
    >           doAction(value, valueUpdater);
    >         }

    >         private void doAction(String value, ValueUpdater<String> valueUpdater) {
    >           // Alert the user that they selected a value.
    >           Window.alert("You selected the color " + value);

    >           // Trigger a value updater. In this case, the value doesn't actually
    >           // change, but we use a ValueUpdater to let the app know that a value
    >           // was clicked.
    >           valueUpdater.update(value);
    >         }
    >       }

    >       /**
    >        * The list of data to display.
    >        */
    >       private static final List<String> COLORS = Arrays.asList("red", "green", "blue", "violet",
    >           "black", "gray");

    >       @Override
    >       public void onModuleLoad() {
    >         // Create a cell to render each value.
    >         ColorCell cell = new ColorCell();

    >         // Use the cell in a CellList.
    >         CellList<String> cellList = new CellList<String>(cell);

    >         // Push the data into the widget.
    >         cellList.setRowData(0, COLORS);

    >         // Add it to the root panel.
    >         RootPanel.get().add(cellList);
    >       }
    >     }

  Interactive cell

    >     public class InteractionCellExample implements EntryPoint {

    >       /**
    >        * A simple data type that represents a contact.
    >        */
    >       private static class Contact {
    >         private final String address;
    >         private final Date birthday;
    >         private final String name;

    >         public Contact(String name, Date birthday, String address) {
    >           this.name = name;
    >           this.birthday = birthday;
    >           this.address = address;
    >         }
    >       }

    >       /**
    >        * A custom {@link Cell} used to render a {@link Contact}. We extend
    >        * {@link AbstractCell} because it provides reasonable implementations of
    >        * methods that work for most use cases.
    >        */
    >       private static class ContactCell extends AbstractCell<Contact> {

    >         /**
    >          * The {@link DateTimeFormat} used to format the birthday. Since our render
    >          * method is called for every value in the list, we want to move heavy
    >          * weight work, such as creating a formatter, out of it to speed up
    >          * rendering as much as possible.
    >          */
    >         private DateTimeFormat dateFormat = DateTimeFormat.getFormat(PredefinedFormat.DATE_LONG);

    >         public ContactCell() {
    >           /*
    >            * Let the parent class know that our cell responds to click events and
    >            * keydown events.
    >            */
    >           super("click", "keydown");
    >         }

    >         @Override
    >         public void onBrowserEvent(Context context, Element parent, Contact value,
    >             NativeEvent event, ValueUpdater<Contact> valueUpdater) {
    >           // Check that the value is not null.
    >           if (value == null) {
    >             return;
    >           }

    >           // Call the super handler, which handlers the enter key.
    >           super.onBrowserEvent(context, parent, value, event, valueUpdater);

    >           // On click, perform the same action that we perform on enter.
    >           if ("click".equals(event.getType())) {
    >             this.onEnterKeyDown(context, parent, value, event, valueUpdater);
    >           }
    >         }

    >         @Override
    >         public void render(Context context, Contact value, SafeHtmlBuilder sb) {
    >           /*
    >            * Always do a null check on the value. Cell widgets can pass null to
    >            * cells if the underlying data contains a null, or if the data arrives
    >            * out of order.
    >            */
    >           if (value == null) {
    >             return;
    >           }

    >           // Display the name in big letters.
    >           sb.appendHtmlConstant("<div style=\"size:200%;font-weight:bold;\">");
    >           sb.appendEscaped(value.name);
    >           sb.appendHtmlConstant("</div>");

    >           // Display the address in normal text.
    >           sb.appendHtmlConstant("<div style=\"padding-left:10px;\">");
    >           sb.appendEscaped(value.address);
    >           sb.appendHtmlConstant("</div>");

    >           // Format that birthday and display it in light gray.
    >           sb.appendHtmlConstant("<div style=\"padding-left:10px;color:#aaa;\">");
    >           sb.append(SafeHtmlUtils.fromTrustedString("Born: "));
    >           sb.appendEscaped(dateFormat.format(value.birthday));
    >           sb.appendHtmlConstant("</div>");
    >         }

    >         /**
    >          * By convention, cells that respond to user events should handle the enter
    >          * key. This provides a consistent user experience when users use keyboard
    >          * navigation in the widget.
    >          */
    >         @Override
    >         protected void onEnterKeyDown(Context context, Element parent,
    >             Contact value, NativeEvent event, ValueUpdater<Contact> valueUpdater) {
    >           Window.alert("You clicked " + value.name);
    >         }
    >       }

    >       /**
    >        * The list of data to display.
    >        */
    >       private static final List<Contact> CONTACTS = Arrays.asList(new Contact(
    >           "John", new Date(80, 4, 12), "123 Fourth Avenue"), new Contact("Joe",
    >           new Date(85, 2, 22), "22 Lance Ln"), new Contact("Michael", new Date(80,
    >           1, 2), "1283 Berry Blvd"), new Contact("Sarah", new Date(67, 10, 28),
    >           "100 Hundred St."), new Contact("George", new Date(46, 6, 6),
    >           "1600 Pennsylvania Avenue"));

    >       public void onModuleLoad() {
    >         // Create a cell to render each value.
    >         ContactCell contactCell = new ContactCell();

    >         // Use the cell in a CellList.
    >         CellList<Contact> cellList = new CellList<Contact>(contactCell);

    >         // Push the data into the widget.
    >         cellList.setRowData(0, CONTACTS);

    >         // Add it to the root panel.
    >         RootPanel.get().add(cellList);
    >       }
    >     }

  Editable cell

    >     public class EditableCellExample implements EntryPoint {

    >       /**
    >        * A simple data type that represents a contact.
    >        */
    >       private static class Contact {
    >         private final String address;
    >         private final String name;

    >         public Contact(String name, String address) {
    >           this.name = name;
    >           this.address = address;
    >         }
    >       }

    >       /**
    >        * A custom {@link Cell} used to render a {@link Contact}. We extend
    >        * {@link AbstractCell} because it provides reasonable implementations of
    >        * methods that work for most use cases.
    >        */
    >       private class ContactCell extends AbstractCell<Contact> {

    >         public ContactCell() {
    >           // Our cell responds to change events and keydown events.
    >           super("change", "keydown");
    >         }

    >         @Override
    >         public void onBrowserEvent(Context context, Element parent, Contact value,
    >             NativeEvent event, ValueUpdater<Contact> valueUpdater) {
    >           // Check that the value is not null.
    >           if (value == null) {
    >             return;
    >           }

    >           // Call the super handler, which handlers the enter key.
    >           super.onBrowserEvent(context, parent, value, event, valueUpdater);

    >           // Handle click events.
    >           if ("change".equals(event.getType())) {
    >             updateFavorites(parent, value);
    >             showCurrentFavorites();
    >           }
    >         }

    >         @Override
    >         public void render(Context context, Contact value, SafeHtmlBuilder sb) {
    >           /*
    >            * Always do a null check on the value. Cell widgets can pass null to
    >            * cells if the underlying data contains a null, or if the data arrives
    >            * out of order.
    >            */
    >           if (value == null) {
    >             return;
    >           }

    >           // Add a checkbox. If the contact is a favorite, the box will be checked.
    >           sb.appendHtmlConstant("<table><tr><td valign=\"top\">");
    >           if (favorites.contains(value)) {
    >             sb.appendHtmlConstant("<input type=\"checkbox\" checked=checked/>");
    >           } else {
    >             sb.appendHtmlConstant("<input type=\"checkbox\" />");
    >           }
    >           sb.appendHtmlConstant("</td><td>");

    >           // Display the name in big letters.
    >           sb.appendHtmlConstant("<div style=\"size:200%;font-weight:bold;\">");
    >           sb.appendEscaped(value.name);
    >           sb.appendHtmlConstant("</div>");

    >           // Display the address in normal text.
    >           sb.appendHtmlConstant("<div style=\"padding-left:10px;\">");
    >           sb.appendEscaped(value.address);
    >           sb.appendHtmlConstant("</div>");

    >           sb.appendHtmlConstant("</td></tr></table>");
    >         }

    >         /**
    >          * By convention, cells that respond to user events should handle the enter
    >          * key. This provides a consistent user experience when users use keyboard
    >          * navigation in the widget. Our cell will toggle the checkbox on Enter.
    >          */
    >         @Override
    >         protected void onEnterKeyDown(Context context, Element parent,
    >             Contact value, NativeEvent event, ValueUpdater<Contact> valueUpdater) {
    >           // Toggle the checkbox.
    >           InputElement input = getInputElement(parent);
    >           input.setChecked(!input.isChecked());

    >           // Update the favorites based on the new state.
    >           updateFavorites(parent, value);

    >           // Show the new list of favorites.
    >           showCurrentFavorites();
    >         }

    >         /**
    >          * Get the checkbox input element from the parent element that wraps our
    >          * cell.
    >          *
    >          * @param parent the parent element
    >          * @return the checkbox
    >          */
    >         private InputElement getInputElement(Element parent) {
    >           // We need to navigate down to our input element.
    >           TableElement table = parent.getFirstChildElement().cast();
    >           TableRowElement tr = table.getRows().getItem(0);
    >           TableCellElement td = tr.getCells().getItem(0);
    >           InputElement input = td.getFirstChildElement().cast();
    >           return input;
    >         }

    >         /**
    >          * Update the favorites list based on the state of the input element.
    >          */
    >         private void updateFavorites(Element parent, Contact value) {
    >           // Get the input element.
    >           InputElement input = getInputElement(parent);

    >           // Update the favorites based on the checked state.
    >           if (input.isChecked()) {
    >             favorites.add(value);
    >           } else {
    >             favorites.remove(value);
    >           }
    >         }
    >       }

    >       /**
    >        * The list of data to display.
    >        */
    >       private static final List<Contact> CONTACTS = Arrays.asList(new Contact(
    >           "John", "123 Fourth Avenue"), new Contact("Joe", "22 Lance Ln"),
    >           new Contact("Michael", "1283 Berry Blvd"), new Contact("Sarah",
    >               "100 Hundred St."), new Contact("George", "1600 Pennsylvania Avenue"));

    >       /**
    >        * Our list of favorite contacts.
    >        */
    >       private final List<Contact> favorites = new ArrayList<EditableCellExample.Contact>();

    >       public void onModuleLoad() {
    >         // Create a cell to render each value.
    >         ContactCell contactCell = new ContactCell();

    >         // Use the cell in a CellList.
    >         CellList<Contact> cellList = new CellList<Contact>(contactCell);

    >         // Push the data into the widget.
    >         cellList.setRowData(0, CONTACTS);

    >         // Add it to the root panel.
    >         RootPanel.get().add(cellList);
    >       }

    >       /**
    >        * Show the list of favorites.
    >        */
    >       private void showCurrentFavorites() {
    >         if (favorites.size() > 0) {
    >           String text = "You favorite contacts are ";
    >           boolean first = true;
    >           for (Contact contact : favorites) {
    >             if (!first) {
    >               text += ", ";
    >             } else {
    >               first = false;
    >             }
    >             text += contact.name;
    >           }
    >           Window.alert(text);
    >         } else {
    >           Window.alert("You have not selected any favorites.");
    >         }
    >       }
    >     }

- - ### Nested Class Summary

    - ### Nested classes/interfaces inherited from interface com.google.gwt.cell.client.Cell

      `Cell.Context`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `AbstractCell(java.util.Set<java.lang.String> consumedEvents)` Construct a new `AbstractCell` with the specified consumed events.
    `AbstractCell(java.lang.String... consumedEvents)` Construct a new `AbstractCell` with the specified consumed events.

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `boolean` | `dependsOnSelection()` Check if this cell depends on the selection state.
    `java.util.Set<java.lang.String>` | `getConsumedEvents()` Get the set of events that this cell consumes (see `BrowserEvents` for useful constants).
    `boolean` | `handlesSelection()` Check if this cell handles selection.
    `boolean` | `isEditing(Cell.Context context, Element parent, C value)` Returns false.
    `void` | `onBrowserEvent(Cell.Context context, Element parent, C value, NativeEvent event, ValueUpdater<C> valueUpdater)` Handle a browser event that took place within the cell.
    `protected void` | `onEnterKeyDown(Cell.Context context, Element parent, C value, NativeEvent event, ValueUpdater<C> valueUpdater)` Called when the user triggers a `keydown` event with the ENTER key while focused on the cell.
    `abstract void` | `render(Cell.Context context, C value, SafeHtmlBuilder sb)` Render a cell as HTML into a `SafeHtmlBuilder`, suitable for passing to `Element.setInnerHTML(String)` on a container element.
    `boolean` | `resetFocus(Cell.Context context, Element parent, C value)` Reset focus on the Cell.
    `void` | `setValue(Cell.Context context, Element parent, C value)` This method may be used by cell containers to set the value on a single cell directly, rather than using `Element.setInnerHTML(String)`.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### AbstractCell

          public AbstractCell(java.lang.String... consumedEvents)

      Construct a new `AbstractCell` with the specified consumed events. The input arguments are passed by copy.
      Parameters:
        `consumedEvents` - the `events` that this cell consumes
      See Also:
        `BrowserEvents`

    - #### AbstractCell

          public AbstractCell(java.util.Set<java.lang.String> consumedEvents)

      Construct a new `AbstractCell` with the specified consumed events.
      Parameters:
        `consumedEvents` - the events that this cell consumes

  - ### Method Detail

    - #### dependsOnSelection

          public boolean dependsOnSelection()

      Description copied from interface: `Cell`
      Check if this cell depends on the selection state.
      Specified by:
        `dependsOnSelection` in interface `Cell<C>`
      Returns:
        true if dependent on selection, false if not

    - #### getConsumedEvents

          public java.util.Set<java.lang.String> getConsumedEvents()

      Description copied from interface: `Cell`
      Get the set of events that this cell consumes (see `BrowserEvents` for useful constants). The container that uses this cell should only pass these events to `Cell.onBrowserEvent(Context, Element, Object, NativeEvent, ValueUpdater)` when the event occurs.

      The returned value should not be modified, and may be an unmodifiable set. Changes to the return value may not be reflected in the cell.

      Specified by:
        `getConsumedEvents` in interface `Cell<C>`
      Returns:
        the consumed events, or null if no events are consumed
      See Also:
        `BrowserEvents`

    - #### handlesSelection

          public boolean handlesSelection()

      Description copied from interface: `Cell`
      Check if this cell handles selection. If the cell handles selection, then its container should not automatically handle selection.
      Specified by:
        `handlesSelection` in interface `Cell<C>`
      Returns:
        true if the cell handles selection, false if not

    - #### isEditing

          public boolean isEditing(Cell.Context context,
                          Element parent,
                          C value)

      Returns false. Subclasses that support editing should override this method to return the current editing status.
      Specified by:
        `isEditing` in interface `Cell<C>`
      Parameters:
        `context` - the `Cell.Context` of the cell
        `parent` - the parent Element
        `value` - the value associated with the cell
      Returns:
        true if the cell is in edit mode

    - #### onBrowserEvent

          public void onBrowserEvent(Cell.Context context,
                            Element parent,
                            C value,
                            NativeEvent event,
                            ValueUpdater<C> valueUpdater)

      Handle a browser event that took place within the cell. The default implementation returns null.

      If you override this method to add support for events, remember to pass the event types that the cell expects into the constructor.

      Specified by:
        `onBrowserEvent` in interface `Cell<C>`
      Parameters:
        `context` - the `Cell.Context` of the cell
        `parent` - the parent Element
        `value` - the value associated with the cell
        `event` - the native browser event
        `valueUpdater` - a `ValueUpdater`, or null if not specified

    - #### render

          public abstract void render(Cell.Context context,
                    C value,
                    SafeHtmlBuilder sb)

      Description copied from interface: `Cell`
      Render a cell as HTML into a `SafeHtmlBuilder`, suitable for passing to `Element.setInnerHTML(String)` on a container element.

      Note: If your cell contains natively focusable elements, such as buttons or input elements, be sure to set the tabIndex to -1 so that they do not steal focus away from the containing widget.

      Specified by:
        `render` in interface `Cell<C>`
      Parameters:
        `context` - the `Cell.Context` of the cell
        `value` - the cell value to be rendered
        `sb` - the `SafeHtmlBuilder` to be written to

    - #### resetFocus

          public boolean resetFocus(Cell.Context context,
                           Element parent,
                           C value)

      Reset focus on the Cell. This method is called if the cell has focus when it is refreshed.

      This method is a no-op and returns false. If your cell is editable or can be focused by the user, override this method to reset focus when the containing widget is refreshed.

      Specified by:
        `resetFocus` in interface `Cell<C>`
      Parameters:
        `context` - the `Cell.Context` of the cell
        `parent` - the parent Element
        `value` - the value associated with the cell
      Returns:
        true if focus is taken, false if not

    - #### setValue

          public void setValue(Cell.Context context,
                      Element parent,
                      C value)

      Description copied from interface: `Cell`
      This method may be used by cell containers to set the value on a single cell directly, rather than using `Element.setInnerHTML(String)`. See `Cell.setValue(Context, Element, Object)` for a default implementation that uses `Cell.render(Context, Object, SafeHtmlBuilder)`.
      Specified by:
        `setValue` in interface `Cell<C>`
      Parameters:
        `context` - the `Cell.Context` of the cell
        `parent` - the parent Element
        `value` - the value associated with the cell

    - #### onEnterKeyDown

          protected void onEnterKeyDown(Cell.Context context,
                            Element parent,
                            C value,
                            NativeEvent event,
                            ValueUpdater<C> valueUpdater)

      Called when the user triggers a `keydown` event with the ENTER key while focused on the cell. If your cell interacts with the user, you should override this method to provide a consistent user experience. Your widget must consume `keydown` events for this method to be called.
      Parameters:
        `context` - the `Context` of the cell
        `parent` - the parent Element
        `value` - the value associated with the cell
        `event` - the native browser event
        `valueUpdater` - a `ValueUpdater`, or null if not specified