I'm liking the new GWT2 UiBinder, however, it's not clear whether certain things are achievable using the declarative UI style.
For instance, ToggleButton only takes the image instances at construction time (no setters for up/down images). As I understand, UiBinder works in a JavaBean-like reflective way, where the assignable attributes are mapped to corresponding setters. Is this style possible with widgets like ToggleButton, where certain attributes have to be specified at construction time?
<g:ToggleButton ui:field="myBtn"></g:ToggleButton>
#Matt Moriarity: Thanks for the tip! I found I had to do it like this:
<g:ToggleButton ui:field="foo">
<g:upFace><img src="images/bar.png"/></g:upFace>
</g:ToggleButton>
If you don't specify other faces (e.g. downFace), that image is used for all button states.
Edit: I guess you use ui:image when you're formally specifying external resources?
You can create these widgets using a #UiFactory or by providing it using #UiField(provided=true)
See http://code.google.com/webtoolkit/doc/latest/DevGuideUiBinder.html#Using_a_widget
Try something like this:
<g:ToggleButton>
<ui:image src="..." />
</g:ToggleButton>
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
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).
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 would like to do absolute layout using said panel by only using ui.xml file however it isn't clear if this is possible since the documentation concentrates on the code and ignores the layout language altogether. I'm assuming, since the tutorial doesn't mention this, it is impossible but would like to know for sure.
I know this is old, but they updated the uibinder for AbsolutePanel
Use in UiBinder Templates
AbsolutePanel elements in UiBinder
templates lay out their children with
absolute position, using
elements. Each at element should have
left and top attributes in pixels.
They also can contain widget children
directly, with no position specified.
For example:
<g:AbsolutePanel>
<g:at left='10' top='20'>
<g:Label>Lorem ipsum...</g:Label>
</g:at>
<g:Label>...dolores est.</g:Label>
</g:AbsolutePanel>
You are right - there's no way to do this at the moment. This could be addressed in a future GWT release by introducing some custom syntax, like it was done for DockLayoutPanel. But I doubt it - you'd want to write code like this:
<g:AbsolutePanel ui:field="absolutePanel">
<g:Button x="50px" y="50px">Test</g:Button>
</g:AbsolutePanel>
However this conflicts with the "bean" (as in Java Beans; if you have a getSomethingCool method, you can write somethingCool="kewl" in the UiBinder code and it will autmagically call the appropriate get/set method) style - because Button doesn't have a setX/Y method. This could be bypassed by replacing the setX/Y calls with appropriate calls to existing methods (CSS positioning, etc) at compile time. But this introduces yet another custom behavior, dependent on the wrapping Widget/Panel - I think the GWT devs would like to avoid that.