Generic widget in UiBinder
Asked Answered
G

3

5

I just created widget:

public class myWidget<T> extends FlowPanel {
private T value;

public T getValue()
{
    return value;
}

public myWidget(T[] values) {
    for (T value : values)
    {
        //do action
    }
}

How can I add it using UiBinder? Is it possible at all?

Gentility answered 9/8, 2012 at 16:35 Comment(1)
If you're only asking if using generics is a problem, then the answer is: You can do it the same way as regular widgets. GWT will instantiate the widget and put it in your @UiField field, even if you can't specify the generic type in the xml file.Aimee
C
7

Yes you can. You have to import the package which contains the myWidget class into an XML namespace. Say your package is called com.test.widgets, the declarative layout looks like this:

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
    xmlns:g='urn:import:com.google.gwt.user.client.ui'
    xmlns:my='urn:import:com.test.widgets'>

  <my:myWidget>
    <g:Label>A label</g:Label>
    <g:Label>A second label</g:Label>
  </my:myWidget>
</ui:UiBinder>

Note the import xmlns:my='urn:import:com.test.widgets' and the usage <my:myWidget>.

Cynosure answered 10/8, 2012 at 6:41 Comment(0)
S
4

To have your widget usable in Uibinder it must implement at least IsWidget interface. Being a widget already, it of course already implements IsWidget.

Therefore, any non-widget could also be used as a child widget element in uibinder by having it implement IsWidget.

The IsWidget interface requires the non-widget to implement the method asWidget(). Therefore, such a non-widget would have to act as a widget container.

Implementing IsWidget will only allow the class to be used as a child widget element.

Let's say your class is

com.zzz.client.ui.HelloKitty

In order for it be able to have child widget elements, it must implement HasWidgets.

<ui:UiBinder
  xmlns:ui='urn:ui:com.google.gwt.uibinder'
  xmlns:g='urn:import:com.google.gwt.user.client.ui'
  xmlns:z='urn:import:com.zzz.client.ui'>

  <g:VerticalPanel>
    <z:HelloKitty>
      <g:button ..../>
      <g:textbox>asdf</g:textbox>
    </z:HelloKitty>
  <g:VerticalPanel>

</ui:UiBinder>

Or, it could also just implement HasOneWidget.

In order to allow the class to have text between its uibinder tags, it must implement HasText.

<ui:UiBinder
  xmlns:ui='urn:ui:com.google.gwt.uibinder'
  xmlns:g='urn:import:com.google.gwt.user.client.ui'
  xmlns:z='urn:import:com.zzz.client.ui'>

  <g:VerticalPanel>
    <z:HelloKitty>qwerty</z:HelloKitty>
  <g:VerticalPanel>

</ui:UiBinder>

In order to accept valid HTML between its tags, I believe you should have it implement HasHTML.

Shelleyshellfire answered 10/8, 2012 at 7:26 Comment(0)
K
0

None of the answers seem to focus on the generic part. As mentioned by others, you can easily add a generic widget in an UiBinder template by omitting the generic types:

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
             xmlns:g='urn:import:com.google.gwt.user.client.ui'
             xmlns:my='urn:import:com.test.widgets'>
    <my:myWidget />
</ui:UiBinder>

But, what about if you want to reference this widget in your Java code? Should you omit the generic type there too and incur the wrath of the compiler's warning?

Thankfully, no. UiBinder is pretty loose when it comes to types and since generic types are just hints, you can get away with the following in the Java code backing the above UiBinder template:

@UiField(provided = true)
myWidget<Date> myWidget = new myWidget(new Date(), new Date());

Alternatively, you can also use an @UiFactory method, as mentioned in the documentation.

Kurman answered 22/10, 2014 at 23:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.