Author: rwhitcomb
Date: Thu Feb 21 17:50:04 2013
New Revision: 1448743

URL: http://svn.apache.org/r1448743
Log:
PIVOT-861: More changes -- using java.util.ArrayList to implement ListenerList
was causing many ConcurrentModificationExceptions to be thrown at various times
and various places.  So, reverting to my homegrown implementation, which at 
least
doesn't complain about this.  Maybe investigate further later to see why this
was happening and make a general solution with locks or something.


Modified:
    pivot/branches/2.0.x/core/src/org/apache/pivot/util/ListenerList.java

Modified: pivot/branches/2.0.x/core/src/org/apache/pivot/util/ListenerList.java
URL: 
http://svn.apache.org/viewvc/pivot/branches/2.0.x/core/src/org/apache/pivot/util/ListenerList.java?rev=1448743&r1=1448742&r2=1448743&view=diff
==============================================================================
--- pivot/branches/2.0.x/core/src/org/apache/pivot/util/ListenerList.java 
(original)
+++ pivot/branches/2.0.x/core/src/org/apache/pivot/util/ListenerList.java Thu 
Feb 21 17:50:04 2013
@@ -16,8 +16,9 @@
  */
 package org.apache.pivot.util;
 
-import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Iterator;
+import java.util.NoSuchElementException;
 
 /**
  * Abstract base class for listener lists.
@@ -29,9 +30,43 @@ import java.util.Iterator;
  */
 public abstract class ListenerList<T> implements Iterable<T> {
 
+    // Iterator through the current array of elements
+    private class NodeIterator implements Iterator<T> {
+        private int index;
+
+        public NodeIterator() {
+            this.index = 0;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return (index < last);
+        }
+
+        @Override
+        public T next() {
+            if (index >= last) {
+                throw new NoSuchElementException();
+            }
+
+            return list[index++];
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
     private static final int DEFAULT_SIZE = 5;
 
-    private ArrayList<T> list = new ArrayList<T>(DEFAULT_SIZE);
+    // The current array of items (some of which are null)
+    // All non-null objects are at the beginning of the array
+    // and the array is reorganized on "remove"
+    @SuppressWarnings({"unchecked"})
+    private T[] list = (T[])new Object[DEFAULT_SIZE];
+    // The current length of the active list
+    private int last = 0;
 
     /**
      * Adds a listener to the list, if it has not previously been added.
@@ -44,7 +79,12 @@ public abstract class ListenerList<T> im
             return;
         }
 
-        list.add(listener);
+        // If no slot is available, increase the size of the array
+        if (last >= list.length) {
+            list = Arrays.copyOf(list, list.length + DEFAULT_SIZE);
+        }
+
+        list[last++] = listener;
     }
 
     /**
@@ -60,18 +100,25 @@ public abstract class ListenerList<T> im
             return;
         }
 
-        list.remove(index);
+        // Once we find the entry in the list, copy the rest of the
+        // existing entries down by one position
+        if (index < last - 1) {
+            System.arraycopy(list, index + 1, list, index, last - 1 - index);
+        }
+
+        list[--last] = null;
     }
 
-    /**
-     * Returns the position of the given listener in the list,
-     * or -1 if the listener is not in the list.
-     */
     private int indexOf(T listener) {
         if (listener == null) {
             throw new IllegalArgumentException("listener is null.");
         }
-        return list.indexOf(listener);
+        for (int i = 0; i < last; i++) {
+            if (list[i] == listener) {
+                return i;
+            }
+        }
+        return -1;
     }
 
     /**
@@ -95,15 +142,12 @@ public abstract class ListenerList<T> im
      * otherwise.
      */
     public boolean isEmpty() {
-        return list.isEmpty();
+        return last == 0;
     }
 
-    /**
-     * Returns an iterator over the elements of the list.
-     */
     @Override
     public Iterator<T> iterator() {
-        return list.iterator();
+        return new NodeIterator();
     }
 
 }


Reply via email to