Custom Composite widget in *.ui.xml - gwt

I would like to create a custom GWT composite widget that I can later use this way in *.ui.xml using uiBinder (cw is prefix for my custom widgets package):
<cw:CustomPanel>
<cw:header><g:Label>test</g:Label></cw:header>
<cw:content><g:Label>test</g:Label></cw:content>
</cw:CustomPanel>
In short, I would expect that setHeader and setContent methods on my custom widget are called by the framework somehow.
Is that at all possible?

This is what #UiChild is for, see the JavaDoc at http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/uibinder/client/UiChild.html
If you want to keep the method names setHeader and setContent (instead of addHeader and addContent), you'll have to use
#UiChild(tagname = "header")
void setHeader(Widget headerWidget) {
...
}

Create setHeader(String title) and setContent(String content) methods in your widget's Java class. In these methods add text to your header and content panel respectively. Then you can use this widget in Ui:Binder this way:
<cw:CustomPanel header="test" content=test" />

Related

GXT UiBinder FieldLabel

I am new to UiBinder and I try to use a FieldLabel.
I found this post : GXT: UiBinder new instance of a Widget
where the developer uses those markups
<form:FieldLabel text="Text">
<form:Widget>
<form:TextField ui:field="text"/>
</form:Widget>
</form:FieldLabel>
When I do exactly the same, I get the following error :
ERROR: Illegal child <form:Widget> in a text-only context. Perhaps you are trying to use unescaped HTML where text is required, as in a HasText widget?: <form:FieldLabel text='Text'> (:7)
It seems that my version of GXT (3.0.1) does not allow to have a non-text-only child for the FieldLabel markup.
Up to now, the only solution I found to include a FieldLabel is to use
#UiField(provided = true)
Is there a better way to use FieldLabel with UiBinder?
The problem is that you shouldn't capitalize form:widget:
<form:FieldLabel text="Text">
<form:widget>
<form:TextField ui:field="text"/>
</form:widget>
</form:FieldLabel>
In UiBinder, elements with a capital letter represent a real Widget subclass, while lowercase elements are either a regular html dom element, or some modifier for the parent widget tag. We can see that this is not a dom element because of the form: namespace, the same as the parent widget tag (i.e. <form:FieldLabel>).
How this works: The FieldLabel class has a Java method to give it the widget to display - setWidget. This method is decorated with a #UiChild annotation (in its superclass):
#Override
#UiChild(limit = 1, tagname = "widget")
public void setWidget(Widget w) {
//...
This enables you, the UiBinder user, to refer to a tag as widget, and have that method invoked with whatever contents you enter.

GWT UiBinder: How to make a custom AbsolutePanel which uses the "at" element?

Trying to extend AbsolutePanel, my UiBinder won't allow the <g:at> element which is normally ok for straight AbsolutePanels. How do I make my AbsolutePanel subclass able to use the <g:at> element? And more generally, can I make custom UiBinder keywords for my own custom Widgets like "at", "west", "layer" etc.?
You can use #UiChild to declare special functions in your widgets accessible in UiBinders.
for example,
class MyPanel extends AbsolutePanel {
#UiChild
public void addAt(Widget w, String parameter1, String parameter2) {
....
Then, in your uiBinder, you can say
<custom:MyPanel>
<custom:at parameter1="HI" parameter2="Anything you like!">
<g:AnySingleWidget />
</custom:at>
</custom:MyPanel>
See #UiChild at http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/uibinder/client/UiChild.html

How to expose table widget to presenter in MVP pattern with gwt

In MVP pattern the widget (the view) exposes its widgets in form like this:
#Override
public HasClickHandlers getAddIssueClickHandlers() {
return addIssueButton;
}
and like:
#Override
public HasText getTaskName() {
return taskName; // taskName is a Label
}
To allow the presenter to modify the view or get the values from a widget. However, its uncertain how to get a table widget, like FlexTable or CellTable in order for the presenter to modify the table. Any ideas is much appreciated. Thanks.
Not all GWT widgets were designed with these interfaces (i.e. HasclickHandlers, HasText, IsWidget, etc) in mind.
In recent GWT versions the basic widgets were changed so that they implement these interfaces in order to make the views which use them testable in unit tests. So I am not sure if the FlexTable implements these interfaces but in case of CellTable you can use the HasData interface.
Here you can find the interfaces that are implemented by the CellTable: Javadoc
I personally would expose the CellTable via the HasData interface, which can be used to set and retrieve the selectionModel (for selecting rows in the CellTable).
For modifying or updating the data that is displayed in the CellTable, I would use a ListDataProvider and store it in the Presenter.
#Override
public HasData getCellTableDisplay() {
return cellTable;
}
and in the constructor of the presenter
you can create a ListDataProvider and use the addDataDisplay function to add the CellTable:
final ListDataProvider<String> dataProvider = new ListDataProvider<String>();
dataProvider.addDataDisplay(getView().getCellTableDisplay);

GWT UiHandler on HTMLPanel

I'm writing a widget with the following markup:
<g:HTMLPanel ui:field="shortcutPanel" styleName="{style.shortcut}">
<g:Image ui:field="shortcutImage"></g:Image>
<span ui:field="shortcutLabel"></span>
</g:HTMLPanel>
So essentially a div that wraps and image and a label. Now, instead of adding the event handlers on the image/span, I'd like an onClick to be associated with the HTMLPanel. My problem however is that gwt tells me that
shortcutPanel doesn't not have an addClickHandler method associated
So I'm assuming the difference is that HTMLPanel doesn't implement HasClickHandlers or something along that line. I'm wondering then what is the standard way to attach a click handler to a Ui element such as an HTMLPanel or even better, is there such a GWT Widget that is essentially a div wrapper that I can easily attach events to with the #UiHandler annotation.
You are probably looking for FocusPanel - it has all the goodies: HasAllFocusHandlers, HasAllKeyHandlers, HasAllMouseHandlers, HasBlurHandlers, HasClickHandlers.... to name a few :) I find it to be the easiest and best way to attach click handlers to a Panel.
I haven't done this before, but you could do the following:
Create a custom class MyPanel that extends HTMLPanel and implements HasClickHandlers
Add the following method in MyPanel.java
public HandlerRegistration addClickHandler(ClickHandler handler) {
return addDomHandler(handler, ClickEvent.getType());
}
Then replace HTMLPanel with MyPanel in your ui.xml and its corresponding Java implementation.
You can always look at the implementation of HTMLTable to get an understanding of how the event propagation works. It's a Panel and implements HasClickHandlers.
If you want to use the #UiHandler annotation to register event handlers for your custom widget, you need to re-implement the addXXHandler methods. The GWT compiler doesn't seem to find those in superclasses. e.g. if you want to use
#UiHandler("myCustomWidget")
public void handleWidgetSelectionChangeEvent(final SelectionEvent<CountryDts> event) {
...
}
and your CustomWidget extends a class for which this is working, you might need to add the HasSelectionHandlers interface explicitly to your class:
public class CustomComboBox<D> extends ComboBox<D> implements HasSelectionHandlers<D> {
#Override
#SuppressWarnings("pmd.UselessOverridingMethod")
public HandlerRegistration addSelectionHandler(final SelectionHandler<D> handler) {
// GWT Compile doesn't recognize method in supertype for UIHandler
return super.addSelectionHandler(handler);
}
...
}

GWT uibinder composite

I'm creating a composite uibinder widget with a Label and a TextBox.
The intented use is:
<x:XTextBox ui:field="fieldName" label="a caption" >
The text to be put in the box.
</x:XTextBox>
I've found how to catch the label with a custom #UiConstructor constructor, I might add another parameter to the constructor, but I would like to know how to get the text from the xml, just like the GWT tag <g:Label>a caption</g:Label> does.
Any help is greatly appreciated.
I've found a possible implementation by looking at the Label widget source code.
The key point is that the composite widget must implement the HasText interface. so in the declaration and in the body:
public class XTextBox extends Composite implements HasText ...
...
#UiField TextBox textBox;
...
public void setText(String text) {
textBox.setText(text);
}
public String getText() {
return textBox.getText();
}
...
Just put the text into another parameter of your widget and have your #UiConstructor take that parameter. That is:
<x:XTextBox ui:field="fieldName" label="a caption"
text="The text to be put in the box." />
Then your XTextBox.java will have this:
#UiField TextBox textBox;
#UiConstructor XTextBox(String label, String text) {
initWidget(uiBinder.createAndBindUi(this));
textBox.setValue(text);
}
Han is right; HasText is what you need to implement. One thing I found handy is to browse the source if you know a Google widget does something you'd like to do also. e.g.
http://www.google.com/codesearch/p?hl=en#A1edwVHBClQ/user/src/com/google/gwt/user/client/ui/Label.java