0

Im using GWTP, working on their tab panel example. My issue is i need to demonstrate taking a search term and adding a new tab to the tab panel with the search results. So if i search 5 times, i have 5 tabs. easy enough, so i thought.

Gin is used extensively in GWTP. So my method to add a new tab, which should be something as simple as

tabPanel.addTab(new SearchDataGridView(), NameTokens.searchPage + 1);

gets confusing because of the constructor for the SearchDataGridView class

@Inject
    SearchDataGridView(Binder uiBinder) {
        employeeDataProvider = new ListDataProvider<Employee>();

        initSearchGrid();

        initWidget(uiBinder.createAndBindUi(this));
    }

yea, i know im not passing the search term yet, im still trying to get the tab to open.

My gin config is this

bindPresenter(
                SearchDataGridPresenter.class,
                SearchDataGridPresenter.MyView.class,
                SearchDataGridView.class,
                SearchDataGridPresenter.MyProxy.class);

The gwtp gin config

@Override
    protected void configure() {
        // RestDispatchAsyncModule.Builder dispatchBuilder = new RestDispatchAsyncModule.Builder();
        // install(dispatchBuilder.build());
        // install(new RestDispatchAsyncModule.Builder().build());

        install(new DefaultModule(DefaultPlaceManager.class));
        install(new ApplicationModule());

        bind(CurrentUser.class).in(Singleton.class);
        bind(IsAdminGatekeeper.class).in(Singleton.class);

        // DefaultPlaceManager Constants
        bindConstant().annotatedWith(DefaultPlace.class).to(NameTokens.homeNewsPage);
        bindConstant().annotatedWith(ErrorPlace.class).to(NameTokens.homeNewsPage);
        bindConstant().annotatedWith(UnauthorizedPlace.class).to(NameTokens.homeNewsPage);
        bindConstant().annotatedWith(Names.named("rest")).to("http://localhost/services");
        // Google Analytics
        // bindConstant().annotatedWith(GaAccount.class).to("UA-8319339-6");

        // Load and inject CSS resources
        bind(ResourceLoader.class).asEagerSingleton();
    }

How do i pull this off?

thanks

Using comments below, sorta got it working. The problem is i can't get the contents of the tab to display. I added debugging code to the setInSlot method of my SearchContainer class and realized that whenever i click the search tab, it fires this setInSlot method, but its fired with my default page presenter listed as content.

@Override
    public void setInSlot(Object slot, IsWidget content) {
        Window.alert("fired setInSlot: " + slot.toString());
        Window.alert("fired setInSlot: " + content.toString());
        if (slot == ApplicationPresenter.TYPE_SetTabContent) {
            tabPanel.setPanelContent(content);
        } else {
            super.setInSlot(slot, content);
        }
    }

Thats the method im using to get my info. Its weird that the tab appears properly, the jsonRPC calls that are built into the view are executed properly, it just doesn't display.

My main container presenter has its view and proxy identified by this

public class ApplicationPresenter
        extends
        TabContainerPresenter<ApplicationPresenter.MyView, ApplicationPresenter.MyProxy> implements
        CurrentUserChangedHandler, AsyncCallStartHandler, AsyncCallFailHandler, AsyncCallSucceedHandler,
        ApplicationUiHandler {
    /**
     * {@link ApplicationPresenter}'s proxy.
     */
    @ProxyStandard
    public interface MyProxy extends Proxy<ApplicationPresenter> {
    }

    /**
     * {@link ApplicationPresenter}'s view.
     */
    public interface MyView extends TabView, HasUiHandlers<ApplicationUiHandler> {
        void refreshTabs();

        void setTopMessage(String string);
    }

Could my issue be with my content type? Here is what i have defined for all my types

/**
     * This will be the event sent to our "unknown" child presenters, in order for them to register their tabs.
     */
    @RequestTabs
    public static final Type<RequestTabsHandler> TYPE_RequestTabs = new Type<RequestTabsHandler>();

    /**
     * Fired by child proxie's when their tab content is changed.
     */
    @ChangeTab
    public static final Type<ChangeTabHandler> TYPE_ChangeTab = new Type<ChangeTabHandler>();

    /**
     * Use this in leaf presenters, inside their {@link #revealInParent} method.
     */
    @ContentSlot
    public static final Type<RevealContentHandler<?>> TYPE_SetTabContent = new Type<RevealContentHandler<?>>();
scphantm
  • 4,293
  • 8
  • 43
  • 77

3 Answers3

1

The proper way to do this is to use a PresenterWidget and a Provider.

In your ClientModule you define this:

bindPresenterWidget(SearchDataGridPresenter.class, SearchDataGridPresenter.MyView.class, SearchDataGridView.class);

In your Presenter that adds the SearchDataGridView you inject a Provider:

@Inject
public SeachContainerPresenter(final Provider<SearchDataGridPresenter> seachDataGridProvider) {
}

For each search you call addToSlot(TYPE_SetSearchDataGridContent,seachDataGridProvider.get()) in your SearchContainerPresenter.

In the SearchContainerView you override the addToSlot() method:

@Override
public void addToSlot(Object slot,Widget content) {
    if (slot == SeachContainerPresenter.TYPE_SetSearchDataGridContent) {
        tabPanel.addTab(content, NameTokens.searchPage + 1);
    }
    else {
        super.addToSlot(slot,content);
    } 
}
Ümit
  • 17,379
  • 7
  • 55
  • 74
  • beautiful. This adds the tab just great. Problem is now I can't click on them. I see the logs where its created, i see the logs where it calls my rest service, the tab appears in the tab panel, but when I click on it, i get the correct placetoken in the address bar and it goes to the default tab. It never displays the new tab. I changed the code that does the placetoken a bit, `getView().addTab(p, NameTokens.searchPage + iCount); ++iCount;` – scphantm Dec 05 '13 at 11:07
  • I am not sure I understand. `TabPanel` usually doesn't really work with a placetoken. Or are you using a `TabContainerPresenter` ? – Ümit Dec 05 '13 at 12:27
  • im using the RoundTabPanel widget from the tab example. It uses placetokens. all i did was copy the tab example into my project and start adding the code for my new tabs. – scphantm Dec 05 '13 at 12:34
  • Maybe its my content type? I pasted what everything uses above. – scphantm Dec 05 '13 at 14:10
  • If you have dynamic tabs I would rather recommend against using a `TabPresenter`. Usually `TabPresenter` are known during compile time. It's possible to have dynamic tabs (both with dynamic places and dynamic number of tabs) however you have to use special custom tab info. In your case I would recommend to use `PresenterWidget`s and just use a normal `TabPanel` and handling the display of the correct TabContent based on the token by your parent `Presenter` – Ümit Dec 05 '13 at 14:35
0

Look in binding everything together. I think that you have to add the AsyncProvider of your presenter to yuor Ginjector.

AsyncProvider<SearchDataGridPresenter> getSearchDataGridPresenter();
vjrj
  • 121
  • 1
  • 4
0

You can put a SearchDataGridView getSearchDataGridView() method in the GIN Injector and call it in order to obtain the SearchDataGridView instance.

Fedy2
  • 3,147
  • 4
  • 26
  • 44
  • ok, but how do i call it? tabPanel.addTab(getSearchDataGridView(), NameTokens.searchPage + 1); gives me a compile error saying it can't find the method. – scphantm Dec 05 '13 at 08:30
  • You have to get the Injector instance and call his method. – Fedy2 Dec 05 '13 at 08:35