title: GWT: handling event in composite cell
body: <p>CompositeCell let us customize the content of a table cell's in GWT using Java. We can put almost any other group of widget within the table's cell and layout them as we want. Problem is that if we used the html tags to define the layout of the CompositeCell as yet another table (see CompositeCell anonymous class implementation bellow) we loose the event handling for the components of the cell :(.</p>
  
  <p>Running the following code, when we click in the buttons of the cell will realize the popup in response of the event handling IF WE COMMENT the CompositeCell anonymous implementation. </p>
  
  <p>I've been debugging CompositeCell.onBrowserEvent(Context, Element, C, NativeEvent, ValueUpdater) because i think that the definition of the cell layout using HTML table tags breaks the event chain within GWT widgets hierarchy but haven't been successful so far.</p>
  
  <p>Remark: both commented and uncommented versions of the code realize the same GUI layout. This example just intent to show that we loose event handling when customizing cell's content.</p>
  
  <pre><code>public class ActionCellTest implements EntryPoint {
  
      private static final String SERVER_ERROR = "An error occurred while " + "attempting to contact the server. Please check your network "
              + "connection and try again.";
  
      private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
  
      public void onModuleLoad() {
          CellTable&lt;Person&gt; table = new CellTable&lt;ActionCellTest.Person&gt;();
  
          final List&lt;HasCell&lt;Person, ?&gt;&gt; cells = new LinkedList&lt;HasCell&lt;Person, ?&gt;&gt;();
          cells.add(new HasCellImpl("first name", new ActionCell.Delegate&lt;Person&gt;() {
  
              @Override
              public void execute(Person object) {
                  Window.alert(object.getFirstName());
              }
          }));
          cells.add(new HasCellImpl("last name", new ActionCell.Delegate&lt;ActionCellTest.Person&gt;() {
  
              @Override
              public void execute(Person object) {
                  Window.alert(object.getLastName());
              }
          }));
  
          CompositeCell&lt;Person&gt; cell = new CompositeCell&lt;Person&gt;(cells) {
  
              @Override
              public void render(Context context, Person value, SafeHtmlBuilder sb) {
                  sb.appendHtmlConstant("&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;");
                  for (HasCell&lt;Person, ?&gt; hasCell : cells) {
                      render(context, value, sb, hasCell);
                  }
                  sb.appendHtmlConstant("&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;");
              }
  
              @Override
              protected &lt;X&gt; void render(Context context, Person value, SafeHtmlBuilder sb, HasCell&lt;Person, X&gt; hasCell) {
                  Cell&lt;X&gt; cell = hasCell.getCell();
                  sb.appendHtmlConstant("&lt;td&gt;");
                  cell.render(context, hasCell.getValue(value), sb);
                  sb.appendHtmlConstant("&lt;/td&gt;");
              }
  
              @Override
              protected Element getContainerElement(Element parent) {
                  return parent.getFirstChildElement().getFirstChildElement().getFirstChildElement();
              }
  
          };
          table.addColumn(new TextColumn&lt;ActionCellTest.Person&gt;() {
  
              @Override
              public String getValue(ActionCellTest.Person object) {
                  return object.getFirstName() + " " + object.getLastName();
              }
          }, "name");
  
          table.addColumn(new Column&lt;Person, Person&gt;(cell) {
  
              @Override
              public Person getValue(ActionCellTest.Person object) {
                  return object;
              }
          }, "composite");
  
          LinkedList&lt;Person&gt; data = new LinkedList&lt;ActionCellTest.Person&gt;();
          data.add(new Person("Amy", "Reed"));
          data.add(new Person("Tim", "Gardner"));
          table.setRowData(data);
  
          RootPanel.get().add(table);
      }
  
      private class HasCellImpl implements HasCell&lt;Person, Person&gt; {
          private ActionCell&lt;Person&gt; fCell;
  
          public HasCellImpl(String text, Delegate&lt;Person&gt; delegate) {
              fCell = new ActionCell&lt;Person&gt;(text, delegate);
          }
  
          @Override
          public Cell&lt;Person&gt; getCell() {
              return fCell;
          }
  
          @Override
          public FieldUpdater&lt;Person, Person&gt; getFieldUpdater() {
              return null;
          }
  
          @Override
          public Person getValue(Person object) {
              return object;
          }
      }
  
      private class Person {
          private String fFirstName;
          private String fLastName;
  
          public Person(String first, String last) {
              fFirstName = first;
              fLastName = last;
          }
  
          public String getFirstName() {
              return fFirstName;
          }
  
          public String getLastName() {
              return fLastName;
          }
      }
  }
  </code></pre>