Zecas
Zecas

Reputation: 647

GWT: handling event in composite cell

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 :(.

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.

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.

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.

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<Person> table = new CellTable<ActionCellTest.Person>();

        final List<HasCell<Person, ?>> cells = new LinkedList<HasCell<Person, ?>>();
        cells.add(new HasCellImpl("first name", new ActionCell.Delegate<Person>() {

            @Override
            public void execute(Person object) {
                Window.alert(object.getFirstName());
            }
        }));
        cells.add(new HasCellImpl("last name", new ActionCell.Delegate<ActionCellTest.Person>() {

            @Override
            public void execute(Person object) {
                Window.alert(object.getLastName());
            }
        }));

        CompositeCell<Person> cell = new CompositeCell<Person>(cells) {

            @Override
            public void render(Context context, Person value, SafeHtmlBuilder sb) {
                sb.appendHtmlConstant("<table><tbody><tr>");
                for (HasCell<Person, ?> hasCell : cells) {
                    render(context, value, sb, hasCell);
                }
                sb.appendHtmlConstant("</tr></tbody></table>");
            }

            @Override
            protected <X> void render(Context context, Person value, SafeHtmlBuilder sb, HasCell<Person, X> hasCell) {
                Cell<X> cell = hasCell.getCell();
                sb.appendHtmlConstant("<td>");
                cell.render(context, hasCell.getValue(value), sb);
                sb.appendHtmlConstant("</td>");
            }

            @Override
            protected Element getContainerElement(Element parent) {
                return parent.getFirstChildElement().getFirstChildElement().getFirstChildElement();
            }

        };
        table.addColumn(new TextColumn<ActionCellTest.Person>() {

            @Override
            public String getValue(ActionCellTest.Person object) {
                return object.getFirstName() + " " + object.getLastName();
            }
        }, "name");

        table.addColumn(new Column<Person, Person>(cell) {

            @Override
            public Person getValue(ActionCellTest.Person object) {
                return object;
            }
        }, "composite");

        LinkedList<Person> data = new LinkedList<ActionCellTest.Person>();
        data.add(new Person("Amy", "Reed"));
        data.add(new Person("Tim", "Gardner"));
        table.setRowData(data);

        RootPanel.get().add(table);
    }

    private class HasCellImpl implements HasCell<Person, Person> {
        private ActionCell<Person> fCell;

        public HasCellImpl(String text, Delegate<Person> delegate) {
            fCell = new ActionCell<Person>(text, delegate);
        }

        @Override
        public Cell<Person> getCell() {
            return fCell;
        }

        @Override
        public FieldUpdater<Person, Person> 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;
        }
    }
}

Upvotes: 3

Views: 2673

Answers (1)

Thomas Broyer
Thomas Broyer

Reputation: 64561

This is a known issue which will be fixed in the upcoming GWT 2.5 (a matter of weeks): http://code.google.com/p/google-web-toolkit/issues/detail?id=5714
(in the mean time, you can run off trunk or try backporting the change)

Upvotes: 2

Related Questions