Suppose I have a <String,String> map defined in my i18n .properties files, e.g.:
userGroupMap = 0, 1, 2, 3
0=Factory
1=Administrators
2=Superusers
3=Operators
The dev guide explains that introducing a corresponding Map<String,String> userGroupMap() method in MyConstants implements Constants interface will result in calls such as MyConstants.userGroupMap().get("1") returning the localized "Administrators". So far so good.
What about UiBinder? How do I use one of the mapped values in a UiBinder template? Is there a syntax I'm missing, e.g. <ui:msg key="userGroupMap:1">Administrators</ui:msg> (doesn't actually work)?
One way you could do this would be a non-xml solution, but you could use a #UiFactory to help with the creation of the specific fields or labels that you need I18N'd. But to me, this particular problems seems like it begs the solution below, since you seem to be looking to decouple your widgets from your screen or panel layouts.
I struggled with this, and for my implementation, I ended up making core widgets with UiBinder backing for their internals(for instance a label and a text field with a help button), and then passing in a 'fieldKey' that was used as a prepender for all the I18N keys in the various maps.
For instance, for the PartNumber field, I had a key in the following maps: labelTexts(), helpTexts(), tooltipTexts(), defaultFieldValues(). Then in the constructor for that widget, I would pass in the string key 'partNumber', and that would be used to build up all the keys needed, so I would call labelTexts().get('partNumberLabelText'), helpTexts().get('partNumberHelpText'), etc.
I didn't want to do this directly in UiBinder, since I wanted the widget key to map back to it's display information, so I could create a widget with as little input information as possible, in many cases just the key and then the widget (provided it was configured in the I18N setup correctly) would just populate everything from the maps based on that.
From a design standpoint, for me it didn't make sense to have separate UiBinders for the screen sets, they were composited from objects that defined the screen layout and relation of all the widgets (meaning that you could define screen content at runtime).
Related
Are there any advantages (other than clean code and the like) of using #UiFactory to construct widgets as opposed to declaring them in #UiField and then making additions/changes in the code after the initWidget()?
You can of course use #UiField to let UiBinder instantiate the fields for you during createAndBindUi(). You can then modify them afterwards.
You can of course use #UiField(provided=true), and instantiate the fields yourself, before calling createAndBindUi(). (This way, you can use any constructor you like, and it also allows for Dependency Injection.) And obviously, you can still modify them after createAndBindUi().
So what's the point of #UiFactory? Well, I use it sometimes, when I have many similar elements in the same ui.xml file. So e. g. I have a page that shows a keypad with digits 0-9. Instead of having ten #UiFields, I prefer to use #UiFactory, which constructs the widgets, and puts them in a java.util.Map (plus performs some common setup).
There might be parameters to your UiBinder file that can not be constructed using a simple constructor (e.g. a CssResource to share styles across many UiBinder files).
Using #UiFactory you can inject those resources into your UiBinder file.
What would be the best approach to implement a form with a variable number of text fields? I'm thinking something like this:
textField1 (removeButton)
textField2 (removeButton)
textField3 (removeButton)
addNewTextFieldButton
I would like this to bind to a list of strings.
I achieved this with an editable grid with a single column and buttons to add/delete rows.
This component is very well integrated with GWT Editor framework so you can bind your grid to a list of objects using a ListStoreEditor
The best approach would be to use the GWT Editor framework. GXT's fields are very well integrated with the Editor framework.
Here is a very rough example of how you might approach this problem.
You would start by creating one Editor for the thing you are wanting to bind to. In your case, I think a composite which contains a TextField (which is bound to the string) and a button. The button won't actually bind to anything, but you will provide a way for something which uses this class to register a SelectHandler against it. Let's call this editor SubEditor.
Once you create a UI component which is designed to bind to one string, you will next create a ListEditor<String, SubEditor> which will bind to a List<String> which will compose a view, consisting of one SubEditor per each String in the bound list.
You don't really need to create the SubEditor, as you could construct something as simple as what you want within your ListEditor's EditorSource class (read through the tutorials on ListEditors).
Again, I want to emphasize the this is a ROUGH example on how to get started. I hope there is enough information here for you to fill in the pieces.
The following SO question has helped me out a lot:
Using GWT Editors with a complex usecase
Having used Wicket recently, I've come to really appreciate its RepeatingView and ListView objects.
They essentially allow you to specify the format of a "row" of data in an HTML template (which roughly corresponds to a UIBinder Foo.gwt.xml), and then in the corresponding Java class you loop over some data, which is then formatted and displayed according to the template.
The GWT version of this seems to require defining a brand new Row.gwt.xml template and Row.java class, which you then reference from the containing Foo.gwt.xml and Foo.java class.
Is there a way to do something like this in a single GWT UIBinder file/class, without creating a subsidiary Row.gwt.xml and Row.java?
does this help ?
http://ptrthomas.wordpress.com/2008/09/04/wicket-and-gwt-compared-with-code/
I'm just going through the GWT Tutorial and one point which just don't understand is when and why to use dependent secondary styles. If I define a style in the .css stylesheet, and use the addStyleName method it seems to have the same effect.
E.g. applying a secondary dependent style to a button or applying the it as a non-dependant style seems to yield the exact same results.
Basically the dependent name is more general, since it's calculated at runtime. You can add a dependent name of "highlighted" to any Widget without knowing what it is, and GWT will come up with the appropriate css class name for you. You don't have to hard code button-highlighted, select-highlighted, mycustomthing-highlighted in GWT this way (you do still need to create them all in your css code).
I want to make a table of data in a UiBinder. I need programmatic access so I can add data at runtime, but I'd like my designer to have access to header names, column styles, etc, in the ui.xml file.
Is there a solution that meets these needs? A Grid perfectly satisfies my programmatic access, but I don't see a way to specify rows or cells in a Grid from the ui.xml.
I'd let the designers change the style via CSS files: Either include those in your host page, or use CssResource in a ClientBundle.
The header names etc. can be provided e. g. by properties files via GWT's internationalization Constants (even if you only want to support one language).
If you want to go one step further, and let the designer specify, which columns to show, and in which order, then it might be a good idea to create your own widget. Maybe the CricketScores example serves as a good starting point on how to use an XML attribute to specify the columns from your ui.xml.