(Addendum: Thomas's answer beat me to it, but since I noticed it after
writing this post, I will post my answer anyway ;) )

I did not have a dev environment setup when I posted this, so did not
test this. I obviously should have, because I did not see the
recursion in what I was trying to do.

As you guessed it, the problem is that we want to inject the same
Display interface (MyPresenter.Display) in two different places:
- in the view, where we want Gin to use the @Provides factory method
(which creates a new view, injects it into a new presenter, and
returns the view)
- in the presenter, where we do NOT want to call the @Provides method,
but instead bind MyPresenter.Display to MyPresenterView in the
"standard" way.

Guice's private modules would have solved this problem elegantly but
they are not yet available in Gin:
http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/PrivateModule.html

Here is what I did instead:

I took as a basis the example project from this good gwt-presenter
tutorial: 
http://blog.hivedevelopment.co.uk/2009/08/google-web-toolkit-gwt-mvp-example.html


I created a new Guice binding annotation:

@BindingAnnotation
@Target( { FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface ViewForPresenter {
}

----------------

I created a new presenter:

public class TestPresenter extends
WidgetPresenter<TestPresenter.Display> {
    public interface Display extends WidgetDisplay {
        HasClickHandlers getTestButton();
    }

    // Notice the @ViewForPresenter annotation here
    @Inject
    public TestPresenter(@ViewForPresenter Display display, EventBus
eventBus) {
        super(display, eventBus);
        Log.info("TestPresenter created");
        bind();
    }

    @Override
    protected void onBind() {
        registerHandler(display.getTestButton().addClickHandler(new
ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                Window.alert("Button clicked!");
            }
        }));
    }

    @Override
    protected void onUnbind() {
    }

    public void refreshDisplay() {
    }

    public void revealDisplay() {
    }

    public static final Place PLACE = null;

    @Override
    public Place getPlace() {
        return PLACE;
    }

    @Override
    protected void onPlaceRequest(final PlaceRequest request) {
    }
}

----------------

And its view:

public class TestView extends VerticalPanel implements
TestPresenter.Display {

    private final Button testButton;

    @Inject
    public TestView() {
        Log.info("TestView created");
        testButton = new Button("Test");
        add(testButton);
    }

    @Override
    public HasClickHandlers getTestButton() {
        return testButton;
    }

    public Widget asWidget() {
        return this;
    }

    @Override
    public void startProcessing() {
    }

    @Override
    public void stopProcessing() {
    }
}

----------------

Updated the module:


public class GreetingClientModule extends AbstractPresenterModule {

    @Override
    protected void configure() {
        [...]

        bind(TestPresenter.class);
        // First binding for TestPresenter.Display, which will be used
when we use the @ViewForPresenter annotation
        bind(TestPresenter.Display.class).annotatedWith
(ViewForPresenter.class).to(TestView.class);
    }

    // Second binding for TestPresenter.Display, which will be used
when no annotation is present
    @Provides
    TestPresenter.Display provideTestView(TestPresenter testPresenter)
{
        testPresenter.bind();
        return testPresenter.getDisplay();
    }
}

----------------

And modified the GreetingView to inject TestView and show it:

public class GreetingView extends Composite implements
GreetingPresenter.Display {
    [...]

    @Inject
    public GreetingView(TestPresenter.Display testView) {
        Log.info("GreetingView created");
        final FlowPanel panel = new FlowPanel();
        panel.add(testView.asWidget());

        [...]

----------------


And voila:

2009-08-28 13:48:10,068 [INFO ] TestView created
2009-08-28 13:48:10,120 [INFO ] TestPresenter created
2009-08-28 13:48:10,131 [INFO ] GreetingView created
2009-08-28 13:48:10,219 [INFO ] GreetingPresenter created



Now, if you inject TestView anywhere in your application, it will
instantiate a new Presenter/View.



Regards,

Etienne

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to