Built in GWT Widgets that require Constructor Arguments

1,799 views
Skip to first unread message

Nitish Upreti

unread,
May 18, 2011, 3:42:36 AM5/18/11
to google-we...@googlegroups.com
The docs Describle what to do when you have a custom widget that requires a constructor argument. However what to do when your using an existing GWT widget with constructor argument. For example -->

Tree(Tree.Resources resources) 
          Constructs a tree that uses the specified ClientBundle for image

I am not writing Tree.java myself here so using  @UiFactory  or  @UiField(provided=true) or @UiConstructor  make no sense.

When I say <g:Tree ...... > in my template how do I pass the argument here?

Thomas Broyer

unread,
May 18, 2011, 4:02:03 AM5/18/11
to google-we...@googlegroups.com
Some widgets have custom parsers, they're then documented in the widget's javadoc.

In the case of Tree, it has a no-arg constructor, so UiBinder will use it. If you want to use another constructor, you'll have to use a @UiFactory to construct the instance (rather than letting UiBinder construct it), or a @UiField(provided=true) to provide the instance to UiBinder (rather than letting it inject it into your @UiField).

Myth17

unread,
May 18, 2011, 4:28:17 AM5/18/11
to google-we...@googlegroups.com
But my question remains same! I can do that when I have a custom widget but this time I am not writing Tree.java myself so how do I do it?

Thomas Broyer

unread,
May 18, 2011, 5:20:50 AM5/18/11
to google-we...@googlegroups.com
Sorry, I don't understand.

You are *using* the Tree widget right? so you can use @UiFactory in your "owner class".
   @UiField Tree tree; // UiBinder will create the Tree using the @UiFactory and then inject it here

   @UiFactory
   Tree createTree() { return new Tree(myResources); }
If you want to pass the Resources from the UiBinder template, then:
   @UiFactory
   Tree createTree(Tree.Resource resources) { return new Tree(resources); }
and:
   <g:Tree resources="{myResources}" />
The arguments are matched by name, just like with a @UiConstructor.

You want to use Tree in a UiBinder template, right? so you already have a @UiField in your "owner class", right? so why couldn't you turn it into @UiField(provided=true) and initialize its value yourself?
  @UiField(provided=true) Tree tree = new Tree(myResources);

Really, the doc is quite clear, with examples of each different option (simply replace CricketScore with Tree and ignore the @UiConstructor option): http://code.google.com/webtoolkit/doc/latest/DevGuideUiBinder.html#Using_a_widget

It's just missing an example of @UiFactory with arguments, maybe that was what you were looking for?

Myth17

unread,
May 18, 2011, 7:16:06 AM5/18/11
to google-we...@googlegroups.com
Actually I am trying this but cannot get it working.

Here is the code

<!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">
<ui:with field='res' type='myth.social.zomato.client.Mainlist.Images' />
<ui:style src="resources/GlobalStyles.css">
</ui:style> 
<g:Tree ui:field='tree' resources='res' >
<g:TreeItem text='Delhi/NCR' />
<g:TreeItem text='Banglore'/>
<g:TreeItem text='Mumbai'/>
</g:Tree>
</ui:UiBinder> 


And the Java File

package myth.social.zomato.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiFactory;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.Tree.Resources;
import com.google.gwt.user.client.ui.Widget;

public class Mainlist extends Composite {

interface MainlistUiBinder extends UiBinder<Widget, Mainlist> {
}
private static MainlistUiBinder uiBinder = GWT
.create(MainlistUiBinder.class);
 public interface Images extends Tree.Resources , ClientBundle
 {
   
  @Source("resources/home.png")
  ImageResource homeLogo();
      }
//We are using an overloaded version of Tree constructor
@UiField(provided=true) 
Tree tree;
 
@UiFactory
Tree createTree(Resources resources)
return new Tree(resources); 
}
 
public Mainlist() 
{
initWidget(uiBinder.createAndBindUi(this));
}

}



Can you point out where am i going wrong? :|

Brian Reilly

unread,
May 18, 2011, 7:37:14 AM5/18/11
to google-we...@googlegroups.com
I think that @UiField(provided=true) and @UiFactory are two different
ways to get the same effect in this case. The smallest change to get
your code to work would be to remove provided=true from your @UiField
annotation. As it is, you're effectively telling UI Binder to not try
to create a Tree for you using any means; you're going to provide it
instead. Removing provided=true should allow UI Binder to use your
@UiFactory method.

The other option is to keep provided=true and not use a @UiFactory;
just create it in the constructor:

@UiField(provided=true) Tree tree;
@UiField Images res;

public Mainlist() {
tree = new Tree(res);
initWidget(uiBinder.createAndBindUi(this));
}

I haven't tested the code above, but I'm pretty sure it would work. If
you only have one Tree, the two methods are pretty similar. If you had
multiple Trees that you wanted to construct the same way (or even with
different resources), @UiFactory might be a little more convenient.

-- Brian

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

Myth17

unread,
May 18, 2011, 7:51:11 AM5/18/11
to google-we...@googlegroups.com
It seems to help but I still get an "Cannot parse attribute resources Element <g:Tree resources='res' ui:field='tree'> (:10)" error. :|

Brian Reilly

unread,
May 18, 2011, 8:10:17 AM5/18/11
to google-we...@googlegroups.com
Hmm... maybe @UiFactory won't work in this case. I looked at the docs
again and it looks like passing constructor parameters is possible
when using @UiConstructor, but I don't see anything about passing
parameters to @UiFactory methods. Try the @UiField(provided=true)
approach instead. Just be careful with the order of the statements;
I'm pretty sure you have to initialize provided UiFields before
calling createAndBindUi().

-- Brian


On Wed, May 18, 2011 at 7:51 AM, Myth17 <nitish...@gmail.com> wrote:
> It seems to help but I still get an "Cannot parse attribute resources
> Element <g:Tree resources='res' ui:field='tree'> (:10)" error. :|
>

Message has been deleted

Myth17

unread,
May 18, 2011, 8:51:47 AM5/18/11
to google-we...@googlegroups.com
I got the @UiFactory based code working but the purpose isnt solved yet. :)

How do I make a structure as 

City(a image next to)
---------Delhi
--------mumbai
--------foo

Right now all I have is 

----Delhi
----mumbai
---foo

How do I put in the City text with image? 

I am really sad about Google not providing any sample examples for Tree. It might be obvious to a lot of people but not everyone. I hope this GWT post keeps on guiding people further.

icamts

unread,
May 18, 2011, 8:54:28 AM5/18/11
to Google Web Toolkit
May be you are missing a couple of braces around "res", like this:

<g:Tree resources='{res}' ui:field='tree'>

look a Thomas' example:

<g:Tree resources="{myResources}" />

Cheers,
Luca

On 18 Mag, 14:27, Myth17 <nitishupr...@gmail.com> wrote:
> No luck. :(
> I get "[ERROR] [zomato] - Failed to create an instance of
> 'myth.social.zomato.client.Mainlist' via deferred binding " :(

Myth17

unread,
May 18, 2011, 8:56:04 AM5/18/11
to google-we...@googlegroups.com
yup i was missing the braces and it worked out. :)

Myth17

unread,
May 18, 2011, 8:59:33 AM5/18/11
to google-we...@googlegroups.com
I am particularly wondering looking at Google Mail sample

"  TreeItem root = new TreeItem(
        imageItemHTML(images.home(), "f...@example.com"));
    tree.addItem(root); "

How do i say this in Uibinder? :|

Thomas Broyer

unread,
May 18, 2011, 9:09:04 AM5/18/11
to google-we...@googlegroups.com
You have to use resources='{res}' to reference your res "variable".

Myth17

unread,
May 18, 2011, 9:16:02 AM5/18/11
to google-we...@googlegroups.com
But I dont see any constructor of TreeItem taking ImageResource or a setImage type function. :|
Reply all
Reply to author
Forward
0 new messages