I am attempting to initialise a TreeItem
with a Widget
defined within a UI Binder template as the TreeItem
's content. Initially I started with a template like this:
<g:Tree>
<g:TreeItem>
<g:HTMLPanel>
<p>This is the root item's content.</p>
</g:HTMLPanel>
<g:TreeItem>
<g:HTMLPanel>
<p>This is the child's content.</p>
</g:HTMLPanel>
</g:TreeItem>
</g:TreeItem>
</g:Tree>
Expecting to end up with a tree structure something like this:
+ This is the root item's content.
Expanding to:
- This is the root item's content.
\ This is the child's content.
But this doesn't work. The HTMLPanel
widgets are created as children of the TreeItem
s, rather than being the items' widgets, so I end up with a structure like this:
- (root item has no content)
\ This is the root item's content.
- (first child has no content)
\ This is the child's content.
So I tried extending the TreeItem
class like so:
public class WidgetTreeItem extends TreeItem {
@UiChild(tagname="widget", limit=1)
public void setWidget(IsWidget isWidget) {
super.setWidget(isWidget.asWidget());
}
}
And then, importing the package containing WidgetTreeItem
into the c
namespace, I have a template like this:
<g:Tree>
<c:WidgetTreeItem>
<c:widget>
<g:HTMLPanel>
<p>This is the root item's content.</p>
</g:HTMLPanel>
</c:widget>
<!-- Should create a child TreeItem with the HTMLPanel as its Widget. -->
<g:HTMLPanel>
<p>This is the child's content.</p>
</g:HTMLPanel>
</c:WidgetTreeItem>
</g:Tree>
But this doesn't work, either. It fails with the following exception:
Only TreeItem or Widget subclasses are valid children: <c:WidgetTreeItem>
.
Can anyone see how to achieve what I am attempting?
Given a little inspiration from this answer, I have found my solution. Given my original example, the XML now looks like this:
<g:Tree>
<g:HTMLPanel ui:field="rootContent">
<p>This is the root item's content.</p>
</g:HTMLPanel>
<g:HTMLPanel ui:field="childContent">
<p>This is the child's content.</p>
</g:HTMLPanel>
<g:TreeItem widget="{rootContent}">
<g:TreeItem widget="{childContent}">
</g:TreeItem>
</g:TreeItem>
</g:Tree>
Some playing around was required here. Most notably, this only works provided that the content panels are contained within a widget implementing the HasWidgets
interface. The Tree
class satisfies this requirement. It is also worth noting that the content fields must be defined before they are used.