Figured out a hackish workaround. I just wanted to post it so if anyone else ran into the same issue, they at least had an idea of where to go.
First I create a class that will help me with field comparisons:
[code]
public class FieldComparison {
private final Object propertyID;
private final Object itemID;
public FieldComparison(Object propertyID, Object itemID) {
this.propertyID = propertyID;
this.itemID = itemID;
}
public Object getPropertyID() {
return propertyID;
}
public Object getItemID() {
return itemID;
}
@Override
public int hashCode() {
return propertyID.hashCode() + itemID.hashCode();
}
@Override
public boolean equals(Object obj) {
try {
if(this.propertyID == ((FieldComparison)obj).propertyID && this.itemID == ((FieldComparison)obj).itemID)
return true;
}
catch (Exception e) {
}
return false;
}
}
[/code]I then create a container to hold all my fields:
protected Map<FieldComparison, Field> tableFields = new HashMap<>();
After that, I add a listener to every generated field with my fieldfactory:
FieldFactory tableFieldFactory = new FieldFactory() {
@Override
public Field createField(final Container container, final Object itemId, final Object propertyId, Component uiContext) {
Field<?> field = super.createField(container, itemId, propertyId, uiContext);
if (propertyId.equals("ID")) {
field.setReadOnly(true);
((TextField) field).setConverter(new StringToPlainIntegerConverter());
}
field.setBuffered(true);
field.addValueChangeListener(event -> {
if (field.isModified() && !tableFields.containsKey(new FieldComparison(propertyId, itemId))) {
tableFields.put(new FieldComparison(propertyId, itemId), field);
}
});
field.addAttachListener(event -> {
FieldComparison fieldComparison = new FieldComparison(propertyId, itemId);
if(tableFields.containsKey(fieldComparison)) {
if(field instanceof TextField)
((TextField) field).setValue((String) tableFields.get(fieldComparison).getValue());
if(field instanceof NativeSelect)
((NativeSelect)field).select(tableFields.get(fieldComparison).getValue());
if(field instanceof CheckBox)
((CheckBox)field).setValue((Boolean) tableFields.get(fieldComparison).getValue());
}
});
return field;
}
};
As you can see, if a value is changed, the field gets added to the tableFields map. When a new field is attached, we look for an existing field in the tableFieldscontainer for the same propertyId and itemId, and if it exists, we set the value of the newly generated field to be the value of the previously generated field. Once the value is set, the ValueChangeListener is called, and the new field replaces the old one in the tableFieldscontainer.
Not the most elegant solution, but it seems to work pretty well so far.