before changing performance characteristics of RefreshableMultiSelectionModel

Change-Id: Icbe2ec171d21f246241202d400f5dc71d53e4ec1
This commit is contained in:
Axel Uhl committed 2015-12-18 15:50:59 +01:00
1 parent 6879ec97d2
commit d5a01ad683
3 files changed
+64 -52

No files matched your search

@@ -24,9 +24,11 @@ import com.google.gwt.view.client.SelectionModel;
* <p>
* 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)}.<p>
*
* @author D064976
* TODO try to factor out the commonalities with RefreshableSingleSelectionModel into a delegate
*
* @author Lukas Furmanek
* @param <T>
* the type of entries
*/
@@ -44,10 +46,7 @@ public class RefreshableMultiSelectionModel<T> extends MultiSelectionModel<T>
* display on {@link ListDataProvider}
*/
public RefreshableMultiSelectionModel(EntityIdentityComparator<T> comp, ListDataProvider<T> listDataProvider) {
super();
this.comp = comp;
this.listDataProvider = listDataProvider;
this.listDataProvider.addDataDisplay(this);
this(/* keyProvider */ null, comp, listDataProvider);
}
/**
@@ -84,7 +83,7 @@ public class RefreshableMultiSelectionModel<T> extends MultiSelectionModel<T>
*/
@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<T> extends MultiSelectionModel<T>
}
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<T> extends MultiSelectionModel<T>
* {@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<T> newObjects) {
dontcheckSelectionState = true;
final Set<T> 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<T> newObjects) {
if (!dontcheckSelectionState) { // avoid endless recursions
dontcheckSelectionState = true;
try {
final Set<T> 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<T> extends MultiSelectionModel<T>
*/
@Override
public void setRowData(int start, List<? extends T> values) {
refreshSelectionModel(new ArrayList<>(listDataProvider.getList()));
refreshSelectionModel(listDataProvider.getList());
}
@Override
@@ -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.
* <p>
* 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.
* <p>
* If this selection model has no {@link EntityIdentityComparator} set, this method will use the {@link #equals(Object)}
* method to compare.
* <P>
* 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)}.
* <p>
* 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<T> extends SetSelectionModel<T>, HasD
* @return Returns an instance of {@link EntityIdentityComparator}, to compare objects from the type
* <code>&ltT&gt</code>.
*/
public EntityIdentityComparator<T> getEntityIdentityComparator();
EntityIdentityComparator<T> getEntityIdentityComparator();
}
@@ -21,9 +21,11 @@ import com.google.gwt.view.client.RangeChangeEvent.Handler;
* <p>
* 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)}.<p>
*
* @author D064976
* TODO try to factor out the commonalities with RefreshableMultiSelectionModel into a delegate
*
* @author Lukas Furmanek
* @param <T>
* the type of entries
*/
@@ -108,21 +110,26 @@ public class RefreshableSingleSelectionModel<T> extends SingleSelectionModel<T>
* the new objects to refresh the {@link RefreshableSingleSelectionModel selectionmodel}
*/
private void refreshSelectionModel(Iterable<T> 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;
}
/**