GWT ViewWithUiHandlers with DialogBox Uibinder - gwt

I have been extending all my Views with ViewWithUiHandlers. So, from the View to invoke a presenter method I call
getUiHandlers().OnUserSelect();
How do i get the getUiHandlers() when one of view has to extend DialogBox, as a class can't have multiple extends.

Look at PopupViewWithUiHandler

Here's an example of a basic popup. First, you'll have to create a PresenterWidget associated to your PopupViewWithUiHandler:
public class MyPopupPresenter extends PresenterWidget<MyPopupPresenter.MyView>
implements MyPopupUiHandlers {
public interface MyView extends PopupView, HasUiHandlers<MyPopupUiHandlers> {
}
#Inject
public MyPopupPresenter(EventBus eventBus,
MyView view) {
super(eventBus, view);
getView().setUiHandlers(this);
}
}
Here's your PopupViewWithUiHandlers:
public class MyPopupView extends PopupViewWithUiHandlers<MyPopupUiHandlers>
implements MyPopupPresenter.MyView, {
public interface Binder extends UiBinder<PopupPanel, MyPopupView> {
}
#Inject
public MyPopupView(Binder binder,
EventBus eventBus) {
super(eventBus);
initWidget(binder.createAndBindUi(this));
}
}
And here's the UiBinder associated to your PopupViewWithUiHandlers. Notice the <g:PopupPanel>:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<g:PopupPanel>
<g:HTMLPanel>
...
</g:HTMLPanel>
</g:PopupPanel>
</ui:UiBinder>
And, you can show the popup by calling addToPopupSlot(myPopupPresenter) in the parent Presenter:
public class MyPresenter extends Presenter<MyPresenter.MyView, MyPresenter.MyProxy> implements MyUiHandlers {
public interface MyView extends View, HasUiHandlers<MyUiHandlers> {
}
#ProxyStandard
#NameToken(NameTokens.myNameToken)
public interface MyProxy extends ProxyPlace<MyPresenter> {
}
private final MyPopupPresenter myPopupPresenter;
#Inject
public MyPresenter(EventBus eventBus,
MyView view,
MyProxy proxy,
MyPopupPresenter myPopupPresenter) {
super(eventBus, view, proxy, ApplicationPresenter.MainContentSlot);
this.myPopupPresenter = myPopupPresenter;
getView().setUiHandlers(this);
}
private void showPopup() {
addToPopupSlot(myPopupPresenter); // this will show your popup
}
}

Related

Why am I not able to update my navigation bar (PermanentSlot)?

Short summary:
I try to update a navigation bar after a place change event. To do so I created a GWTP Test*.java that I try to render in a SLOT_NavBar. However, this is not working. In order to see if I did something wrong I just made itself render in my SLOT_AdminToolMainContent slot which is working perfectly fine. The question is why I can render TestView in one slot but not in the other. GWTP is not giving me any clues about what I'm doing wrong here and I can't find anything in the documention that would help me out here.
I'm sure the problem must be either a misunderstanding from my side or something really stupid that I'm doing but I just fail to see the reason why this is not working.
I'm having here a "root" presenter:
AdminToolPresenter.java
public class AdminToolPresenter extends Presenter<AdminToolPresenter.MyView, AdminToolPresenter.MyProxy> {
public interface MyView extends View {
}
#ProxyStandard
#NameToken(AdminNameTokens.adminTool)
#UseGatekeeper(AdminGatekeeper.class)
public interface MyProxy extends ProxyPlace<AdminToolPresenter> {
}
/** */
public static final PermanentSlot<MenuPresenter> SLOT_Menu = new PermanentSlot<>();
/** */
public static final NestedSlot SLOT_AdminToolMainContent = new NestedSlot();
/** */
private MenuPresenter menuPresenter;
#Inject
public AdminToolPresenter(EventBus eventBus, MyView view, MyProxy proxy, MenuPresenter menuPresenter) {
super(eventBus, view, proxy, RevealType.RootLayout);
this.menuPresenter = menuPresenter;
}
#Override
protected void onBind() {
this.setInSlot(SLOT_Menu, this.menuPresenter);
}
#Override
protected void onReveal() {
LOGGER.fine("AdminToolPresenter.onReveal()");
}
}
and its view:
AdminToolView.java
public class AdminToolView extends ViewImpl implements AdminToolPresenter.MyView {
#SuppressWarnings("unused")
private final static Logger LOGGER = Logger.getLogger(AdminToolView.class.getName());
public interface Binder extends UiBinder<Widget, AdminToolView> {
}
#UiField HTMLPanel menuPanel;
#UiField SimplePanel adminMainContent;
#Inject
public AdminToolView(Binder uiBinder) {
this.initWidget(uiBinder.createAndBindUi(this));
this.bindSlot(AdminToolPresenter.SLOT_Menu, this.menuPanel);
this.bindSlot(AdminToolPresenter.SLOT_AdminToolMainContent, this.adminMainContent);
}
}
Everything I'm doing with this is working just fine for example:
TestPresenter.java
public class TestPresenter extends Presenter<TestPresenter.MyView, TestPresenter.MyProxy> implements TestUiHandlers {
private final static Logger LOGGER = Logger.getLogger(TestPresenter.class.getName());
interface MyView extends View , HasUiHandlers<TestUiHandlers> {
}
#NameToken(AdminNameTokens.test)
#ProxyStandard
interface MyProxy extends ProxyPlace<TestPresenter> {
}
#Inject
TestPresenter(EventBus eventBus, MyView view, MyProxy proxy) {
// This is working just fine. The content gets displayed correctly in the SLOT_AdminToolMainContent slot
super(eventBus, view, proxy, AdminToolPresenter.SLOT_AdminToolMainContent);
this.getView().setUiHandlers(this);
}
#Override
public void prepareFromRequest(PlaceRequest request) {
LOGGER.severe("prepareFromRequest");
super.prepareFromRequest(request);
}
}
TestView.java
class TestView extends ViewWithUiHandlers<TestUiHandlers> implements TestPresenter.MyView {
interface Binder extends UiBinder<Widget, TestView> {
}
#UiField SimplePanel main;
#Inject TestView(Binder uiBinder) {
this.initWidget(uiBinder.createAndBindUi(this));
}
}
No problem at all! However, if I try to bind this to another slot:
The issue
#Inject
TestPresenter(EventBus eventBus, MyView view, MyProxy proxy) {
// MenuPresenter.SLOT_NavBar instead of AdminToolPresenter.SLOT_AdminToolMainContent
super(eventBus, view, proxy, MenuPresenter.SLOT_NavBar);
this.getView().setUiHandlers(this);
}
Then it's simply doing nothing! I only changed the slot - so why is this not working? Here is the MenuPresenter and related code:
MenuPresenter.java
public class MenuPresenter extends PresenterWidget<MenuPresenter.MyView> implements MenuUiHandlers {
private final static Logger LOGGER = Logger.getLogger(MenuPresenter.class.getName());
interface MyView extends View, HasUiHandlers<MenuUiHandlers> {
}
/** Slot for the navigation bar. */
public static final NestedSlot SLOT_NavBar = new NestedSlot();
#Inject
MenuPresenter(EventBus eventBus, MyView view) {
super(eventBus, view);
this.getView().setUiHandlers(this);
}
#Override
protected void onReveal() {
LOGGER.severe("onReveal()");
}
}
MenuView.java
class MenuView extends ViewWithUiHandlers<MenuUiHandlers> implements MenuPresenter.MyView {
interface Binder extends UiBinder<Widget, MenuView> {
}
#UiField HTMLPanel navBarPanel;
#UiField MaterialSideNav sideNav;
private PlaceManager placeManager;
#Inject MenuView(Binder uiBinder, PlaceManager placeManager) {
this.initWidget(uiBinder.createAndBindUi(this));
this.bindSlot(MenuPresenter.SLOT_NavBar, this.navBarPanel);
this.placeManager = placeManager;
}
}
MenuView.ui.xml
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:m="urn:import:gwt.material.design.client.ui"
xmlns:m.addins="urn:import:gwt.material.design.addins.client.ui">
<ui:with field="tokens" type="com.mz.client.admin.place.AdminNameTokens"/>
<ui:style gss="true">
/* .. */
</ui:style>
<g:HTMLPanel ui:field="main">
<g:HTMLPanel addStyleNames="{style.navbar-wrapper}">
<g:SimplePanel ui:field="navBarPanel" />
</g:HTMLPanel>
<m:MaterialHeader>
<m:MaterialNavBar backgroundColor="white" activates="sideNav" layoutPosition="RELATIVE" addStyleNames="{style.nav-bar}">
<m:MaterialNavSection>
</m:MaterialNavSection>
</m:MaterialNavBar >
<m:MaterialSideNav ui:field="sideNav" m:id="sideNav" type="FIXED" alwaysShowActivator="true" width="280" addStyleNames="{style.side-nav}" >
<m:MaterialLink targetHistoryToken="{tokens.getHome}" iconType="HOME" iconPosition="LEFT" textColor="black" text="Home" />
</m:MaterialSideNav>
</m:MaterialHeader>
</g:HTMLPanel>
</ui:UiBinder>
Please explain to me why this is not working - it is driving me nuts. I'm not getting anything from GWTP like "dude, you're trying to do something strange here". No warning, error or info. Just nothing and I don't see what I do wrong here!
To give you an idea how this looks like: The blue bar is the <g:SimplePanel ui:field="navBarPanel"/> which you see in MenuView:
Did You tried to replace PernamentSlot with SingleSlot? I am not sure that you can update PernamentSlot.
Did You tried to replace PresenterWidget with Presenter in class extension in MenuPresenter class?
MenuView is widget, no place, So it seems that You did not add this view anywhere, so it simply doesn't display it self. Try to put some static content to this view and see is it even reveal itself.
Try in main view add in constructor widget.add(new MenuView());. where widget is initialized(using java or uibinder) view element.
To display regular Presenter (which is a place)You have to have a url for it (f.e.: localhost:8080/myApp | localhost:8080/myApp#MenuPresenter).
To display PresenterWidget You have to call it somewhere!
According to documentation here:
NestedSlot: Same as SingleSlot, but can only take Presenters that have
Proxies (no PresenterWidget).
and You try to put there a PresenterWidget- WHICH IS WRONG, try to:
replace NestedSlot with Slot or SingleSlot(accepts PresenterWidget),
or change MenuPresenter to extend regular Presenter instead of PresenterWidget.
Try do this and give me feedback.
You should try to clean and install Your whole application and restart SuperDevMode and Your server.
I've recreate described functionality. It works. I've base on this article
Layout example
Layout example. Hope this will help.
package pl.korbeldaniel.cms.client.place.app;
public class AppModule extends AbstractPresenterModule {
#Override
protected void configure() {
install(new UiModule());
bindPresenter(AppPresenter.class, AppPresenter.MyView.class, AppView.class, AppPresenter.MyProxy.class);
bindPresenter(HomePresenter.class, HomePresenter.MyView.class, HomeView.class, HomePresenter.MyProxy.class);
bindPresenter(ErrorPresenter.class, ErrorPresenter.MyView.class,
bindPresenter(TesttPresenter.class, TesttPresenter.MyView.class, TesttView.class, TesttPresenter.MyProxy.class);
}
}
package pl.korbeldaniel.cms.client.place.app;
public class AppPresenter extends TabContainerPresenter<AppPresenter.MyView, AppPresenter.MyProxy> implements AppUiHandlers, CurrentUserChangedHandler, AsyncCallStartHandler, AsyncCallFailHandler, AsyncCallSucceedHandler {
#ProxyStandard
public interface MyProxy extends Proxy<AppPresenter> {}
public interface MyView extends TabView, HasUiHandlers<AppUiHandlers> {}
public static final NestedSlot SLOT_NavBar = new NestedSlot();
private final TesttPresenter testtPresenter;
#Inject
AppPresenter(EventBus eventBus, MyView view, MyProxy proxy, TesttPresenter testtPresenter) {
super(eventBus, view, proxy, SLOT_TAB_CONTENT, SLOT_REQUEST_TABS, SLOT_CHANGE_TAB, RevealType.Root);
this.testtPresenter = testtPresenter;
getView().setUiHandlers(this);
}
#Override
protected void onBind() {
super.onBind();
setInSlot(SLOT_NavBar, testtPresenter);
}
}
package pl.korbeldaniel.cms.client.place.app;
public class AppView extends ViewWithUiHandlers<AppUiHandlers> implements AppPresenter.MyView {
public interface Binder extends UiBinder<Widget, AppView> {}
#UiField MaterialRow navBarPanel;
#Inject
AppView(Binder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
bindSlot(AppPresenter.SLOT_NavBar, navBarPanel);
}
}
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui' xmlns:m="urn:import:gwt.material.design.client.ui"
<m:MaterialPanel>
<m:MaterialRow ui:field="navBarPanel" />
</m:MaterialPanel>
</ui:UiBinder>
package pl.korbeldaniel.cms.client.playground.test.testt;
import pl.korbeldaniel.cms.client.place.app.AppPresenter;
public class TesttPresenter extends Presenter<TesttPresenter.MyView, TesttPresenter.MyProxy> {
public interface MyView extends View {}
#ProxyStandard
public interface MyProxy extends Proxy<TesttPresenter> {}
#Inject
public TesttPresenter(EventBus eventBus, MyView view, MyProxy proxy) {
super(eventBus, view, proxy, AppPresenter.SLOT_NavBar);
}
}
package pl.korbeldaniel.cms.client.playground.test.testt;
import pl.korbeldaniel.cms.client.place.app.AppPresenter;
public class TesttView extends ViewImpl implements TesttPresenter.MyView {
public interface Binder extends UiBinder<Widget, TesttView> {}
#UiField
SimplePanel main;
#Inject
public TesttView(Binder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
main.add(new Label("____________________________________________________________________________________________________________________>TEST "));
Window.alert("TESTT");
this.bindSlot(AppPresenter.SLOT_NavBar, this.main);
}
}
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:SimplePanel ui:field="main"></g:SimplePanel>
</ui:UiBinder>

GWTP not displaying UI

I'm trying to use GWTP in my GWT 2.7 application but the UI in my uibinder is not displaying. My app compiles and runs in Super dev mode without any errors, but I get a blank screen. I expected the HTML in the LayoutView.ui.xml to show in the browser. I'm sure I'm missing something really basic. Any help would be great.
The following is included in my .gwt.xml file
<inherits name='com.google.gwt.inject.Inject' />
<!-- Other module inherits -->
<inherits name="com.google.gwt.uibinder.UiBinder" />
<inherits name='com.gwtplatform.mvp.Mvp' />
<entry-point class="com.clearwood.client.App" />
<define-configuration-property name="gin.ginjector" is-multi-valued="false" />
<set-configuration-property name="gin.ginjector"
value="com.clearwood.client.gin.MyGinjector" />
client/App.java
public class App implements EntryPoint {
public final MyGinjector ginjector = GWT.create(MyGinjector.class);
#Override
public void onModuleLoad() {
DelayedBindRegistry.bind(ginjector);
ginjector.getPlaceManager().revealCurrentPlace();
}
}
client/gin/ClientModule.java
public class ClientModule extends AbstractPresenterModule {
#Override
protected void configure() {
install(new DefaultModule());
install(new LayoutModule());
bindConstant().annotatedWith(DefaultPlace.class).to(NameTokens.LAYOUT);
bindConstant().annotatedWith(ErrorPlace.class).to(NameTokens.LAYOUT);
bindConstant().annotatedWith(UnauthorizedPlace.class).to(NameTokens.LAYOUT);
requestStaticInjection(NameTokens.class);
}
}
client/gin/Ginjector.java
#GinModules({ ClientModule.class })
public interface MyGinjector extends Ginjector {
EventBus getEventBus();
PlaceManager getPlaceManager();
Provider<LayoutPresenter> getLayoutPresenter();
}
client/place/NameTokens.java
public class NameTokens {
public static final String LAYOUT = "LAYOUT";
public static String getLAYOUT() {
return LAYOUT;
}
}
client/layout/LayoutView.ui.xml
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:SimplePanel width="600px" height="auto" ui:field="main">
<g:HTML width="100%" height="100%">TEST</g:HTML>
</g:SimplePanel>
</ui:UiBinder>
client/layout/LayoutView.java
class LayoutView extends ViewImpl implements LayoutPresenter.MyView {
interface Binder extends UiBinder<Widget, LayoutView> {
}
#UiField
SimplePanel main;
#Inject
LayoutView(Binder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
}
#Override
public void setInSlot(Object slot, IsWidget content) {
if (slot == LayoutPresenter.SLOT_Layout) {
main.setWidget(content);
} else {
super.setInSlot(slot, content);
}
}
}
client/layout/LayoutPresenter.java
public class LayoutPresenter extends Presenter<LayoutPresenter.MyView, LayoutPresenter.MyProxy> {
interface MyView extends View {
}
#ContentSlot
public static final Type<RevealContentHandler<?>> SLOT_Layout = new Type<RevealContentHandler<?>>();
#ProxyStandard
interface MyProxy extends Proxy<LayoutPresenter> {
}
#Inject
LayoutPresenter(
EventBus eventBus,
MyView view,
MyProxy proxy) {
super(eventBus, view, proxy, RevealType.Root);
}
}
client/layout/LayoutModule.java
public class LayoutModule extends AbstractPresenterModule {
#Override
protected void configure() {
bindPresenter(LayoutPresenter.class, LayoutPresenter.MyView.class, LayoutView.class, LayoutPresenter.MyProxy.class);
}
}
I generated the Layout presenter using the GWTP plugin.
I tried to follow the sample tutorials at
http://dev.arcbees.com/gwtp/sampletutorial/
and
https://code.google.com/p/gwt-platform/wiki/GettingStarted#Getting_the_sample_applications
but some of it seems to be deprecated
You don't have a presenter with a ProxyPlace and the annotation #NameToken on it. To get your code working quickly, you can change LayoutPresenter.MyProxy to:
#ProxyStandard
#NameToken(NameTokens.LAYOUT)
interface MyProxy extends ProxyPlace<LayoutPresenter> {}
Also the Google Code documentation is actually outdated by a lot. There are warnings all over the place, so I thought this was obvious.
The documentation on https://dev.arcbees.com/gwtp/sampletutorial/ is recent enough to help you develop a working application. You can also have a look at GWTP's Basic Sample for more examples: https://github.com/ArcBees/GWTP-Samples/tree/master/gwtp-samples/gwtp-sample-basic

GWT's Editor Framework and GWTP

building on this answer, i try to integrate the GWT editors into a popup presenter widget. What is the right way to do that?
My view looks like this:
public class DeviceEditorDialogView extends
PopupViewWithUiHandlers<DeviceEditorDialogUiHandlers> implements
DeviceEditorDialogPresenterWidget.MyView {
interface Binder extends UiBinder<PopupPanel, DeviceEditorDialogView> {
}
public interface Driver extends SimpleBeanEditorDriver<DeviceDto, DeviceEditorDialogView> {
}
#Inject
DeviceEditorDialogView(Binder uiBinder, EventBus eventBus) {
super(eventBus);
initWidget(uiBinder.createAndBindUi(this));
}
#Override
public SimpleBeanEditorDriver<DeviceDto, ?> createEditorDriver() {
Driver driver = GWT.create(Driver.class);
driver.initialize(this);
return driver;
}
}
and my presenter looks like this:
public class DeviceEditorDialogPresenterWidget extends PresenterWidget<DeviceEditorDialogPresenterWidget.MyView> implements
DeviceEditorDialogUiHandlers {
#Inject
DeviceEditorDialogPresenterWidget(EventBus eventBus,
MyView view) {
super(eventBus, view);
getView().setUiHandlers(this);
}
/**
* {#link LocalDialogPresenterWidget}'s PopupView.
*/
public interface MyView extends PopupView, DevicesEditView<DeviceDto>, HasUiHandlers<DeviceEditorDialogUiHandlers> {
}
private DeviceDto currentDeviceDTO = null;
private SimpleBeanEditorDriver<DeviceDto, ?> driver;
public DeviceDto getCurrentDeviceDTO() {
return currentDeviceDTO;
}
public void setCurrentDeviceDTO(DeviceDto currentDeviceDTO) {
this.currentDeviceDTO = currentDeviceDTO;
}
#Override
protected void onBind() {
super.onBind();
driver = getView().createEditorDriver();
}
//UiHandler Method: Person person = driver.flush();
}
Is this the right approach? What is missing? Currently nothing happens when i try to use it like this:
#Override
public void showDeviceDialog() {
deviceEditorDialog.setCurrentDeviceDTO(new DeviceDto());
addToPopupSlot(deviceEditorDialog);
}
showDeviceDialog is in the parent presenter and called when clicking a button in that parent Presenter, that instantiates the dialog with private final DeviceEditorDialogPresenterWidget deviceEditorDialog;
Thanks!
Here are a few key points that are missing from your code above:
Your DeviceEditorDialogView should implement Editor<DeviceDto>. This is required in order for the fields of DeviceEditorDialogView to be populated with data from you POJO.
Your DeviceEditorDialogView should have child editors that are mapped to fields in your POJO. For example, given the field deviceDto.modelName (type String), you could have a GWT Label named modelName in your DeviceEditorDialogView. This Label implements Editor<String> and will be populated with the modelName from your DeviceDto when you call driver.edit(deviceDto)
You should call driver.initialize(this) only once, in DeviceEditorDialogView's constructor
You should override onReveal() like this:
#Override
public void onReveal() {
super.onReveal();
driver.edit(currentDeviceDTO); // this will populate your view with the data from your POJO
}
This method will be called when the popup is displayed, just after your DeviceEditorDialogPresenterWidget has been addToPopupSlot

How to pass parameter into Constructor View of UiBinder (by using setInSlot) in GWT Platform?

It's very hard to find questions about GWTP (GWT Platform).
Ok, Here is my Story. I am using GWTP & eclipse to create the Presenter-View structure automatically.
Example, I created a TestPresenter in eclipse, & it created 3 files: TestPresenter.java, TestView.java, TestView.xml
In TestView.xml, i have:
<g:RadioButton ui:field="firstRadioButton" value="false" text="1st" />
<g:RadioButton ui:field="secondRadioButton" value="false" text="2nd" />
<g:RadioButton ui:field="bothRadioButton" value="true" text="Both" />
Now I want to set the GroupName automatically for each TestView, so in TestView.java
public class TestView extends ViewImpl implements
TestPresenter.MyView {
private final Widget widget;
#UiField RadioButton firstRadioButton;
#UiField RadioButton secondRadioButton;
#UiField RadioButton bothRadioButton;
private String groupName;
#UiFactory
RadioButton makeRadioButton() {
return new RadioButton(groupName);
}
public interface Binder extends UiBinder<Widget, TestView> {
}
#Inject
public TestView(final Binder binder) {
widget = binder.createAndBindUi(this);
}
#Override
public Widget asWidget() {
return widget;
}
public RadioButton getFirstRadioButton() {
return firstRadioButton;
}
public RadioButton getSecondRadioButton() {
return secondRadioButton;
}
public RadioButton getBothRadioButton() {
return bothRadioButton;
}
}
In TestPresenter.java,
public class TestPresenter extends
PresenterWidget<TestPresenter.MyView> {
public interface MyView extends View {
public RadioButton getFirstRadioButton();
public RadioButton getSecondRadioButton();
public RadioButton getBothRadioButton();
}
}
Ok, finally I want to use many TestPresenter (by using setInLot) in MainPresenter.java
So, in MainPresenter.java, I have:
public static final Object SLOT1=new Object();
public static final Object SLOT2=new Object();
public static final Object SLOT3=new Object();
public static final Object SLOT4=new Object();
//...... more lot
#Inject TestPresenter testPresenter1;
#Inject TestPresenter testPresenter2;
#Inject TestPresenter testPresenter3;
#Inject TestPresenter testPresenter4;
//.. more test presenter
in MainView.java, i have setInSlot
#UiField HTMLPanel mainHtmlPanel;
#Override
public void setInSlot(Object slot, Widget content){
if(slot==MainPresenter.SLOT1){
mainHtmlPanel.clear();
if(content!=null){
mainHtmlPanel.add(content);
}
}
else if(slot==MainPresenter.SLOT2){
mainHtmlPanel.clear();
if(content!=null){
mainHtmlPanel.add(content);
}
}
//... more else if here
}
Now, if i just do like that then I can not pass the groupName separately for each TestPresenter & that is not good. So I want to pass the groupName string for each TestPresenter so that each will have their own groupName. SOmething like this
#Inject TestPresenter testPresenter1 ("group1");
#Inject TestPresenter testPresenter2 ("group2");
#Inject TestPresenter testPresenter3 ("group3");
#Inject TestPresenter testPresenter4 ("group4");
...
but I don't know how to it properly, so please tell me how to it properly in GWTP?
If you want to specify a groupName in constructors of TestPresenter why you might need to use is assisted injection".
Then you would probably end up with something like this (I have not tested the code):
public interface TestPresenterFactory {
TestPresenter create(String groupName);
}
and in your Gin Module:
#Override
protected void configure() {
...
install(new GinFactoryModuleBuilder().build(TestPresenterFactory.class));
}
Then instead of:
#Inject TestPresenter testPresenter1 ("group1");
#Inject TestPresenter testPresenter2 ("group2");
#Inject TestPresenter testPresenter3 ("group3");
#Inject TestPresenter testPresenter4 ("group4");
...
you would inject the TestPresenterFactory in the constructor of ParentPresenter to create all TestPresenters:
private TestPresenter testPresenter1;
private TestPresenter testPresenter2;
private TestPresenter testPresenter3;
private TestPresenter testPresenter4;
#Inject
public ParentPresenter(final EventBus eventBus, final ParentView view, final ParentProxy proxy, final TestPresenterFactory factory)
{
...
testPresenter1 = factory.create("group1");
testPresenter2 = factory.create("group2");
testPresenter3 = factory.create("group3");
testPresenter4 = factory.create("group4");
}
And the #Assisted annotation in the TestPresenter.java:
public interface MyView extends View {
...
public void setRadioButtonsGroupName(String groupName);
}
#Inject
public TestPresenter(final EventBus eventBus, final MyView view, #Assisted String groupName)
{
...
view.setRadioButtonsGroupName(groupName);
}
And TestView.java:
public class TestView extends ViewImpl implements TestPresenter.MyView {
private final Widget widget;
#UiField RadioButton firstRadioButton;
#UiField RadioButton secondRadioButton;
#UiField RadioButton bothRadioButton;
...
public void setRadioButtonsGroupName(String groupName) {
firstRadioButton.setName(groupName);
secondRadioButton.setName(groupName);
bothRadioButton.setName(groupName);
}
}
But do you really need your TestPresenters to be aware of the groupName used by the RadioButtons in their views ?
Ok, I haven't test Alexis' solution, but his idea of "setGroupName" trigger my mind so I can adjust my code abit & it works fine.
In TestPresenter.java, I have this method
public void setGroupName(String groupName) {
getView().getFirstRadioButton().setName(groupName);
getView().getSecondRadioButton().setName(groupName);
getView().getBothRadioButton().setName(groupName);
}
in MainPresenter.java
#Inject TestPresenter testPresenter1;
#Inject TestPresenter testPresenter2;
....
#Override
protected void onReset() {
super.onReset();
setInSlot(SLOT1, testPresenter1);
setInSlot(SLOT2, testPresenter2);
.....
testPresenter1.setGroupName("group1");
testPresenter2.setGroupName("group2");
....
}

GIN & GWT: Binding Presentation layer with View

I'm trying to bind a GWT view with its presentation layer, but it doesn't seem to be doing anything.
It's a Spring Roo GWT generated project and I'm trying to use the scaffold given as far as possible.
The view is a simple button (R.ui.xml) and the rest of the view is defined in R.java:
public class R extends Composite implements RPresenter.Display {
interface MyUiBinder extends UiBinder<Widget, R> {}
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
#UiField Button myButton;
private ClickHandler buttonClickHandler = null;
public R(){
initWidget(uiBinder.createAndBindUi(this));
}
#UiHandler("myButton")
void onButtonClick(ClickEvent event){
GWT.log('Button clicked');
if (buttonClickHandler != null){
GWT.log("buttonClickHandler event triggered");
buttonClickHandler.onClick(event);
}
}
#Override
public void setButtonClickHandler(ClickHandler buttonClickHandler) {
GWT.log("setButtonClickHandler");
this.buttonClickHandler = buttonClickHandler;
}
}
The presenter:
public class RPresenter {
public interface Display extends IsWidget {
void setButtonClickHandler(ClickHandler buttonClickHandler);
}
private final Display display;
private final EventBus eventBus;
#Inject
public RPresenter(EventBus eventBus, Display display){
this.display = display;
this.eventBus = eventBus;
bind();
}
private void bind(){
display.setButtonClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
GWT.log("onClick event triggered");
}
});
}
public void go(HasWidgets container){
container.add(display.asWidget());
}
}
And for my GIN module I use the generated ScaffoldModule in the ...client.scaffold.ioc package:
public class ScaffoldModule extends AbstractGinModule {
#Override
protected void configure() {
GWT.log("ScaffoldModule configure");
bind(EventBus.class).to(SimpleEventBus.class).in(Singleton.class);
bind(ApplicationRequestFactory.class).toProvider(RequestFactoryProvider.class).in(Singleton.class);
bind(PlaceController.class).toProvider(PlaceControllerProvider.class).in(Singleton.class);
//bind(RPresenter.Display.class).to(R.class).in(Singleton.class);
bind(RPresenter.Display.class).to(R.class);
}
static class PlaceControllerProvider implements Provider<PlaceController> {
private final EventBus eventBus;
#Inject
public PlaceControllerProvider(EventBus eventBus) {
this.eventBus = eventBus;
}
public PlaceController get() {
return new PlaceController(eventBus);
}
}
static class RequestFactoryProvider implements Provider<ApplicationRequestFactory> {
private final EventBus eventBus;
#Inject
public RequestFactoryProvider(EventBus eventBus) {
this.eventBus = eventBus;
}
public ApplicationRequestFactory get() {
ApplicationRequestFactory requestFactory = GWT.create(ApplicationRequestFactory.class);
requestFactory.initialize(eventBus);
return requestFactory;
}
}
}
In the GWT development mode console, the "ScaffoldModule configure" never displays, yet the generated scaffold seems to binding just fine as the events get passed along from component to component without a hitch, unless the binding is magically happening somewhere else and that is dead code.
When I put my bind(RPresenter.Display.class).to(R.class) in, it doesn't seem to do the binding. The only output I get in the GWT console is "Button clicked" which is called in the view and then nothing further. I'm clearly missing something, any ideas?
The call to GWT.log() will not output anything from an AbstractGinModule - classes that extend AbstractGinModule (ScaffoldModule in your situation) are used by gin at compile time to decide which concrete implementations to use for injected interfaces. From the rest of your description (i.e. that the UI shows up in the application) it appears that your dependency injection is working correctly.