For example if I've a tipical application with header,sidebar,content,
maybe I'll make at least 3 template (ui.xml).
So the App.ui.xml could be something as:
<g:DockLayoutPanel unit='PX'>
<g:north size='121'>
<my:Header></my:Header>
</g:north>
<g:center size="200">
<g:ScrollPanel>
<my:Content></my:Content>
</g:ScrollPanel>
</g:center>
</g:DockLayoutPanel>
where <my:Content> is another ui.xml template with the specific
content.
The entry point is:
public class Main implements EntryPoint {
@Override
public void onModuleLoad() {
ServiceAsync rpcService = GWT.create(Service.class);
HandlerManager eventBus = new HandlerManager(null);
AppController appViewer = new AppController(rpcService, eventBus);
appViewer.go(RootPanel.get());
}
}
But then if I add the Presenter of App.ui.xml only that presenter will
be binded to the view!! And the presenter/s of <my:Content> when(how)
can be binded?
Can you give me some suggestion or a basic structure of a generic
application with this pattern and uibinder?
Thanks
Best regards
It looks like, though, you're combining the Presenter and View roles
for your App, Header, and Content classes. That's not necessarily a
bad thing, but it means that your unit tests (you are unit testing,
right?) won't work in plain old JUnit... they'll have to use the
(slower) GWTTestCase harness, since they explicitly depend on
UiBinder, which won't work outside of a "development" mode.
Nonetheless, since you have combined them, I'll assume you are at
least using an MVP framework to help you? If you are using an MVP
framework like gwt-presenter or gwt-mvp, then the Presenter classes
have a bind() method (or something similar).
When one Presenter "contains" other presenters, as is the case here
for your AppController, then when it binds, it should take
responsibility for binding it's contained presenters at the right
time.
You'll need to use UiBinder to get references to your "child"
presenters. For the sake of this post, I will assume that, like
AppController below, your Header and Content classes also implement
both Presenter and View interfaces.
<g:DockLayoutPanel unit='PX'>
<g:north size='121'>
<my:Header ui:field="header" /> <!-- NB: ui:field -->
</g:north>
<g:center size="200">
<g:ScrollPanel>
<my:Content ui:field="content" /> <!-- NB: ui:field -->
</g:ScrollPanel>
</g:center>
</g:DockLayoutPanel>
In AppController, you'll have something like:
public class AppController implements Presenter, View {
interface Binder extends UiBinder<DockLayoutPanel, AppController> {}
private static Binder binder = GWT.create(Binder.class);
@UiField
Header header; // will be populated by UiBinder with your Header
// alternatively, you could set @UiField(provided=true) and use DI
// to get the instance of Header; pass it in as a constructor
arg ;-)
@UiField
Content content; // will be populated by UiBinder with your Content
ServiceAsync service;
HandlerManager eventBus;
DockLayoutPanel widget;
public AppControler(ServiceAsync service, HandlerManager eventBus) {
this.service = service;
this.eventBus = eventBus;
widget = binder.createAndBind(this);
}
@Override
public void bind() {
// when I bind you bind we bind!
header.bind();
content.bind();
}
@Override
public void unbind() {
header.unbind();
content.unbind();
}
// the remaining methods will vary,
// depending on your framework of choice
@Override
public void go(Panel panel) {
panel.add(widget);
}
@Override
public View getView() {
return this;
}
@Override
public Widget asWidget() {
return widget;
public class AppController implements Presenter, View {
interface Binder extends UiBinder<DockLayoutPanel, AppController>
{}
private static Binder binder = GWT.create(Binder.class);
@UiField(provided=true)
HeaderView header;
@UiField(provided=true)
ContentView content;
ServiceAsync service;
HandlerManager eventBus;
DockLayoutPanel widget;
public AppControler(ServiceAsync service, HandlerManager eventBus,
HeaderPresenter header, ContentPresenter presenter) {
this.service = service;
this.eventBus = eventBus;
this.header = header.getView();
this.content = content.getView();
widget = binder.createAndBind(this);
}
@Override
public void bind() {
// when I bind you bind we bind!
header.bind();
content.bind();
}
@Override
public void unbind() {
header.unbind();
content.unbind();
}
// the remaining methods will vary,
// depending on your framework of choice
@Override
public void go(Panel panel) {
panel.add(widget);
}
@Override
public View getView() {
return this;
}
@Override
public Widget asWidget() {
return widget;
}
}
This should work with the same App.ui.xml I previously posted above.
I should also note that I haven't specifically tested this code. It's
possible that the "View" classes will need to extend Widget to be
included in the UI by UiBinder. If that is the case, then the
following might be more appropriate:
<g:DockLayoutPanel unit='PX'>
<g:north size='121'>
<my:HeaderViewWidget ui:field="header" /> <!-- NB: ui:field -->
</g:north>
<g:center size="200">
<g:ScrollPanel>
<my:ContentViewWidget ui:field="content" /> <!-- NB: ui:field --
>
</g:ScrollPanel>
</g:center>
</g:DockLayoutPanel>
public class AppController implements Presenter, View {
interface Binder extends UiBinder<DockLayoutPanel, AppController>
{}
private static Binder binder = GWT.create(Binder.class);
@UiField(provided=true)
HeaderViewWidget header;
@UiField(provided=true)
ContentViewWidget content;
ServiceAsync service;
HandlerManager eventBus;
DockLayoutPanel widget;
public AppControler(ServiceAsync service, HandlerManager eventBus,
HeaderPresenter header, ContentPresenter presenter) {
this.service = service;
this.eventBus = eventBus;
this.header = header.getView().asWidget();
this.content = content.getView().asWidget();
widget = binder.createAndBind(this);
}
// the remainder is unchanged
public AppControler(ServiceAsync service, HandlerManager eventBus,
HeaderPresenter header, ContentPresenter content) {
this.service = service;
this.eventBus = eventBus;
this.header = header.getView().asWidget();
this.content = content.getView().asWidget();
widget = binder.createAndBind(this);
}
I mistyped the name of the ContentPresenter argument...
Instead of having EditContactView and ContactsView as completly
separate views, I want to add them to a DockLayoutPanel,
showing both views at the same time.
Let´s assume that I want to put the ContactsView in the center panel,
and the EditContactView in the south panel.
I guess I would do this by creating a third view, called e.g. MainView
(and MainPresenter),
and then putting my existing views in this third view? But I´m still
confused as to how I would set this up,
or if creating a third view would even be the correct approach.
Please advice :-)
CouponWidget couponWidget = new CouponWidget();
GameStatsWidget gameStatsWidget = new GameStatsWidget();
CouponPresenter coupon = new CouponPresenter(rpcService,
eventBus, couponWidget);
GameStatsPresenter gameStats = new GameStatsPresenter
(rpcService, eventBus, gameStatsWidget);
presenter = new MainPresenter(rpcService, eventBus, coupon,
gameStats, new MainPanel(couponWidget,gameStatsWidget));
Coupon and Gamestats are child widgets here, they are injected into
their presenters as usual.
MainPresenter is the presenter responsible for the parent view,
MainPanel.
Beside this, I pretty much used code similar to the one suggested by
jarrod above.
On 26 Jan, 16:46, Dalla <dalla_man...@hotmail.com> wrote:
> To clarify what I´m looking for, let´s assume that I´m working with
> GooglesMVPContacts example.