I'd like a way to easily tie a widget back to the business object it is rendering. So when the user interacts with a widget I can easily determine the business object holding the data for that widget.
For example, if we imagine a calendar widget that we're going to implement with an AbsolutePanel. For each appt object we'll add a label to the calendar. Then when a user clicks on a label he can update the appt. So I need to know which appt object that label refers to.
For instance, if we look at the following code; if the label for an appointment receives a click, how can I find out to which appt it represented ? The only solution I can see is to create a ApptLabel sub-class for Label which would hold a reference to its appt. This is fine, but the example illustrates a more general need which is to associate widgets with data objects; however this would mean that every object that has a presence in a view needs to subclass a widget. that seems heavy - I expected to find something in the framework e.g. a string property in a widget that I can set to an object key
other approaches I tried; maintaining a map of Map -- this didnt work as the label object I create doesnt appear to be the same (in terms of the Object.equals which I guess is what HashMap uses)
class WidgetCalendar extends Composite {
AbsolutePanel m_panel = new AbsolutePanel();
m_panel.setStylePrimaryName("calendar");
m_panel.setPixelSize(width, height);
public WidgetCalendar(ArrayList<BomAppt> appts) {
initWidget(m_panel);
for (BomAppt a : appts) {
Label l = new Label();
l.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
// how do I know my BomAppt in here ?
}
m_panel.add(l, someX, someY);
}
}
}
Ideally I can do something like this class WidgetCalendar extends Composite { AbsolutePanel m_panel = new AbsolutePanel(); m_panel.setStylePrimaryName("calendar"); m_panel.setPixelSize(width, height);
public WidgetCalendar(ArrayList<BomAppt> appts) {
initWidget(m_panel);
for (BomAppt a : appts) {
Label l = new Label();
l.setItemData(a.getUniqueId());
l.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
BomAppt a = BomAppt.getApptWithId(e.getItemData())
}
}
m_panel.add(l, someX, someY);
}
}
}
This is the solution where I create a subclass, this seems heavy to me and I'd prefer something simpler
class ApptLabel extends Label {
public ApptLabel(BomAppt a) {
m_a = a;
this.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
m_a.doSomething();
});
}
BomAppt m_a;
}
class WidgetCalendar extends Composite {
AbsolutePanel m_panel = new AbsolutePanel();
m_panel.setStylePrimaryName("calendar");
m_panel.setPixelSize(width, height);
public WidgetCalendar(ArrayList<BomAppt> appts) {
initWidget(m_panel);
for (BomAppt a : appts) {
BomLabel l = new BomLabel();
l.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
// how do I know my BomAppt in here ?
}
m_panel.add(l, someX, someY);
}
}
}