How to use UIBinder dynamacally? - gwt

I am using gwt 2.3.I am using UI binder in this. I want to create grid in this by using UIBinder. For this I have written this code.
<g:Grid ui:field='mygrid' addStyleNames='{style.panel}'
cellSpacing='10'>
<g:row>
<g:customCell>
<g:Label text="11" styleName="{style.label}" />
</g:customCell>
<g:customCell>
<g:Label text="22" styleName="{style.label}" />
</g:customCell>
</g:row>
<g:row>
<g:customCell>
<g:Label text="33" styleName="{style.label}" />
</g:customCell>
<g:customCell>
<g:Label text="44" styleName="{style.label}" />
</g:customCell>
</g:row>
</g:Grid>
Now here my data of grid is static.Now In case if my data comes from server side & depending on that data I want to create a Grid using UIbinder. How can this possible ??
One another case.There is form.In that from number of controls comes from data base.
So How can UIBider support to create this form.As number of control may vary each time
So I want to know is it possible to use UIBinder in case to create User Interface depending on run time data.
Any suggestions or example appreciated.

UiBinder is "cross compiled" to JavaScript and HTML code. Once that is done you cant modify it. There is now way to do something like send your XML syntax to client and then it creates a grid.
However it is possible that you add new Rows in your "code behind".
For your second question: I have no Idea what you mean :P

Yes, you can add data into UIBinder from Java. When you created UIBinder in Eclipse it also created .java file for this XML. Edit this corresponding java file and add something like this:
public class MyGridSample extends Composite {
// uiBinder interface declaration...
private static MyGridSampleUiBinderUiBinder uiBinder = GWT.create(MyGridSampleUiBinder.class);
interface MyGridSampleUiBinder extends UiBinder<Widget, MyGridSample > {
}
// annotation to get ui-field into code
#UiField
Grid mygrid;
public MyGridSample () {
setWidget(uiBinder.createAndBindUi(this));
// sets cell 0,0 with label
mygrid.setWidget(0, 0, new Label("cell 0"));
}
}
GWT is client side framework and UIBinder is precompiled as javascript files - they are served as static files. You should make a Webservice call to get data into this template.

Related

Hide <g:customCell styleName="width:15%;">

I have a customcell in my xml file, It contains vertical panel which I have hide, But it cause some UI design issue as CustomCell is not hidde. Can anyone tell me how I can hide my customcell?. Thanks in advance.
<g:customCell styleName="width:15%;" ui:field="parentCell"
visible="false">
<g:VerticalPanel visible="false" ui:field="SortVPanel">
<g:Grid width="100%">
<g:row>
<g:customCell >
<g:Label styleName="float-left" wordWrap="false" width="65px" >
<ui:msg key="lblSort"> Sort By </ui:msg></g:Label>
</g:customCell>
<g:customCell styleName="cell-width83">
<c:ComboBoxComponent />
</g:customCell>
</g:row>
</g:Grid>
</g:VerticalPanel>
</g:customCell>
I want to hide the above customcell, which UiField value is ui:field="parentCell"
The g:customCell tag isnt a dom element, but a marker for the g:Grid tag to know which items are cells vs rows. This means you can't add html attributes to it. You also can't give it a ui:field, since it isn't an object at all.
Instead, you put these on the child Widget which lives inside the g:customCell tag, or from your Java code, you can call grid.getCellFormatter() and use the methods there to further format the cell which wraps the widget.

How to use buttons with GWT's UiBinder?

In MyPanel.ui.xml:
<button class="btn" ui:field="myButton">Save</button>
In MyPanel.java:
public class MyPanel extends Composite {
...
#UiField ButtonElement myButtonUi;
...
public MyScreen() {
final HTMLPanel panel = uiBinder.createAndBindUi(this);
initWidget(panel);
Button myButton = Button.wrap(myButtonUi);
In MyEntryPoint.java:
if (....)
RootPanel.get().add(new MyPanel());
So I think I don't really understand how to use UiBinder.
It's my intention to use HTML with ui:field=".." so that the web-designer can set things like class="xx" on the UI fields. Most of the GWT documentation assumes you've got a Button not a ButtonElement. But if I use a Button I need to have a <g:Button> in the HTML document which means my web-designer can't set the class? I mean the point of UiBinder is to allow one to use normal HTML and integrate it with the GWT code?
When I do the above, on the wrap line, I get a NullPointerException in development mode from:
public static Button wrap(com.google.gwt.dom.client.Element element) {
// Assert that the element is attached.
assert Document.get().getBody().isOrHasChild(element);
In production mode it seems to work OK. In the debugger of development mode in Eclipse, when I right-click and "Inspect" the expression "Document.get().getBody()" Eclipse says "Cannot send a static message to a non class type object".
What should I do? Is the null pointer exception happening because I need to attach the element first? If so, how? (I am already calling createAndBindUi and the element passed to wrap is non-null).
So finally, here's the answer. I Edited it and deleted useless comments.
You can't use HTML in your ui.xml if your plan is to use UiBinder to wire a component from the ui.xml to your view's Java code. Instead of
<button class="btn" ui:field="myButton">Save</button>
use
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<g:Button styleName="btn" text="Save" ui:field="myButton"/>
Then in your view -java code- simply type
#UiField com.google.gwt.user.client.ui.Button myButton;
public MyScreen() {
final HTMLPanel panel = uiBinder.createAndBindUi(this);
initWidget(panel);
}
That's it.
The "styleName" attribute is enough for your designer to hook a CSS class. This other post might interest you. Designers will have to learn about what attributes are available on which components. Using UiBinder is not as straighforward as using HTML.
UiBinder is not for writing HTML but to write XML that can be understood by GWT and compiled to javascript (which in turn will produce the page's HTML). It's not like the JSP mechanism where you can insert plain HTML right away.
UiBinder is most helpful when you have to wire ui elements (widgets or composites from the ui.xml) with your Java view code (i.e. using the #UiField or #UiHandler annotations).
You can use HTML. The only restriction is that g:Button must be inside a container like g:HTMLPanel.
The good thing about g:HTMLPanel is that it can render HTML.
See the example below:
<g:HTMLPanel>
<div>
test
</div>
<table border="1">
<th>
button
</th>
<tr>
<td>
<g:Button styleName="{style.important}" ui:field="button"/>
</td>
</tr>
</table>
<div>
test
</div>
</g:HTMLPanel>

Is it possible to set the column width of a grid in GWT using uibinder?

I'm trying to use the GWT grid component in uibinder. It works fine until I want to set the width of the columns. The following is what I've tried to do but it doesn't seem to work.
<g:Grid width="100%">
<g:row>
<g:customCell width="20%">
<g:FlowPanel width="">
</g:FlowPanel>
</g:customCell>
<g:customCell width="80%">
<g:FlowPanel width="">
</g:FlowPanel>
</g:customCell>
</g:row>
</g:Grid>
You can write some java code in order to do that, example:
grid.getColumnFormatter().setWidth(0, "10%");
grid.getColumnFormatter().setWidth(1, "10%");
Only styleName is taken into account on g:row, g:cell and g:customCell elements.
If you can (i.e. if your grid content is mostly static), avoid using Grid and prefer an HTMLPanel containing an HTML <table>, this gives you much more flexibility.
http://code.google.com/p/google-web-toolkit/source/browse/tags/2.4.0/user/src/com/google/gwt/uibinder/elementparsers/GridParser.java

How to implement i18n in GWT application?

I have a problem with internationalization. I'm trying to implement support two languages ​​in my GWT application. Unfortunately I never found a complete example how to do it with the help of UiBinder. That is what I did:
My module I18nexample.gwt.xml:
<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='i18nexample'>
<inherits name="com.google.gwt.user.User" />
<inherits name='com.google.gwt.user.theme.clean.Clean' />
<inherits name="com.google.gwt.i18n.I18N" />
<inherits name="com.google.gwt.i18n.CldrLocales" />
<entry-point class='com.myexample.i18nexample.client.ExampleI18N' />
<servlet path="/start" class="com.myexample.i18nexample.server.StartServiceImpl" />
<extend-property name="locale" values="en, fr" />
<set-property-fallback name="locale" value="en" />
</module>
My interface Message.java:
package com.myexample.i18nexample.client;
import com.google.gwt.i18n.client.Constants;
public interface Message extends Constants {
String greeting();
}
The same package com.myexample.i18nexample.client has three properties file:
Message.properties:
greeting = hello
Message_en.properties:
greeting = hello
Message_fr.properties:
greeting = bonjour
My UiBinder file Greeting.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"
ui:generateFormat="com.google.gwt.i18n.rebind.format.PropertiesFormat"
ui:generateKeys="com.google.gwt.i18n.rebind.keygen.MD5KeyGenerator"
ui:generateLocales="default" >
<ui:with type="com.myexample.i18nexample.client.Message" field="string" />
<g:HTMLPanel>
<ui:msg key="greeting" description="greeting">Default greeting</ui:msg>
</g:HTMLPanel>
</ui:UiBinder>
When the application starts, I always get the output in the browser:
Default greeting
Why? What am I doing wrong?
I tried to run the application from different URL:
http://127.0.0.1:8888/i18nexample.html?gwt.codesvr=127.0.0.1:9997
http://127.0.0.1:8888/i18nexample.html?locale=en&gwt.codesvr=127.0.0.1:9997
http://127.0.0.1:8888/i18nexample.html?locale=fr&gwt.codesvr=127.0.0.1:9997
The result does not change. Although I expected in last case a message bonjour.
If for example I use a g:Buttton instead of the message ui:msg:
<g:HTMLPanel>
<g:Button text="{string.greeting}" />
</g:HTMLPanel>
Then I get as a result of the button with text "hello"
And if I enter the URL:
http://127.0.0.1:8888/i18nexample.html?locale=fr&gwt.codesvr=127.0.0.1:9997
The text on the button changes to "bonjour". Here everything works as expected. But why internationalization is not working in my first case?
And whether there is a difference between the following:
<ui:msg description="greeting">Default greeting</ui:msg>
<ui:msg description="greeting">hello</ui:msg>
<ui:msg description="greeting"></ui:msg>
Should there be different results in these cases? How to write properly?
Please explain to me the principles of internationalization in GWT and why my example does not work.
Any suggestions would be greatly appreciated.
First, the files should be named Message_fr.properties (resp. Message_en.properties), not Message.properties_fr (resp. Message.properties_en).
Then ui:msg et al. in UiBinder will generate an interface (extending com.google.gwt.i18n.client.Messages)), not use one that you defined. For that, you have to use {string.greeting} (where string is the ui:field you gave to your ui:with). The UiBinder generator will do a GWT.create() on the type class of your ui:with, which is what you'd have done in Java code:
Message string = GWT.create(Message.class);
String localizedGreeting = string.greeting();
In the implicit Messages interface (generated by UiBinder), the various ui:generateXxx attributes on the ui:UiBinder will be transformed into annotations on the interface (properties of the #Generate annotation, or the value of the #GenerateKeys annotation).
Then, one method will be generated for each ui:msg, where the attributes generate equivalent annotations (#Key, #Description) and the content of the ui:msg element is the value of the #DefaultMessage annotation. When you have or widgets inside the content, they'll be turned into arguments to the method and placeholders in the #DefaultMessage text (the values will be filled by UiBinder).
I'd suggest you make something working without UiBinder first, and understand how it works; then try the ui:msg in UiBinder, using -gen in DevMode or the compiler so you can see exactly what code does UiBinder generate (yes, it really only generates code that you could have written yourself by hand).
Also, you should add a <set-property name="locale" value="en, fr" /> or you'll still have the default locale around, despite the set-property-fallback (it'd just never be used)).

Grid + UiBinder : Setting row level styles

...........
.........
<g:row styleName="OddNumberRow">
....
....
</g:row>
<g:row styleName="EvenNumberRow">
....
....
</g:row>
...........
...........
The above approach is not working. In other words, the "tr" elements in the generated html do not have any class names at all. A back up option would be to inject styles into these rows from the UiBinder's constructors (using getRowFormatter.addStyleName) but
I do not want to take that route for now.(I wanna try to reserve the code that goes into the UiBinder java class for event handling purposes only. )
Any thoughts/pointers would be much appreciated.
Note: Cross posted at https://groups.google.com/forum/?fromgroups#!topic/google-web-toolkit/yGRUkpcpBzU
thanks
You are right, this does not work. I have also tried adding the style to g:customCell, which does not work either.
The only way I can think of is using a SimplePanel to wrap your content in:
<g:row>
<g:customCell>
<g:SimplePanel width="100%" height="100%" styleName="OddNumberRow">
<g:Label>Content</g:Label>
</g:SimplePanel>
</g:customCell>
</g:row>
<g:row>
<g:customCell>
<g:SimplePanel width="100%" height="100%" styleName="EvenNumberRow">
<g:Label>Content</g:Label>
</g:SimplePanel>
</g:customCell>
</g:row>
It looks like GWT has been updated to understand styleName=foo directly on <gwt:cell> and <gwt:row> elements.
Your example code should now do what you expect :)