Class AbstractEditableCell<C,​V>

  • Type Parameters:
    C - the type that this Cell represents
    V - the data type of the view data state
    All Implemented Interfaces:
    Cell<C>
    Direct Known Subclasses:
    AbstractInputCell, CheckboxCell, DatePickerCell, EditTextCell

    public abstract class AbstractEditableCell<C,​V>
    extends AbstractCell<C>
    A default implementation of the Cell interface used for editable cells that need to save view data state for specific values.

    Example

    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.");
        }
      }
    }
    

    • Constructor Detail

      • AbstractEditableCell

        public AbstractEditableCell​(java.lang.String... consumedEvents)
        Construct a new AbstractEditableCell with the specified consumed events.
        Parameters:
        consumedEvents - the events that this cell consumes
      • AbstractEditableCell

        public AbstractEditableCell​(java.util.Set<java.lang.String> consumedEvents)
        Construct a new AbstractEditableCell with the specified consumed events.
        Parameters:
        consumedEvents - the events that this cell consumes
    • Method Detail

      • clearViewData

        public void clearViewData​(java.lang.Object key)
        Clear the view data associated with the specified key.
        Parameters:
        key - the key identifying the row value
      • getViewData

        public V getViewData​(java.lang.Object key)
        Get the view data associated with the specified key.
        Parameters:
        key - the key identifying the row object
        Returns:
        the view data, or null if none has been set
        See Also:
        setViewData(Object, Object)
      • isEditing

        public abstract boolean isEditing​(Cell.Context context,
                                          Element parent,
                                          C value)
        Returns true if the cell is currently editing the data identified by the given element and key. While a cell is editing, widgets containing the cell may choose to pass keystrokes directly to the cell rather than using them for navigation purposes.
        Specified by:
        isEditing in interface Cell<C>
        Overrides:
        isEditing in class AbstractCell<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
      • setViewData

        public void setViewData​(java.lang.Object key,
                                V viewData)
        Associate view data with the specified key. If the key is null, the view data will be ignored.
        Parameters:
        key - the key of the view data
        viewData - the view data to associate
        See Also:
        getViewData(Object)