diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/RefreshableMultiSelectionModel.java b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/RefreshableMultiSelectionModel.java
index 11055c02646..aeb9634fccb 100644
--- a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/RefreshableMultiSelectionModel.java
+++ b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/RefreshableMultiSelectionModel.java
@@ -24,9 +24,11 @@ import com.google.gwt.view.client.SelectionModel;
*
* For more details on the update process read the {@link RefreshableSelectionModel} Javadoc and see the methods
* {@link RefreshableMultiSelectionModel#refreshSelectionModel(Iterable)} and
- * {@link RefreshableMultiSelectionModel#setRowData(int, List)}.
+ * {@link RefreshableMultiSelectionModel#setRowData(int, List)}.
*
- * @author D064976
+ * TODO try to factor out the commonalities with RefreshableSingleSelectionModel into a delegate
+ *
+ * @author Lukas Furmanek
* @param
* the type of entries
*/
@@ -44,10 +46,7 @@ public class RefreshableMultiSelectionModel extends MultiSelectionModel
* display on {@link ListDataProvider}
*/
public RefreshableMultiSelectionModel(EntityIdentityComparator comp, ListDataProvider listDataProvider) {
- super();
- this.comp = comp;
- this.listDataProvider = listDataProvider;
- this.listDataProvider.addDataDisplay(this);
+ this(/* keyProvider */ null, comp, listDataProvider);
}
/**
@@ -84,7 +83,7 @@ public class RefreshableMultiSelectionModel extends MultiSelectionModel
*/
@Override
public void setSelected(T item, boolean selected) {
- if (comp == null || dontcheckSelectionState || item == null || getSelectedSet() == null) {
+ if (comp == null || dontcheckSelectionState || item == null || getSelectedSet().isEmpty()) {
super.setSelected(item, selected);
} else {
T wasSelectedBefore = null;
@@ -97,7 +96,7 @@ public class RefreshableMultiSelectionModel extends MultiSelectionModel
}
if (wasSelectedBefore != null) {
super.setSelected(wasSelectedBefore, false);
- isSelected(item); //triggers the deleting of the wasSelectedBefrore element in super class
+ isSelected(item); // triggers the deleting of the wasSelectedBefrore element in super class
super.setSelected(item, selected);
} else {
super.setSelected(item, selected);
@@ -119,31 +118,37 @@ public class RefreshableMultiSelectionModel extends MultiSelectionModel
* {@link AbstractSelectionModel#fireEvent(com.google.gwt.event.shared.GwtEvent)}.
*
* @param newObjects
- * the new objects to refresh the {@link RefreshableMultiSelectionModel selectionmodel}
+ * the new objects to refresh the {@link RefreshableMultiSelectionModel selection model}
*/
- private void refreshSelectionModel(Iterable newObjects) {
- dontcheckSelectionState = true;
- final Set selectedSet = getSelectedSet();
- final boolean isEmpty = selectedSet.isEmpty();
- if (!isEmpty) {
- clear();
- for (T it : newObjects) {
- if (comp == null) {
- setSelected(it, selectedSet.contains(it));
- } else {
- boolean isSelected = false;
- for (T selected : selectedSet) {
- isSelected = comp.representSameEntity(selected, it);
- if (isSelected) {
- setSelected(it, isSelected);
- break;
+ private void refreshSelectionModel(Iterable newObjects) {
+ if (!dontcheckSelectionState) { // avoid endless recursions
+ dontcheckSelectionState = true;
+ try {
+ final Set selectedSet = getSelectedSet(); // gets the selected set as a non-live copy, so later
+ // changes to the selection won't change this set anymore
+ final boolean isEmpty = selectedSet.isEmpty();
+ if (!isEmpty) {
+ clear();
+ for (T it : newObjects) {
+ if (comp == null) {
+ setSelected(it, selectedSet.contains(it));
+ } else {
+ boolean isSelected = false;
+ for (T selected : selectedSet) { // FIXME leads to O(n^2) effort which is inacceptable for large tables with all elements selected
+ isSelected = comp.representSameEntity(selected, it);
+ if (isSelected) {
+ setSelected(it, isSelected);
+ break;
+ }
+ }
}
- }
+ }
+ SelectionChangeEvent.fire(this);
}
+ } finally {
+ dontcheckSelectionState = false;
}
- SelectionChangeEvent.fire(this);
}
- dontcheckSelectionState = false;
}
/**
@@ -152,7 +157,7 @@ public class RefreshableMultiSelectionModel extends MultiSelectionModel
*/
@Override
public void setRowData(int start, List extends T> values) {
- refreshSelectionModel(new ArrayList<>(listDataProvider.getList()));
+ refreshSelectionModel(listDataProvider.getList());
}
@Override
diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/RefreshableSelectionModel.java b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/RefreshableSelectionModel.java
index fb27830ee65..7d8c87d72fc 100644
--- a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/RefreshableSelectionModel.java
+++ b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/RefreshableSelectionModel.java
@@ -8,25 +8,25 @@ import com.google.gwt.view.client.SingleSelectionModel;
/**
* The {@link RefreshableSelectionModel} unifies the refresh behavior of SelectionModels e.g. of a
- * {@link SingleSelectionModel}. This {@link RefreshableSelectionModel selectionmodel} will automatically refresh the
- * selection, when there are changes on the {@link ListDataProvider}. Therefore the {@link RefreshableSelectionModel
- * selectionmodel} is a listener of the {@link ListDataProvider} and implements the {@link HasData}-interface.
+ * {@link SingleSelectionModel}. This {@link RefreshableSelectionModel selection model} will automatically refresh the
+ * selection when there are changes on the {@link ListDataProvider}. Therefore the {@link RefreshableSelectionModel
+ * selection model} is a listener of the {@link ListDataProvider} and implements the {@link HasData}-interface.
*
* All objects from the current selection that {@link EntityIdentityComparator#representSameEntity(Object, Object)
* represent the same entity} as a new object from {@link ListDataProvider} will be reselected. All others are
- * de-selected. That means a selected object is not contained in {@link ListDataProvider#getList()} wouldn't be selected
- * anymore. If an element is reselected the element will be replaced with new version of it.
+ * de-selected. That means a selected object that is not contained in {@link ListDataProvider#getList()} wouldn't be
+ * selected anymore. If an element is reselected the element will be replaced with new version of it.
*
* If this selection model has no {@link EntityIdentityComparator} set, this method will use the {@link #equals(Object)}
* method to compare.
*
- * When the selection is refreshed this {@link RefreshableSelectionModel selectionmodel} triggers a
+ * When the selection is refreshed this {@link RefreshableSelectionModel selection model} triggers a
* {@link SelectionChangeEvent.Handler#onSelectionChange(SelectionChangeEvent) onSelectionChangedEvent} using
* {@link AbstractSelectionModel#fireEvent(com.google.gwt.event.shared.GwtEvent)}.
*
- * When you use this {@link RefreshableSelectionModel selectionmodel} make sure that you don't modify
+ * When you use this {@link RefreshableSelectionModel selection model} make sure that you don't modify
* {@link ListDataProvider} in {@link Handler#onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent)
- * onSelectionChange()} (it causes a stackoverflow).
+ * onSelectionChange()} (it causes a stack overflow).
*
* @author D064976
*/
@@ -36,5 +36,5 @@ public interface RefreshableSelectionModel extends SetSelectionModel, HasD
* @return Returns an instance of {@link EntityIdentityComparator}, to compare objects from the type
* <T>.
*/
- public EntityIdentityComparator getEntityIdentityComparator();
+ EntityIdentityComparator getEntityIdentityComparator();
}
\ No newline at end of file
diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/RefreshableSingleSelectionModel.java b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/RefreshableSingleSelectionModel.java
index c9c845e8cb9..beb76970ba1 100644
--- a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/RefreshableSingleSelectionModel.java
+++ b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/RefreshableSingleSelectionModel.java
@@ -21,9 +21,11 @@ import com.google.gwt.view.client.RangeChangeEvent.Handler;
*
* For more details on the update process read the {@link RefreshableSelectionModel} Javadoc and see the methods
* {@link RefreshableSingleSelectionModel#refreshSelectionModel(Iterable)} and
- * {@link RefreshableSingleSelectionModel#setRowData(int, List)}.
+ * {@link RefreshableSingleSelectionModel#setRowData(int, List)}.
*
- * @author D064976
+ * TODO try to factor out the commonalities with RefreshableMultiSelectionModel into a delegate
+ *
+ * @author Lukas Furmanek
* @param
* the type of entries
*/
@@ -108,21 +110,26 @@ public class RefreshableSingleSelectionModel extends SingleSelectionModel
* the new objects to refresh the {@link RefreshableSingleSelectionModel selectionmodel}
*/
private void refreshSelectionModel(Iterable newObjects) {
- // avoid a new selection state check in setSelected
- dontcheckSelectionState = true;
- final T selected = getSelectedObject();
- if (selected != null) {
- clear();
- for (final T it : newObjects) {
- boolean isEqual = comp == null ? selected.equals(it) : comp.representSameEntity(selected, it);
- if (isEqual) {
- setSelected(it, true);
- break;
+ if (!dontcheckSelectionState) { // avoid endless recursion
+ try {
+ // avoid a new selection state check in setSelected
+ dontcheckSelectionState = true;
+ final T selected = getSelectedObject();
+ if (selected != null) {
+ clear();
+ for (final T it : newObjects) {
+ boolean isEqual = comp == null ? selected.equals(it) : comp.representSameEntity(selected, it);
+ if (isEqual) {
+ setSelected(it, true);
+ break;
+ }
+ }
}
+ SelectionChangeEvent.fire(this);
+ } finally {
+ dontcheckSelectionState = false;
}
}
- SelectionChangeEvent.fire(this);
- dontcheckSelectionState = false;
}
/**