Under Vaadin 6, my editable Table allows the rows to be dragged and dropped without errors. Under Vaadin 7, it seems that whenI drag the row, the dragged item has the values I expect, the new item I create seems to have the values set back, but when the Table is re-rendered, the item’s two String properties are set to null (but the Integer property shows the original value from before the drag).
I don’t seem to have this issue with my tables that are backed by bean items. Any ideas what might be wrong with this code?
Here’s where I create the Table:
optionList = new Table();
optionList.setWidth(100, Unit.PERCENTAGE);
optionList.addContainerProperty("order", Integer.class, null);
optionList.addContainerProperty("label", String.class, null);
optionList.addContainerProperty("value", String.class, null);
optionList.setColumnHeaders( vaadinUi.getStringArray("LibDropDownVersionForm.optionList.columnHeaders") );
optionList.setColumnAlignment("order", Align.CENTER);
optionList.setColumnExpandRatio("order", 0f);
optionList.setColumnExpandRatio("label", 0.25f);
optionList.setColumnExpandRatio("value", 0.75f);
optionList.setSortEnabled(false);
optionList.setNullSelectionAllowed(true);
optionList.setSelectable(true);
optionList.setImmediate(true);
Here’s my table’s field factory (note that the order field is just an Integer and has no actual field, and I’m currently tracking the fields created in my table so I can commit them individually since I guess that’s how I did it back in Vaadin 6):
optionList.setTableFieldFactory(new DefaultFieldFactory() {
private static final long serialVersionUID = 2978798748115448927L;
public Field<?> createField(Container container, Object itemId, Object propertyId, Component uiContext) {
// If I already have the specified itemId in my map and this is the first property in our table,
// let's clear it and assume we're building it again
if ( propertyId.equals("order") ) {
if ( optionListFields.containsKey(itemId) ) {
optionListFields.clear();
}
return null;
}
List<Field<?>> fieldList = optionListFields.get(itemId);
if ( fieldList == null ) fieldList = new LinkedList<Field<?>>();
Field<?> f = super.createField(container, itemId, propertyId, uiContext);
f.setBuffered(true);
f.setWidth(100,Unit.PERCENTAGE);
fieldList.add(f);
optionListFields.put(itemId,fieldList);
return f;
}
});
Here’s my drop handler:
optionList.setDropHandler(new DropHandler() {
private static final long serialVersionUID = 9044808753146836665L;
@SuppressWarnings("unchecked")
public void drop(DragAndDropEvent dropEvent) {
DataBoundTransferable t = (DataBoundTransferable)dropEvent.getTransferable();
Object sourceItemId = t.getItemId();
AbstractSelectTargetDetails dropData = ((AbstractSelectTargetDetails)dropEvent.getTargetDetails());
Object targetItemId = dropData.getItemIdOver();
// No move if source and target are the same
if ( sourceItemId == targetItemId || targetItemId == null )
return;
commitFieldsToTableOnly();
// Let's remove the source of the drag so we can add it back where requested...
Item sourceItem = optionList.getItem(sourceItemId);
Integer sourceOrder = (Integer)sourceItem.getItemProperty("order").getValue();
String sourceOption = (String)sourceItem.getItemProperty("label").getValue();
String sourceValue = (String)sourceItem.getItemProperty("value").getValue();
Item newItem;
optionList.removeItem(sourceItemId);
if ( dropData.getDropLocation() == VerticalDropLocation.BOTTOM ) {
newItem = optionList.addItemAfter(targetItemId,sourceItemId);
} else {
Object prevItemId = optionList.prevItemId(targetItemId);
newItem = optionList.addItemAfter(prevItemId, sourceItemId);
}
newItem.getItemProperty("order").setValue(sourceOrder);
newItem.getItemProperty("label").setValue(sourceOption);
newItem.getItemProperty("value").setValue(sourceValue);
// AT THIS POINT, newItem definitely shows all of the correct values -- that is, they are the same as values are retrieved from the sourceItem
optionListChanged = true;
}
public AcceptCriterion getAcceptCriterion() {
return new And(SourceIsTarget.get(), new Not(AbstractSelect.VerticalLocationIs.MIDDLE));
}
});
But after the drag, the source row has moved to the right location, and it shows the correct order value (the order value from the row that was dragged), but the two String fields are null. When I actually save my data by looping, they loops through optionList.getItemIds() and when I retrieve the 3 properties, they also show null values for the two String properties. I am confused because the item is created by the optionList (Table) via addItem() and I use that returned Item to set the values, so you’d think the Table’s container would have my values and not null. Clearly, I’m missing something that worked in Vaadin 6, but not in Vaadin 7. Thanks!