Why not store the IsWidget instances as children in the Panel, instead
of the contained Widget?
At this moment Panels contain a WidgetCollection instance that
contains Widget instances. Why not use store the IsWidget instances.
I don't think this breaks anything as Widget implements IsWidget.
I think this improves the lazy behavior of Widgets.
I love the IsWidget interface as it improves the lazy creation of
widgets, testing, and result in the creation of widget interfaces.
However, at the moment that you want to store it in a panel, you have
to store the contained widget, which leads to nasty situations.
Example:
I have a widget that I add to some Panel:
class TitleWidget implements IsWidget, HasText {}
and the implementation (uses the UiBinder):
class TitleWidgetUi implements LineTitle {
...
...
public Widget asWidget() {
return getEnsureUiWidget();
}
private Widget getEnsureUiWidget() {
if (this.uiWidget == null) { // lazy creation
this.uiWidget = GWT.<TitleWidgetUiBinder>
create(TitleWidgetUiBinder.class).createAndBindUi(this);
}
return this.uiWidget;
}
}
Usage:
Panel panel = new FlowPanel();
panel.add(new TitleWidget(createTitleText()); // panel will store
the contained widget and not the TitleWidget instance
private String createTitleText() {
return "Logged in member: " + getMemberName());
}
As you can see, the title widget contains some member name.
If his member name changes, I iterate through the widgets contained in
Panel and in case it implements HasText, I update the title text.
Code:
for (Widget widget: panel.iterator()) {
if (widget instanceof HasText) {
( (HasText) widget).setText(createTitleText());
}
}
However, this will never work as you would expect as the panel will
contain the Widget contained in the created TitleWidget instance and
not the TitleWidget instance itself. And the contained widget isn't
implementing HasText.
The above situation is common I think as the member name is contained
in a global data model and I don't allow listeners to subscribe them
self because of possible memory leaks. Memory leaks can easily occur
when widget are added and removed and don't remove their listener.
This was what happened in the past, so I changed this (we don't have
weak listeners in gwt/javascript like in swt). So a changed member
name is pushed on the event bus, controllers will receive it and
further distribute it to the potential interested widgets.
I might react: Stupid that a widget doesn't remove his listener when
removed. Of course, this would be the perfect case, but in complex
situations it's easily forgotten and almost unavailable (my
experience)
Work around: let LineTitleUi extend Composite, such that Panel will
store it directly and not the contained widget. but that then you will
loze the lazy behavior and you can't test it anymore outside of GWT.
Especially this latter one is important and important result of the
IsWidget interface.. In this case the IsWidget loses his value and
could also be removed..
What do you think ?
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors