public void fireEvent(EventObject event) {
// It is not necessary to send any events if there are no listeners
if (listenerList != null) {
+
+ // Make a copy of the listener list to allow listeners to be added
+ // inside listener methods. Fixes #3605.
+
// Send the event to all listeners. The listeners themselves
// will filter out unwanted events.
-
- final Iterator<ListenerMethod> i = listenerList.iterator();
- while (i.hasNext()) {
- (i.next()).receiveEvent(event);
+ final Object[] listeners = listenerList.toArray();
+ for (int i = 0; i < listeners.length; i++) {
+ ((ListenerMethod) listeners[i]).receiveEvent(event);
}
+
}
}
appClass = (Class<? extends Application>) getClass()
.getClassLoader().loadClass(
defaultPackages[i] + "." + baseName);
+ } catch (ClassNotFoundException ee) {
+ // Ignore as this is expected for many packages
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
--- /dev/null
+package com.vaadin.tests.server;
+
+import junit.framework.TestCase;
+
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.ui.TextField;
+
+public class TestEventRouter extends TestCase {
+
+ int innerListenerCalls = 0;
+
+ public void testAddInEventListener() {
+ final TextField tf = new TextField();
+
+ final ValueChangeListener outer = new ValueChangeListener() {
+
+ public void valueChange(ValueChangeEvent event) {
+ ValueChangeListener inner = new ValueChangeListener() {
+
+ public void valueChange(ValueChangeEvent event) {
+ innerListenerCalls++;
+ System.out.println("The inner listener was called");
+ }
+ };
+
+ tf.addListener(inner);
+ }
+ };
+
+ tf.addListener(outer);
+ tf.setValue("abc"); // No inner listener calls, adds one inner
+ tf.setValue("def"); // One inner listener call, adds one inner
+ tf.setValue("ghi"); // Two inner listener calls, adds one inner
+ assert (innerListenerCalls == 3);
+ }
+}