public interface HasData<T> {
public T getData();
public void setData(T data);
}
Maybe I'm just not seeing your use case.
First, some definitions (please excuse the crudity of these models. I
didn't have time to build them to scale):
public interface HasData<T> {
public T getData();
public void setData(T data);
}
public abstract class Form<T> extends Composite implements HasData<T> {
// Some reusable form-y stuff here.
}
public abstract class ContrivedReadOnlyWidget<T> extends Composite
implements HasData<T> {
// A contrived example of something else that HasData.
}
public class Foo {
// My data
}
public class LoadFooCommand implements Command {
private String fooId;
private HasData<T> dataWidget;
public LoadFooCommand(String fooId, HasData<Foo> dataWidget) {
this.fooId = fooId;
this.dataWidget = dataWidget;
}
// Load the Foo with the specified into the dataWidget.
public void execute() {
Foo myFoo = getFoo(fooId);
dataWidget.setData(myFoo);
}
}
I have a pattern very close to this in my current project. Basically,
I can reuse simple Commands to do things like populate forms or
display pages with existing database records.
What would you do with the DataManager interface in this example? Or
if it doesn't apply in this example, what would be an example of how
it would be used?
I'm not with Isaac. My first experience working with data binding was
as a co-op student working on the UI team on the Eclipse project at
OTI. That was a very educational co-op term! Eclipse, at least in
version 2--I've lost track since then, has a very clear separation
between SWT, the widget kit, and JFace, the "data binding" library
that sits on top of SWT.
In my mind, a Widget has a specific job to do--get displayed in an
application and, when appropriate, react to user manipulation.
Teaching basic widgets to know about "data" is a bad idea, IMO,
because it makes basic widgets too complicated. It also puts a lot of
pressure on programmers to use the data binding model that's baked
into the widgets, even if that model doesn't really suit a given
application. In fact, I think Isaac's comments may be an example of
this--he's built himself a model for doing data binding and, at first
blush, it looks like it doesn't match with Arthur's. It also seems
like neither Arthur's nor Isaac's model fits with the model that I
built and am frantically documenting in preparation for releasing
here. If any of our models is chosen as The GWT Way and baked into
the basic widgets, the others are probably out of luck. Instead, I
think a data binding library should be built on top of a widget
library for two main reasons: you can switch data binding libraries
more easily and, perhaps more importantly, you don't have to use any
data binding library at all.
Ian
> Right now, extracting data from widgets is very different depending on the widget.
Most of the Widgets could implement HasData<String> and solve this
problem (See Ray's post while I was writing this). DataManagers and
complex but separated Model/View schemes could be based on that.
HasData is a tool for normalizing APIs which would make building data
binding, validation, and other libraries easier.
On Fri, Oct 3, 2008 at 12:38 PM, Ray Ryan <rj...@google.com> wrote:
> I think you're reading too much into the word "data."
That might be true....
> Suppose that you could already rely on TextField implements
> HasValue<String>, CheckBox implements HasValue<Boolean>. How would that
> interfere with the work you're doing now? Might it simplify it any?
Perhaps. What would ListBox implement? HasData<String> or
HasData<List<String>> (ie. do we assume single-select or
multi-select)? Would Label implement HasData<String>? Does
HasData<T> imply SourcesChangeEvents (or the gen2 equivalent)? Would
it be useful to do something like the following? (I've done
essentially this in my library)
public interface DisplaysData<T> {
void setData(T data);
}
public interface HasData<T> extends DisplaysData<T> {
T getData();
}
Maybe Label would implement DisplaysData<String> while TextBox would
implement HasData<String>. DisplaysData<T> wouldn't imply
SourcesChangeEvents but HasData<T> might.
Ian
/**
* Gets the currently-selected item. If multiple items are selected, this
* method will return the first selected item ({@link #isItemSelected(int)}
* can be used to query individual items).
*
* @return the selected index, or <code>-1</code> if none is selected
*/
public int getSelectedIndex() {
return getSelectElement().getSelectedIndex();
}
To me, this indicates an existing single-select bias. On that basis, I
would say that ListBox implements HasValue<String>. Or...
interface HasValue<T> {
T getValue();
void setValue(T value);
}
interface HasValues<Collections<T>> extends HasValue<T> {
Collection<T> getValues();
void setValues(Collection<T> values);
}
I'm shooting from the hip there, but at first glance it makes sense.
Then ListBox implements HasValues<String> and you get singular methods
which return the first selected item or set the only selected
(removing any other selections) item. The plural methods obviously get
and set all selected items.
> Would Label implement HasData<String>?
Yes. HasData<String> would essentially replace HasText, wouldn't it?
(As an aside, if HasData<String> replaces HasText, perhaps HasText
should be "redefined" to extend HasData<String>.)
Ray talked about creating a "uniform way to find out what value a
widget is showing" and Isaac described HasData<T> as "a tool for
normalizing API". I think those are key ideas. As such, I think we
need to go one step further. HasData<T> should imply
SourcesChangeEvents, or maybe SourcesDataChangeEvents<T>. A TextBox
certainly HasData<String>, but I think it's equally important that the
user can change the data in the text box. Any data binding library is
going to have to listen for updates from the widgets that are capable
of editing a value, and I think normalizing the notification of those
changes is at least as useful as normalizing the display of values.
In particular, I think CheckBox would benefit from
SourcesDataChangeEvents<Boolean>.
If you buy my argument that HasData<T> needs to imply
SourcesDataChangeEvents<T>, then I think it follows that Label should
not implement HasData<T>. Something like HasReadOnlyData<T> (like
Emily suggested) would be necessary to bridge the gap between
"editors" and "viewers".
On a completely different note, I just noticed that RadioButton
inherits from CheckBox. Does it make sense for RadioButton to
implement HasData<Boolean>? To me, a collection of RadioButtons is
roughly equivalent to a single-select ListBox and, as such,
RadioButton implementing HasData<Boolean> is somewhat nonsensical,
whereas a collection of RadioButtons should probably implement
HasData<String>, or something similar.
Ian
Sorry to nitpick, but I hope that DropDownListBox is not the only way
to get a single-select list box--sometimes it's useful to have a
single-select list box that is not a drop-down. I'd be happy with
either SingleSelectListBox and DropDownListBox being sibling classes
or SingleSelectListBox having a way to toggle between drop-down and
not-drop-down modes.
+1 to everything else you said.
Ian