I am using GWT 2.5.0
My intent was to create an editor hierarchy which binds to a ParentBean
object. The ParentBean
contains a List<Group>
, and the Group
bean has a List<ChildBean>
and List<Group>
. From the Editor tutorials I have found, it seemed simple enough to create an editor which contains a ListEditor as one of its sub-editors. But the parent editor never seems to properly initialize the sub ListEditor.
Here is an explanation of how I attempted to do this.
From the code below, I created a ParentBeanEditor
which is composed of one other editor, GroupListEditor
.
The GroupListEditor
implements IsEditor<ListEditor<Group, GroupEditor>>
.
Then, the GroupEditor
contains a GroupListEditor
subeditor and a ChildBeanEditor
.
I initialized the ParentBeanEditor
with a ParentBean
which contained a list of Group
objects, but no GroupEditor
was ever constructed for any of the Group
objects.
I put break points in the EditorSource<GroupEditor>.create(int)
method to verify that GroupEditor
s were being created for each Group
in the ParentBean
, but the break point was never hit (the ListEditor was not constructing editors).
I expected that the GroupListEditor
would be initialized since it was a subeditor of ParentBeanEditor
. Neither the list nor the editor chain was set in the GroupListEditor
. I tried to set the list of the GroupListEditor
subeditor directly in ParentBeanEditor
by having it extend ValueAwareEditor<ParentBean>
. Doing this, the break point I mentioned above was hit, and the GroupListEditor
tried to attach a GroupEditor
to the editor chain. But the editor chain was never set, and a NPE is thrown in ListEditorWrapper
line 95.
Example
Here is the example where the GroupListEditor
is not initializing as expected. The EditorChain
is never set, and this results in a NPE being thrown in ListEditorWrapper
line 95.
Data Model
public interface ParentBean {
...
List<Group> getGroups();
}
public interface Group {
...
List<ChildBean> getChildBeans();
List<Group> getGroups();
}
public interface ChildBean {
// ChildType is an enum
ChildType getChildType();
}
Editors
The ParentBean Editor
public class ParentBeanEditor extends Composite implements ValueAwareEditor<ParentBean> {
interface ParentBeanEditorUiBinder extends UiBinder<Widget, ParentBeanEditor> {
}
private static ParentBeanEditorUiBinder BINDER = GWT.create(ParentBeanEditorUiBinder.class);
@Path("groups")
@UiField
GroupListEditor groupsEditor;
public ParentBeanEditor() {
initWidget(BINDER.createAndBindUi(this));
}
@Override
public void setDelegate(EditorDelegate<ParentBean> delegate) {}
@Override
public void flush() {}
@Override
public void onPropertyChange(String... paths) {}
@Override
public void setValue(ParentBean value) {
groupsEditor.asEditor().setValue(value.getGroups());
}
}
GroupListEditor
public class GroupListEditor extends Composite implements IsEditor<ListEditor<Group, GroupEditor>>{
interface GroupListEditorUiBinder extends UiBinder<VerticalLayoutContainer, TemplateGroupListEditor> {
}
private static GroupListEditorUiBinder BINDER = GWT.create(GroupListEditorUiBinder.class);
private class GroupEditorSource extends EditorSource<GroupEditor> {
private final GroupListEditor GroupListEditor;
public GroupEditorSource(GroupListEditor GroupListEditor) {
this.GroupListEditor = GroupListEditor;
}
@Override
public GroupEditor create(int index) {
GroupEditor subEditor = new GroupEditor();
GroupListEditor.getGroupsContainer().insert(subEditor, index);
return subEditor;
}
@Override
public void dispose(GroupEditor subEditor){
subEditor.removeFromParent();
}
@Override
public void setIndex(GroupEditor editor, int index){
GroupListEditor.getGroupsContainer().insert(editor, index);
}
}
private final ListEditor<Group, GroupEditor> editor = ListEditor.of(new GroupEditorSource(this));
@UiField
VerticalLayoutContainer groupsContainer;
public GroupListEditor() {
initWidget(BINDER.createAndBindUi(this));
}
public InsertResizeContainer getGroupsContainer() {
return groupsContainer;
}
@Override
public ListEditor<Group, GroupEditor> asEditor() {
return editor;
}
}
GroupEditor
public class GroupEditor extends Composite implements ValueAwareEditor<Group> {
interface GroupEditorUiBinder extends UiBinder<Widget, GroupEditor> {}
private static GroupEditorUiBinder BINDER = GWT.create(GroupEditorUiBinder.class);
@Ignore
@UiField
FieldSet groupField;
@UiField
@Path("childBeans")
ChildBeanListEditor childBeansEditor;
@UiField
@Path("groups")
GroupListEditor groupsEditor;
public GroupEditor() {
initWidget(BINDER.createAndBindUi(this));
}
@Override
public void setDelegate(EditorDelegate<Group> delegate) {}
@Override
public void flush() { }
@Override
public void onPropertyChange(String... paths) {}
@Override
public void setValue(Group value) {
// When the value is set, update the FieldSet header text
groupField.setHeadingText(value.getLabel());
groupsEditor.asEditor().setValue(value.getGroups());
childBeansEditor.asEditor().setValue(value.getChildBeans());
}
}
The ChildBeanListEditor
will be using the polymorphic editor methodology mention here. Meaning that a specific leafeditor is attached to the editor chain based off the value of the ChildBean.getType()
enum. However, I am not showing that code since I am unable to get the GroupListEditor
to properly initialize.
ListEditorWrapper
line 95. I'll revise the question to be more specific. Mea culpa. – Bridgehead