create new instance of class that is managed by gin

625 views Asked by At

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<?>>();
3

There are 3 answers

0
vjrj On

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

AsyncProvider<SearchDataGridPresenter> getSearchDataGridPresenter();
5
Ümit On

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);
    } 
}
2
Fedy2 On

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