I'm going crazy over what should be a simple procedure. I want to add an
element to a ListView's model, but when I try, it throws an
IndexOutOfBoundsException.

I have a form [1] which contains a ListView and an AjaxSubmitLink which adds
items to the ListView. The only funny thing you might notice with the form
is that ListView's model is employerInfoModel.contactPoints, while the
AjaxSubmitLink is adding items to employerInfoModel.contactPointsSet. This
is because employerInfo's collection of contactPoints is actually a set, but
ListView needs them as a list. In order to get around this, I have two
getters and setters, one that gets the set directly, and one that converts
to and from a list [2].

[1] - public class ContactInfoForm extends Form<EmployerInfo> {

        WebMarkupContainer contactPointsContainer;

        public ContactInfoForm(String id,
CompoundPropertyModel<EmployerInfo> model) {
            super(id, model);

            contactPointsContainer = new
WebMarkupContainer("contactPointsContainer");

            ListView<ContactPoint> contactPointsListView = new
ListView<ContactPoint>("contactPoints", new
PropertyModel<List<ContactPoint>>(employerInfoModel, "contactPoints")) {
                @Override
                protected void populateItem(ListItem<ContactPoint> item) {
                    final ContactPoint cp = item.getModelObject();

                    item.add(new TextField<String>("contactInfo", new
PropertyModel<String>(item.getModel(), "contactInfo")));
                    item.add(new
ContactPointTypesDropDownChoice("contactPointTypeImpl", new
PropertyModel<ContactPointType>(item.getModel(), "contactPointTypeImpl")));
                    item.add(new
IndicatingAjaxLink<ContactPoint>("deleteLink", new Model<ContactPoint>(cp))
{
                        @Override
                        public void onClick(AjaxRequestTarget target) {

employerInfoModel.getObject().getContactPoints().remove(cp);
                            target.addComponent(ContactInfoForm.this);
                        }
                    });
                }
            };
            contactPointsContainer.add(contactPointsListView);
            contactPointsContainer.setOutputMarkupId(true);
            add(contactPointsContainer);

            add(new AjaxSubmitLink("addContactPointLink", this) {
                @Override
                public void onSubmit(AjaxRequestTarget target, Form<?> form)
{
                    getModelObject().getContactPointsSet().add(new
ContactPointImpl());
                    target.addComponent(contactPointsContainer);
                }
            });
        }
    }



[2] - public class EmployerInfo extends PersonInfoImpl {
    ...
    Set<ContactPoint> contactPointsSet;

    public List<ContactPoint> getContactPoints() {
        List<ContactPoint> list = new
ArrayList<ContactPoint>(contactPointsSet);
        Collections.sort(list);
        return list;
    }

    public void setContactPoints(List<ContactPoint> contactPoints) {
        this.contactPointsSet = new HashSet<ContactPoint>(contactPoints);
    }

    public Set<ContactPoint> getContactPointsSet() {
        return contactPointsSet;
    }

    public void setContactPointsSet(Set<ContactPoint> contactPointsSet) {
        this.contactPointsSet = contactPointsSet;
    }

}

Reply via email to