0
votes

I'm using GWT 2.4, SmartGWT 3.0, GWTP 0.7.

I mostly try to stick with SmartGWT widgets for my layout, but I'm trying to add a GWT widget (can be anything from a MapWidget to a ChartWidget from HighCharts or a GWT label) to a tab in the SmartGWT tabset. Then I get the following exception:

Caused by: java.lang.AssertionError: A widget that has an existing parent widget may not be added to the detach list

This only happens in Dev mode. In production the assertions have been turned off, and my widgets do show up, but it makes it impossible to debug in Dev mode. As I understand it is because I'm mixing SmartGWT and GWT widgets.

Before GWTP, I was able to make this work, because to show my UI I would call draw() on my root layout, which was a VLayout. Now that I'm using GWTP, it will show my layout for me when I fire the RevealRootContentEvent, and it will add the layout by calling RootPanel.get().add(...), which I think is the reason why I'm having these problems now. All my layouts are still in SmartGWT.

Has anyone experienced the same issues (in the same setup) and how can this be handled?

1
can't you get rid of the RootPanel.get().add() and just use the draw method ? Your problem is directly related to the RootPanel.get().add() callJean-Michel Garcia
I'm not calling RootPanel.get().add() directly. This is done in GWTP's RootPresenter.setInSlot. I guess your suggestion is to clone the GWTP source, and make my own custom version?Rasmus Nielsen
Why don't override setinslot then ?Jean-Michel Garcia
I'm not sure how I can do that. I have my LoginPresenter which extends Presenter<>. Here I can override setInSlot(Object slot, PresenterWidget<?> content), but this method is never invoked. Same with the LoginView, which is extending from ViewImpl. Here I can override setInSlot(Object slot, Widget content), but this one is also never invoked.Rasmus Nielsen
...or did u refer to cloning the GWTP src and override setInSlot there? (because now Im trying to override that particular method in my own code, which is using the original gwtp src)Rasmus Nielsen

1 Answers

3
votes

So I think I got to the bottom of my problem.

I read this issue http://code.google.com/p/gwt-platform/issues/detail?id=127

In one of the posts, it is shown how to create a custom RootPresenter. The RootPresenter also contains a RootView, where the aforementioned setInSlot method is placed, and by writing a custom view, it is possible to override that method, and make sure that draw() is invoked on SmartGWT layouts, rather than being added in RootPanel.get().add(...);

My impl looks like this:

public class CustomRootPresenter extends RootPresenter
{
    public static final class CustomRootView extends RootView
    {
        @Override
        public void setInSlot(Object slot, Widget content)
        {
            if (content instanceof Layout)
            {
                // clear
                RootLayoutPanel.get().clear();
                RootPanel.get().clear();

                Layout layout = (Layout) content;
                layout.draw();
            }
            else
            {
                super.setInSlot(slot, content);
            }
        }
    }

    @Inject
    public CustomRootPresenter(EventBus eventBus, CustomRootView myRootView)
    {
        super(eventBus, myRootView);
    }
}

Remember to inject the custom root presenter in your GIN module:

// don't use install, when using custom RootPresenter
// install(new DefaultModule(ClientPlaceManager.class));

bind(EventBus.class).to(SimpleEventBus.class).in(Singleton.class);
bind(TokenFormatter.class).to(ParameterTokenFormatter.class).in(Singleton.class);
bind(CustomRootPresenter.class).asEagerSingleton();
bind(PlaceManager.class).to(ClientPlaceManager.class).in(Singleton.class);
bind(GoogleAnalytics.class).to(GoogleAnalyticsImpl.class).in(Singleton.class);

It definitely solved my problem with adding GWT widgets to SmartGWT layouts.

Thanks to Jean-Michel Garcia for pushing me in the right direction! :)