Fix ConcurrentModificationException on designer

It was triggered when restoring multiple properties,
since the items where added to a collection that was
being iterated.

Also fix a small bug when creating a property named
TODO -> the next property was allowed to be called
TODO if the name wasn't changed, since the name field
wasn't changed, so didn't trigger reevaluation of the
validators.
This commit is contained in:
Clément Fournier
2018-06-04 00:47:45 +02:00
parent eaa907cd36
commit 4e29b793d2
3 changed files with 11 additions and 4 deletions

View File

@ -115,6 +115,7 @@ public class EditPropertyDialogController implements Initializable {
backingDescriptor.ifPresent(PropertyDescriptorSpec::unbind);
backingDescriptor.setValue(null);
backingDescriptorList.setValue(null);
this.nameProperty().setValue(""); // necessary to get the validator to reevaluate each time
}

View File

@ -157,14 +157,13 @@ public final class DesignerUtil {
*/
public static <T> void rewire(Property<T> underlying, ObservableValue<? extends T> ui, Consumer<? super T> setter) {
setter.accept(underlying.getValue());
underlying.unbind();
underlying.bind(ui); // Bindings are garbage collected after the popup dies
rewire(underlying, ui);
}
/** Like rewire, with no initialisation. */
public static <T> void rewire(Property<T> underlying, ObservableValue<? extends T> source) {
underlying.unbind();
underlying.bind(source);
underlying.bind(source); // Bindings are garbage collected after the popup dies
}

View File

@ -6,9 +6,11 @@ package net.sourceforge.pmd.util.fxdesigner.util.beans;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
@ -90,6 +92,9 @@ public class RestorePropertyVisitor extends BeanNodeVisitor<SettingsOwner> {
Iterator<SettingsOwner> existingItems = container.iterator();
Class<?> itemType = null;
// use a buffer to avoid concurrent modification
List<SettingsOwner> itemsToAdd = new ArrayList<>();
for (SimpleBeanModelNode child : model.getChildrenNodes()) {
SettingsOwner item;
if (existingItems.hasNext()) {
@ -108,9 +113,11 @@ public class RestorePropertyVisitor extends BeanNodeVisitor<SettingsOwner> {
}
child.accept(this, item);
container.add(item);
itemsToAdd.add(item);
}
container.addAll(itemsToAdd);
try {
PropertyUtils.setProperty(target, model.getPropertyName(), container);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {