* Filters that are applied to the container to limit the items visible in
* it
*/
- private HashSet filters;
+ private HashSet<Filter> filters;
private HashMap<Object, Object> defaultPropertyValues;
*/
public Item addItem(Object itemId) {
- // Null ids are not accepted
- if (itemId == null) {
- throw new NullPointerException("Container item id can not be null");
- }
-
- // Makes sure that the Item has not been created yet
- if (items.containsKey(itemId)) {
+ // Make sure that the Item is valid and has not been created yet
+ if (itemId == null || items.containsKey(itemId)) {
return null;
}
- // Adds the Item to container
+ // Adds the Item to container (at the end of the unfiltered list)
itemIds.add(itemId);
Hashtable t = new Hashtable();
items.put(itemId, t);
addDefaultValues(t);
+ // this optimization is why some code is duplicated with
+ // addItemAtInternalIndex()
final Item item = new IndexedContainerItem(itemId);
if (filteredItemIds != null) {
if (passesFilters(item)) {
public Item addItemAfter(Object previousItemId, Object newItemId) {
// Get the index of the addition
- int index = 0;
+ int index = -1;
if (previousItemId != null) {
index = 1 + indexOfId(previousItemId);
if (index <= 0 || index > size()) {
*/
public Object addItemAfter(Object previousItemId) {
- // Get the index of the addition
- int index = 0;
- if (previousItemId != null) {
- index = 1 + indexOfId(previousItemId);
- if (index <= 0 || index > size()) {
- return null;
- }
- }
+ // Creates a new id
+ final Object id = new Object();
- return addItemAt(index);
+ return addItemAfter(previousItemId, id);
}
/*
*/
public Item addItemAt(int index, Object newItemId) {
- // Make sure that the Item has not been created yet
- if (items.containsKey(newItemId)) {
- return null;
- }
-
- // TODO should add based on a filtered index!
- // Adds the Item to container
- itemIds.add(index, newItemId);
- Hashtable t = new Hashtable();
- items.put(newItemId, t);
- addDefaultValues(t);
-
- if (filteredItemIds != null) {
- updateContainerFiltering();
+ // add item based on a filtered index
+ int internalIndex = -1;
+ if (filteredItemIds == null) {
+ internalIndex = index;
+ } else if (index == 0) {
+ internalIndex = 0;
+ } else if (index == size()) {
+ // add just after the last item
+ Object id = getIdByIndex(index - 1);
+ internalIndex = itemIds.indexOf(id) + 1;
+ } else if (index > 0 && index < size()) {
+ // map the index of the visible item to its unfiltered index
+ Object id = getIdByIndex(index);
+ internalIndex = itemIds.indexOf(id);
+ }
+ if (internalIndex >= 0) {
+ return addItemAtInternalIndex(internalIndex, newItemId);
} else {
- fireContentsChange(index);
+ return null;
}
-
- return getItem(newItemId);
}
/*
/* Event notifiers */
+ /**
+ * Adds new item at given index of the internal (unfiltered) list.
+ * <p>
+ * The item is also added in the visible part of the list if it passes the
+ * filters.
+ * </p>
+ *
+ * @param index
+ * Internal index to add the new item.
+ * @param newItemId
+ * Id of the new item to be added.
+ * @return Returns new item or null if the operation fails.
+ */
+ private Item addItemAtInternalIndex(int index, Object newItemId) {
+ // Make sure that the Item is valid and has not been created yet
+ if (index < 0 || index > itemIds.size() || newItemId == null
+ || items.containsKey(newItemId)) {
+ return null;
+ }
+
+ // Adds the Item to container
+ itemIds.add(index, newItemId);
+ Hashtable t = new Hashtable();
+ items.put(newItemId, t);
+ addDefaultValues(t);
+
+ if (filteredItemIds != null) {
+ // when the item data is set later (IndexedContainerProperty),
+ // filtering is updated
+ updateContainerFiltering();
+ } else {
+ fireContentsChange(index);
+ }
+
+ return new IndexedContainerItem(newItemId);
+ }
+
/**
* An <code>event</code> object specifying the list whose Property set has
* changed.
}
}
+ // update the container filtering if this property is being filtered
+ updateContainerFiltering(propertyId);
+
firePropertyValueChange(this);
}
* @see com.itmill.toolkit.data.Container.Sortable#sort(java.lang.Object[],
* boolean[])
*/
- public synchronized void sort(Object[] propertyId, boolean[] ascending) {
+ public void sort(Object[] propertyId, boolean[] ascending) {
// Removes any non-sortable property ids
final List ids = new ArrayList();
.clone() : null;
nc.types = types != null ? (Hashtable) types.clone() : null;
- nc.filters = filters == null ? null : (HashSet) filters.clone();
+ nc.filters = filters == null ? null : (HashSet<Filter>) filters.clone();
nc.filteredItemIds = filteredItemIds == null ? null
: (LinkedHashSet) filteredItemIds.clone();
public void addContainerFilter(Object propertyId, String filterString,
boolean ignoreCase, boolean onlyMatchPrefix) {
if (filters == null) {
- filters = new HashSet();
+ filters = new HashSet<Filter>();
}
filters.add(new Filter(propertyId, filterString, ignoreCase,
onlyMatchPrefix));
if (filters == null || propertyId == null) {
return;
}
- for (final Iterator i = filters.iterator(); i.hasNext();) {
- final Filter f = (Filter) i.next();
+ final Iterator<Filter> i = filters.iterator();
+ while (i.hasNext()) {
+ final Filter f = i.next();
if (propertyId.equals(f.propertyId)) {
i.remove();
}
updateContainerFiltering();
}
+ private void updateContainerFiltering(Object propertyId) {
+ if (filters == null || propertyId == null) {
+ return;
+ }
+ // update container filtering if there is a filter for the given
+ // property
+ final Iterator<Filter> i = filters.iterator();
+ while (i.hasNext()) {
+ final Filter f = i.next();
+ if (propertyId.equals(f.propertyId)) {
+ updateContainerFiltering();
+ return;
+ }
+ }
+ }
+
private void updateContainerFiltering() {
// Clearing filters?
return;
}
- // Reset filteres list
+ // Reset filtered list
if (filteredItemIds == null) {
filteredItemIds = new LinkedHashSet();
} else {
if (item == null) {
return false;
}
- for (final Iterator i = filters.iterator(); i.hasNext();) {
- final Filter f = (Filter) i.next();
+ final Iterator<Filter> i = filters.iterator();
+ while (i.hasNext()) {
+ final Filter f = i.next();
final String s1 = f.ignoreCase ? f.filterString.toLowerCase()
: f.filterString;
final Property p = item.getItemProperty(f.propertyId);