You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by tv...@apache.org on 2009/08/03 15:31:55 UTC

svn commit: r800373 - /incubator/pivot/trunk/core/src/org/apache/pivot/collections/MapList.java

Author: tvolkert
Date: Mon Aug  3 13:31:55 2009
New Revision: 800373

URL: http://svn.apache.org/viewvc?rev=800373&view=rev
Log:
Resolve PIVOT-193

Modified:
    incubator/pivot/trunk/core/src/org/apache/pivot/collections/MapList.java

Modified: incubator/pivot/trunk/core/src/org/apache/pivot/collections/MapList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/collections/MapList.java?rev=800373&r1=800372&r2=800373&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/org/apache/pivot/collections/MapList.java (original)
+++ incubator/pivot/trunk/core/src/org/apache/pivot/collections/MapList.java Mon Aug  3 13:31:55 2009
@@ -46,83 +46,138 @@
 
     private Map<K, V> source;
 
-    private ArrayList<Pair<K, V>> view = new ArrayList<Pair<K, V>>();
+    private ArrayList<Pair<K, V>> view = null;
 
     private boolean updating = false;
 
     private ListListenerList<Pair<K, V>> listListeners = new ListListenerList<Pair<K, V>>();
     private MapListListenerList<K, V> mapListListeners = new MapListListenerList<K, V>();
 
+    private MapListener<K, V> mapHandler = new MapListener.Adapter<K, V>() {
+        @Override
+        public void valueAdded(Map<K, V> map, K key) {
+            if (!updating) {
+                int index = view.add(new Pair<K, V>(key, map.get(key)));
+                listListeners.itemInserted(MapList.this, index);
+            }
+        }
+
+        @Override
+        public void valueUpdated(Map<K, V> map, K key, V previousValue) {
+            if (!updating) {
+                Pair<K, V> pair = new Pair<K, V>(key, map.get(key));
+                Pair<K, V> previousPair = new Pair<K, V>(key, previousValue);
+
+                // Bypass the view comparator to find exact matches only
+                int index = linearSearch(pair);
+
+                if (index >= 0) {
+                    // We disallow duplicate keys in the list, so this means
+                    // that the value logically equals the previous value
+                    view.update(index, pair);
+                    listListeners.itemUpdated(MapList.this, index, previousPair);
+                } else {
+                    int previousIndex = linearSearch(previousPair);
+                    assert (previousIndex >= 0);
+
+                    Sequence<Pair<K, V>> removed = view.remove(previousIndex, 1);
+                    listListeners.itemsRemoved(MapList.this, previousIndex, removed);
+
+                    index = view.add(pair);
+                    listListeners.itemInserted(MapList.this, index);
+                }
+            }
+        }
+
+        @Override
+        public void valueRemoved(Map<K, V> map, K key, V value) {
+            if (!updating) {
+                Pair<K, V> pair = new Pair<K, V>(key, value);
+
+                // Bypass the view comparator to find exact matches only
+                int index = linearSearch(pair);
+
+                Sequence<Pair<K, V>> removed = view.remove(index, 1);
+                listListeners.itemsRemoved(MapList.this, index, removed);
+            }
+        }
+
+        @Override
+        public void mapCleared(Map<K, V> map) {
+            if (!updating) {
+                view.clear();
+                listListeners.listCleared(MapList.this);
+            }
+        }
+    };
+
+    /**
+     * Creates a new map list with no source map.
+     */
+    public MapList() {
+        this(null);
+    }
+
     /**
-     * Creates a new map list that decorates the specified map.
+     * Creates a new map list that decorates the specified source map.
      *
      * @param source
      * The map to present as a list
      */
     public MapList(Map<K, V> source) {
-        this.source = source;
+        setSource(source);
+    }
 
-        for (K key : source) {
-            view.add(new Pair<K, V>(key, source.get(key)));
-        }
+    /**
+     * Gets the source map.
+     *
+     * @return
+     * The source map, or <tt>null</tt> if no source is set
+     */
+    public Map<K, V> getSource() {
+        return source;
+    }
 
-        source.getMapListeners().add(new MapListener.Adapter<K, V>() {
-            @Override
-            public void valueAdded(Map<K, V> map, K key) {
-                if (!updating) {
-                    int index = view.add(new Pair<K, V>(key, map.get(key)));
-                    listListeners.itemInserted(MapList.this, index);
-                }
-            }
+    /**
+     * Sets the source map.
+     *
+     * @param source
+     * The source map, or <tt>null</tt> to clear the source
+     */
+    public void setSource(Map<K, V> source) {
+        Map<K, V> previousSource = this.source;
 
-            @Override
-            public void valueUpdated(Map<K, V> map, K key, V previousValue) {
-                if (!updating) {
-                    Pair<K, V> pair = new Pair<K, V>(key, map.get(key));
-                    Pair<K, V> previousPair = new Pair<K, V>(key, previousValue);
-
-                    // Bypass the view comparator to find exact matches only
-                    int index = linearSearch(pair);
-
-                    if (index >= 0) {
-                        // We disallow duplicate keys in the list, so this means
-                        // that the value logically equals the previous value
-                        view.update(index, pair);
-                        listListeners.itemUpdated(MapList.this, index, previousPair);
-                    } else {
-                        int previousIndex = linearSearch(previousPair);
-                        assert (previousIndex >= 0);
-
-                        Sequence<Pair<K, V>> removed = view.remove(previousIndex, 1);
-                        listListeners.itemsRemoved(MapList.this, previousIndex, removed);
-
-                        index = view.add(pair);
-                        listListeners.itemInserted(MapList.this, index);
-                    }
-                }
+        if (previousSource != source) {
+            // Clear any existing view
+            if (view != null) {
+                view.clear();
+                listListeners.listCleared(this);
             }
 
-            @Override
-            public void valueRemoved(Map<K, V> map, K key, V value) {
-                if (!updating) {
-                    Pair<K, V> pair = new Pair<K, V>(key, value);
-
-                    // Bypass the view comparator to find exact matches only
-                    int index = linearSearch(pair);
+            // Attach/detach list listeners
+            if (previousSource != null) {
+                previousSource.getMapListeners().remove(mapHandler);
+            }
 
-                    Sequence<Pair<K, V>> removed = view.remove(index, 1);
-                    listListeners.itemsRemoved(MapList.this, index, removed);
-                }
+            if (source != null) {
+                source.getMapListeners().add(mapHandler);
             }
 
-            @Override
-            public void mapCleared(Map<K, V> map) {
-                if (!updating) {
-                    view.clear();
-                    listListeners.listCleared(MapList.this);
+            // Update source
+            this.source = source;
+            mapListListeners.sourceChanged(this, previousSource);
+
+            // Refresh the view
+            if (source == null) {
+                view = null;
+            } else {
+                view = new ArrayList<Pair<K, V>>(source.count());
+
+                for (K key : source) {
+                    listListeners.itemInserted(this, view.add(new Pair<K, V>(key, source.get(key))));
                 }
             }
-        });
+        }
     }
 
     /**