4857 all classes that handle event management should use EventListeners class
authorStephen Talley <stephen.talley@sun.com>
Tue, 11 Nov 2008 09:59:40 -0500
changeset 157 f4316b998c95
parent 156 ad266190d7e6
child 158 01ac8774cbc3
4857 all classes that handle event management should use EventListeners class
usr/src/java/util/org/opensolaris/os/vp/swing/AggregateAction.java
usr/src/java/util/org/opensolaris/os/vp/swing/ExtendedListSelectionEvent.java
usr/src/java/util/org/opensolaris/os/vp/swing/ExtendedListSelectionListener.java
usr/src/java/util/org/opensolaris/os/vp/swing/ExtendedListSelectionModel.java
usr/src/java/util/org/opensolaris/os/vp/swing/HyperlinkLabel.java
usr/src/java/util/org/opensolaris/os/vp/swing/ListItem.java
usr/src/java/util/org/opensolaris/os/vp/swing/ListItemGroup.java
usr/src/java/util/org/opensolaris/os/vp/swing/ListSelectionUnifier.java
usr/src/java/util/org/opensolaris/os/vp/swing/PopupList.java
usr/src/java/util/org/opensolaris/os/vp/swing/SingleListSelectionModel.java
usr/src/java/util/org/opensolaris/os/vp/swing/event/ActionListeners.java
usr/src/java/util/org/opensolaris/os/vp/swing/event/ChangeListeners.java
usr/src/java/util/org/opensolaris/os/vp/swing/event/ExtendedListSelectionEvent.java
usr/src/java/util/org/opensolaris/os/vp/swing/event/ExtendedListSelectionListener.java
usr/src/java/util/org/opensolaris/os/vp/swing/event/ExtendedListSelectionListeners.java
usr/src/java/util/org/opensolaris/os/vp/swing/event/ItemListeners.java
usr/src/java/util/org/opensolaris/os/vp/swing/event/ListDataListeners.java
usr/src/java/util/org/opensolaris/os/vp/swing/event/ListSelectionListeners.java
usr/src/java/util/org/opensolaris/os/vp/swing/event/TableModelListeners.java
usr/src/java/util/org/opensolaris/os/vp/swing/event/TreeModelListeners.java
usr/src/java/util/org/opensolaris/os/vp/swing/tree/NotifyingTreeNode.java
usr/src/java/util/org/opensolaris/os/vp/swing/tree/TableModelAdapter.java
usr/src/java/util/org/opensolaris/os/vp/util/ChangeableMonitor.java
usr/src/java/util/org/opensolaris/os/vp/util/event/ChangeListeners.java
usr/src/java/util/org/opensolaris/os/vp/util/event/ConnectionListListeners.java
usr/src/java/util/org/opensolaris/os/vp/util/event/EventListeners.java
usr/src/java/util/org/opensolaris/os/vp/util/event/IntervalEventSource.java
usr/src/java/util/org/opensolaris/os/vp/util/event/IntervalListener.java
usr/src/java/util/org/opensolaris/os/vp/util/event/IntervalListeners.java
usr/src/java/util/org/opensolaris/os/vp/util/event/PropertyChangeListeners.java
usr/src/java/util/org/opensolaris/os/vp/wrapper/AbstractDataWrapper.java
usr/src/java/vpanels/client/org/opensolaris/os/vp/client/common/ConnectionManager.java
usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/AppInstance.java
usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/ConsoleCategoryControl.java
usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/PanelLozenge.java
usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/PanelLozengeList.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/ConnectionListeners.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/control/NavigationListeners.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/control/Navigator.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/model/AbstractManagedObject.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/model/FilterManagedObject.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/control/WizardControl.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/view/ObjectsFilterPanel.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/view/ObjectsView.java
usr/src/java/vpanels/panels/sysid/org/opensolaris/system/sysid/client/swing/LocationPicker.java
usr/src/java/vpanels/panels/sysid/org/opensolaris/system/sysid/client/swing/LocationSelectionListeners.java
--- a/usr/src/java/util/org/opensolaris/os/vp/swing/AggregateAction.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/AggregateAction.java	Tue Nov 11 09:59:40 2008 -0500
@@ -22,15 +22,13 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- *
- * ident	"@(#)AggregateAction.java	1.3	08/05/11 SMI"
  */
 
 package org.opensolaris.os.vp.swing;
 
 import java.awt.event.*;
-import java.util.*;
 import javax.swing.*;
+import org.opensolaris.os.vp.swing.event.ActionListeners;
 
 @SuppressWarnings({"serial"})
 public class AggregateAction extends AbstractAction {
@@ -38,7 +36,7 @@
     // Instance data
     //
 
-    private List<ActionListener> listeners = new ArrayList<ActionListener>();
+    private ActionListeners listeners = new ActionListeners(false);
 
     //
     // Constructors
@@ -60,22 +58,19 @@
     //
 
     @Override
-    public synchronized void actionPerformed(ActionEvent e) {
-	// Iterate backwards to allow listener removal during iteration
-	for (int i = listeners.size() - 1; i >= 0; i--) {
-	    listeners.get(i).actionPerformed(e);
-	}
+    public void actionPerformed(ActionEvent e) {
+	listeners.actionPerformed(e);
     }
 
     //
     // AggregateAction methods
     //
 
-    public synchronized void addActionListener(ActionListener listener) {
+    public void addActionListener(ActionListener listener) {
 	listeners.add(listener);
     }
 
-    public synchronized boolean removeActionListener(ActionListener listener) {
+    public boolean removeActionListener(ActionListener listener) {
 	return listeners.remove(listener);
     }
 }
--- a/usr/src/java/util/org/opensolaris/os/vp/swing/ExtendedListSelectionEvent.java	Mon Nov 10 14:20:25 2008 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- *
- * ident	"@(#)ExtendedListSelectionEvent.java	1.3	08/05/11 SMI"
- */
-
-package org.opensolaris.os.vp.swing;
-
-import java.util.EventObject;
-
-@SuppressWarnings({"serial"})
-public class ExtendedListSelectionEvent extends EventObject {
-    //
-    // Enums
-    //
-
-    public enum Type {
-	ADD, REMOVE, SET, CLEAR
-    }
-
-    //
-    // Instance data
-    //
-
-    private Type type;
-    private int anchorIndex;
-    private int leadIndex;
-    private boolean isAdjusting;
-
-    //
-    // Constructors
-    //
-
-    public ExtendedListSelectionEvent(ExtendedListSelectionModel source,
-	Type type, int anchorIndex, int leadIndex, boolean isAdjusting) {
-
-	super(source);
-
-	this.type = type;
-	this.anchorIndex = anchorIndex;
-	this.leadIndex = leadIndex;
-	this.isAdjusting = isAdjusting;
-    }
-
-    //
-    // EventObject methods
-    //
-
-    public ExtendedListSelectionModel getSource() {
-	return (ExtendedListSelectionModel)super.getSource();
-    }
-
-    //
-    // ExtendedListSelectionEvent methods
-    //
-
-    public Type getType() {
-	return type;
-    }
-
-    public int getAnchorIndex() {
-	return anchorIndex;
-    }
-
-    public int getLeadIndex() {
-	return leadIndex;
-    }
-
-    public boolean getIsAdjusting() {
-	return isAdjusting;
-    }
-}
--- a/usr/src/java/util/org/opensolaris/os/vp/swing/ExtendedListSelectionListener.java	Mon Nov 10 14:20:25 2008 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- *
- * ident	"@(#)ExtendedListSelectionListener.java	1.3	08/05/11 SMI"
- */
-
-package org.opensolaris.os.vp.swing;
-
-public interface ExtendedListSelectionListener {
-    void selectionChanged(ExtendedListSelectionEvent e);
-}
--- a/usr/src/java/util/org/opensolaris/os/vp/swing/ExtendedListSelectionModel.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/ExtendedListSelectionModel.java	Tue Nov 11 09:59:40 2008 -0500
@@ -22,15 +22,12 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- *
- * ident	"@(#)ExtendedListSelectionModel.java	1.3	08/05/11 SMI"
  */
 
 package org.opensolaris.os.vp.swing;
 
-import java.util.*;
 import javax.swing.DefaultListSelectionModel;
-import org.opensolaris.os.vp.swing.ExtendedListSelectionEvent.Type;
+import org.opensolaris.os.vp.swing.event.*;
 
 /**
  * The {@code ExtendedListSelectionModel} class provides an event mechanism that
@@ -43,8 +40,8 @@
     // Instance data
     //
 
-    private List<ExtendedListSelectionListener> listeners =
-	new ArrayList<ExtendedListSelectionListener>();
+    private ExtendedListSelectionListeners listeners =
+	new ExtendedListSelectionListeners(false);
 
     //
     // ListSelectionModel methods
@@ -109,24 +106,15 @@
 
     public void addExtendedListSelectionListener(
 	ExtendedListSelectionListener listener) {
-	synchronized (listeners) {
-	    listeners.add(listener);
-	}
+	listeners.add(listener);
     }
 
     public void removeExtendedListSelectionListener(
 	ExtendedListSelectionListener listener) {
-	synchronized (listeners) {
-	    listeners.remove(listener);
-	}
+	listeners.remove(listener);
     }
 
     public void fireExtendedListSelectionEvent(ExtendedListSelectionEvent e) {
-	synchronized (listeners) {
-	    // Iterate backwards to allow listener removal during iteration
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).selectionChanged(e);
-	    }
-	}
+	listeners.selectionChanged(e);
     }
 }
--- a/usr/src/java/util/org/opensolaris/os/vp/swing/HyperlinkLabel.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/HyperlinkLabel.java	Tue Nov 11 09:59:40 2008 -0500
@@ -29,9 +29,10 @@
 import java.awt.*;
 import java.awt.event.*;
 import java.awt.font.TextAttribute;
-import java.util.*;
+import java.util.HashMap;
 import javax.swing.*;
 import javax.swing.border.Border;
+import org.opensolaris.os.vp.swing.event.ActionListeners;
 
 @SuppressWarnings({"serial"})
 public class HyperlinkLabel extends JLabel {
@@ -74,8 +75,7 @@
     // Instance data
     //
 
-    private ArrayList<ActionListener> listeners =
-	new ArrayList<ActionListener>();
+    private ActionListeners listeners = new ActionListeners(false);
     private boolean visited;
     private boolean underline;
     private boolean active;
@@ -235,9 +235,7 @@
     }
 
     protected void fireActionPerformed(ActionEvent e) {
-	for (int i = 0, n = listeners.size(); i < n; i++) {
-	    listeners.get(i).actionPerformed(e);
-	}
+	listeners.actionPerformed(e);
     }
 
     public boolean getActive() {
--- a/usr/src/java/util/org/opensolaris/os/vp/swing/ListItem.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/ListItem.java	Tue Nov 11 09:59:40 2008 -0500
@@ -22,19 +22,16 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- *
- * ident	"@(#)ListItem.java	1.3	08/05/11 SMI"
  */
 
 package org.opensolaris.os.vp.swing;
 
 import java.awt.*;
 import java.awt.event.*;
-import java.util.*;
-import java.util.List;
 import javax.swing.*;
 import javax.swing.border.Border;
 import javax.swing.event.*;
+import org.opensolaris.os.vp.swing.event.ItemListeners;
 
 @SuppressWarnings({"serial"})
 public class ListItem extends JLabel implements FocusListener, ItemSelectable,
@@ -70,7 +67,7 @@
     protected Border focusSelectedBorder;
     protected Border noFocusBorder;
 
-    protected List<ItemListener> listeners = new ArrayList<ItemListener>();
+    protected ItemListeners listeners = new ItemListeners(false);
 
     //
     // Constructors
@@ -124,9 +121,7 @@
 
     @Override
     public void addItemListener(ItemListener l) {
-	synchronized (listeners) {
-	    listeners.add(l);
-	}
+	listeners.add(l);
     }
 
     @Override
@@ -136,9 +131,7 @@
 
     @Override
     public void removeItemListener(ItemListener l) {
-	synchronized (listeners) {
-	    listeners.remove(l);
-	}
+	listeners.remove(l);
     }
 
     //
@@ -325,12 +318,7 @@
     }
 
     protected void fireItemStateChanged(ItemEvent e) {
-	synchronized (listeners) {
-	    // Iterate backwards to allow listener removal during iteration
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).itemStateChanged(e);
-	    }
-	}
+	listeners.itemStateChanged(e);
     }
 
     public boolean isSelected() {
--- a/usr/src/java/util/org/opensolaris/os/vp/swing/ListItemGroup.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/ListItemGroup.java	Tue Nov 11 09:59:40 2008 -0500
@@ -22,8 +22,6 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- *
- * ident	"@(#)ListItemGroup.java	1.3	08/05/11 SMI"
  */
 
 package org.opensolaris.os.vp.swing;
@@ -31,6 +29,7 @@
 import java.util.*;
 import javax.swing.*;
 import javax.swing.event.*;
+import org.opensolaris.os.vp.swing.event.ListDataListeners;
 
 public class ListItemGroup implements ListModel, ListSelectionListener {
     //
@@ -38,8 +37,7 @@
     //
 
     private List<ListItem> items = new ArrayList<ListItem>();
-    private List<ListDataListener> listeners =
-	new ArrayList<ListDataListener>();
+    private ListDataListeners listeners = new ListDataListeners(false);
     private ListSelectionModel lsModel;
 
     //
@@ -56,9 +54,7 @@
 
     @Override
     public void addListDataListener(ListDataListener l) {
-	synchronized (listeners) {
-	    listeners.add(l);
-	}
+	listeners.add(l);
     }
 
     @Override
@@ -77,9 +73,7 @@
 
     @Override
     public void removeListDataListener(ListDataListener l) {
-	synchronized (listeners) {
-	    listeners.remove(l);
-	}
+	listeners.remove(l);
     }
 
     //
@@ -114,12 +108,7 @@
 		ListDataEvent e = new ListDataEvent(
 		    this, ListDataEvent.INTERVAL_ADDED, index, index);
 
-		synchronized (listeners) {
-		    // Iterate backwards to allow listener removal mid-iteration
-		    for (int i = listeners.size() - 1; i >= 0; i--) {
-			listeners.get(i).intervalAdded(e);
-		    }
-		}
+		listeners.intervalAdded(e);
 	    }
 	}
     }
@@ -147,12 +136,7 @@
 		ListDataEvent e = new ListDataEvent(
 		    this, ListDataEvent.INTERVAL_REMOVED, index, index);
 
-		synchronized (listeners) {
-		    // Iterate backwards to allow listener removal mid-iteration
-		    for (int i = listeners.size() - 1; i >= 0; i--) {
-			listeners.get(i).intervalRemoved(e);
-		    }
-		}
+		listeners.intervalRemoved(e);
 
 		lsModel.removeIndexInterval(index, index);
 	    }
--- a/usr/src/java/util/org/opensolaris/os/vp/swing/ListSelectionUnifier.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/ListSelectionUnifier.java	Tue Nov 11 09:59:40 2008 -0500
@@ -22,14 +22,12 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- *
- * ident	"@(#)ListSelectionUnifier.java	1.3	08/05/11 SMI"
  */
 
 package org.opensolaris.os.vp.swing;
 
 import java.util.*;
-import org.opensolaris.os.vp.swing.ExtendedListSelectionEvent.Type;
+import org.opensolaris.os.vp.swing.event.*;
 
 /**
  * The {@code ListSelectionHandler} class unifies the selection of multiple
--- a/usr/src/java/util/org/opensolaris/os/vp/swing/PopupList.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/PopupList.java	Tue Nov 11 09:59:40 2008 -0500
@@ -22,18 +22,15 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- *
- * ident	"@(#)PopupList.java	1.2	08/05/11 SMI"
  */
 
 package org.opensolaris.os.vp.swing;
 
 import java.awt.*;
 import java.awt.event.*;
-import java.util.*;
-import java.util.List;
 import javax.swing.*;
 import javax.swing.plaf.basic.BasicComboPopup;
+import org.opensolaris.os.vp.swing.event.ItemListeners;
 
 @SuppressWarnings({"serial"})
 public class PopupList implements ItemSelectable {
@@ -51,8 +48,7 @@
     private JComponent component;
     private BasicComboPopup popup;
     private JComboBox combo;
-
-    private List<ItemListener> listeners = new ArrayList<ItemListener>();
+    private ItemListeners listeners = new ItemListeners(false);
 
     //
     // Constructors
@@ -95,9 +91,7 @@
 
     @Override
     public void addItemListener(ItemListener l) {
-	synchronized (listeners) {
-	    listeners.add(l);
-	}
+	listeners.add(l);
     }
 
     @Override
@@ -107,9 +101,7 @@
 
     @Override
     public void removeItemListener(ItemListener l) {
-	synchronized (listeners) {
-	    listeners.remove(l);
-	}
+	listeners.remove(l);
     }
 
     //
@@ -142,11 +134,7 @@
 	ItemEvent e = new ItemEvent(
 	    this, ItemEvent.ITEM_STATE_CHANGED, item, ItemEvent.SELECTED);
 
-	synchronized (listeners) {
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).itemStateChanged(e);
-	    }
-	}
+	listeners.itemStateChanged(e);
     }
 
     public void setModel(ComboBoxModel model) {
--- a/usr/src/java/util/org/opensolaris/os/vp/swing/SingleListSelectionModel.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/SingleListSelectionModel.java	Tue Nov 11 09:59:40 2008 -0500
@@ -22,23 +22,21 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- *
- * ident	"@(#)SingleListSelectionModel.java	1.3	08/05/11 SMI"
  */
 
 package org.opensolaris.os.vp.swing;
 
-import java.util.*;
 import javax.swing.ListSelectionModel;
 import javax.swing.event.*;
+import org.opensolaris.os.vp.swing.event.ListSelectionListeners;
 
 public class SingleListSelectionModel implements ListSelectionModel {
     //
     // Instance data
     //
 
-    private List<ListSelectionListener> listeners =
-	new ArrayList<ListSelectionListener>();
+    private ListSelectionListeners listeners =
+	new ListSelectionListeners(false);
 
     private int selectedIndex = -1;
     private int adjustingIndex = selectedIndex;
@@ -50,9 +48,7 @@
 
     @Override
     public void addListSelectionListener(ListSelectionListener l) {
-	synchronized (listeners) {
-	    listeners.add(l);
-	}
+	listeners.add(l);
     }
 
     @Override
@@ -141,9 +137,7 @@
 
     @Override
     public void removeListSelectionListener(ListSelectionListener l) {
-	synchronized (listeners) {
-	    listeners.remove(l);
-	}
+	listeners.remove(l);
     }
 
     @Override
@@ -208,12 +202,7 @@
     }
 
     protected void fireValueChanged(ListSelectionEvent e) {
-	synchronized (listeners) {
-	    // Iterate backwards to allow listener removal during iteration
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).valueChanged(e);
-	    }
-	}
+	listeners.valueChanged(e);
     }
 
     public int getAdjustingIndex() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/event/ActionListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.os.vp.swing.event;
+
+import java.awt.event.*;
+import org.opensolaris.os.vp.util.event.*;
+
+public class ActionListeners extends EventListeners<ActionEvent, ActionListener>
+    implements ActionListener {
+
+    //
+    // Static data
+    //
+
+    private static final EventDispatcher<ActionEvent, ActionListener>
+	dispatcher = new EventDispatcher<ActionEvent, ActionListener>() {
+	    public void dispatch(ActionListener listener, ActionEvent event) {
+		listener.actionPerformed(event);
+	    }
+	};
+
+    //
+    // Constructors
+    //
+
+    public ActionListeners(boolean mtSafe) {
+	super(mtSafe);
+    }
+
+    //
+    // ActionListener methods
+    //
+
+    @Override
+    public void actionPerformed(ActionEvent event) {
+	dispatch(dispatcher, event);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/event/ChangeListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.os.vp.swing.event;
+
+import javax.swing.event.*;
+import org.opensolaris.os.vp.util.event.*;
+
+public class ChangeListeners
+    extends EventListeners<ChangeEvent, ChangeListener>
+    implements ChangeListener {
+
+    //
+    // Static data
+    //
+
+    private static final EventDispatcher<ChangeEvent, ChangeListener>
+	dispatcher = new EventDispatcher<ChangeEvent, ChangeListener>() {
+	    public void dispatch(ChangeListener listener, ChangeEvent event) {
+		listener.stateChanged(event);
+	    }
+	};
+
+    //
+    // Constructors
+    //
+
+    public ChangeListeners(boolean mtSafe) {
+	super(mtSafe);
+    }
+
+    //
+    // ChangeListener methods
+    //
+
+    @Override
+    public void stateChanged(ChangeEvent event) {
+	dispatch(dispatcher, event);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/event/ExtendedListSelectionEvent.java	Tue Nov 11 09:59:40 2008 -0500
@@ -0,0 +1,93 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.os.vp.swing.event;
+
+import java.util.EventObject;
+import org.opensolaris.os.vp.swing.ExtendedListSelectionModel;
+
+@SuppressWarnings({"serial"})
+public class ExtendedListSelectionEvent extends EventObject {
+    //
+    // Enums
+    //
+
+    public enum Type {
+	ADD, REMOVE, SET, CLEAR
+    }
+
+    //
+    // Instance data
+    //
+
+    private Type type;
+    private int anchorIndex;
+    private int leadIndex;
+    private boolean isAdjusting;
+
+    //
+    // Constructors
+    //
+
+    public ExtendedListSelectionEvent(ExtendedListSelectionModel source,
+	Type type, int anchorIndex, int leadIndex, boolean isAdjusting) {
+
+	super(source);
+
+	this.type = type;
+	this.anchorIndex = anchorIndex;
+	this.leadIndex = leadIndex;
+	this.isAdjusting = isAdjusting;
+    }
+
+    //
+    // EventObject methods
+    //
+
+    public ExtendedListSelectionModel getSource() {
+	return (ExtendedListSelectionModel)super.getSource();
+    }
+
+    //
+    // ExtendedListSelectionEvent methods
+    //
+
+    public Type getType() {
+	return type;
+    }
+
+    public int getAnchorIndex() {
+	return anchorIndex;
+    }
+
+    public int getLeadIndex() {
+	return leadIndex;
+    }
+
+    public boolean getIsAdjusting() {
+	return isAdjusting;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/event/ExtendedListSelectionListener.java	Tue Nov 11 09:59:40 2008 -0500
@@ -0,0 +1,31 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.os.vp.swing.event;
+
+public interface ExtendedListSelectionListener {
+    void selectionChanged(ExtendedListSelectionEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/event/ExtendedListSelectionListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.os.vp.swing.event;
+
+import org.opensolaris.os.vp.util.event.*;
+
+public class ExtendedListSelectionListeners
+    extends EventListeners<ExtendedListSelectionEvent,
+    ExtendedListSelectionListener>
+    implements ExtendedListSelectionListener {
+
+    //
+    // Static data
+    //
+
+    private static final EventDispatcher<ExtendedListSelectionEvent,
+	ExtendedListSelectionListener> dispatcher = new EventDispatcher<
+	ExtendedListSelectionEvent, ExtendedListSelectionListener>() {
+	    public void dispatch(ExtendedListSelectionListener listener,
+		ExtendedListSelectionEvent event) {
+		listener.selectionChanged(event);
+	    }
+	};
+
+    //
+    // Constructors
+    //
+
+    public ExtendedListSelectionListeners(boolean mtSafe) {
+	super(mtSafe);
+    }
+
+    //
+    // ExtendedListSelectionListener methods
+    //
+
+    @Override
+    public void selectionChanged(ExtendedListSelectionEvent event) {
+	dispatch(dispatcher, event);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/event/ItemListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -0,0 +1,62 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.os.vp.swing.event;
+
+import java.awt.event.*;
+import org.opensolaris.os.vp.util.event.*;
+
+public class ItemListeners extends EventListeners<ItemEvent, ItemListener>
+    implements ItemListener {
+
+    //
+    // Static data
+    //
+
+    private static final EventDispatcher<ItemEvent, ItemListener>
+	dispatcher = new EventDispatcher<ItemEvent, ItemListener>() {
+	    public void dispatch(ItemListener listener, ItemEvent event) {
+		listener.itemStateChanged(event);
+	    }
+	};
+
+    //
+    // Constructors
+    //
+
+    public ItemListeners(boolean mtSafe) {
+	super(mtSafe);
+    }
+
+    //
+    // ItemListener methods
+    //
+
+    @Override
+    public void itemStateChanged(ItemEvent event) {
+	dispatch(dispatcher, event);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/event/ListDataListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -0,0 +1,90 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.os.vp.swing.event;
+
+import javax.swing.event.*;
+import org.opensolaris.os.vp.util.event.*;
+
+public class ListDataListeners
+    extends EventListeners<ListDataEvent, ListDataListener>
+    implements ListDataListener {
+
+    //
+    // Static data
+    //
+
+    private static final EventDispatcher<ListDataEvent, ListDataListener>
+	cDispatcher = new EventDispatcher<ListDataEvent, ListDataListener>() {
+	    public void dispatch(ListDataListener listener,
+		ListDataEvent event) {
+		listener.contentsChanged(event);
+	    }
+	};
+
+    private static final EventDispatcher<ListDataEvent, ListDataListener>
+	aDispatcher = new EventDispatcher<ListDataEvent, ListDataListener>() {
+	    public void dispatch(ListDataListener listener,
+		ListDataEvent event) {
+		listener.intervalAdded(event);
+	    }
+	};
+
+    private static final EventDispatcher<ListDataEvent, ListDataListener>
+	rDispatcher = new EventDispatcher<ListDataEvent, ListDataListener>() {
+	    public void dispatch(ListDataListener listener,
+		ListDataEvent event) {
+		listener.intervalRemoved(event);
+	    }
+	};
+
+    //
+    // Constructors
+    //
+
+    public ListDataListeners(boolean mtSafe) {
+	super(mtSafe);
+    }
+
+    //
+    // ListDataListener methods
+    //
+
+    @Override
+    public void contentsChanged(ListDataEvent event) {
+	dispatch(cDispatcher, event);
+    }
+
+    @Override
+    public void intervalAdded(ListDataEvent event) {
+	dispatch(aDispatcher, event);
+    }
+
+    @Override
+    public void intervalRemoved(ListDataEvent event)  {
+	dispatch(rDispatcher, event);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/event/ListSelectionListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.os.vp.swing.event;
+
+import javax.swing.event.*;
+import org.opensolaris.os.vp.util.event.*;
+
+public class ListSelectionListeners
+    extends EventListeners<ListSelectionEvent, ListSelectionListener>
+    implements ListSelectionListener {
+
+    //
+    // Static data
+    //
+
+    private static final EventDispatcher<ListSelectionEvent,
+	ListSelectionListener> dispatcher = new EventDispatcher<
+	ListSelectionEvent, ListSelectionListener>() {
+	    public void dispatch(ListSelectionListener listener,
+		ListSelectionEvent event) {
+		listener.valueChanged(event);
+	    }
+	};
+
+    //
+    // Constructors
+    //
+
+    public ListSelectionListeners(boolean mtSafe) {
+	super(mtSafe);
+    }
+
+    //
+    // ListSelectionListener methods
+    //
+
+    @Override
+    public void valueChanged(ListSelectionEvent event) {
+	dispatch(dispatcher, event);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/event/TableModelListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.os.vp.swing.event;
+
+import javax.swing.event.*;
+import org.opensolaris.os.vp.util.event.*;
+
+public class TableModelListeners
+    extends EventListeners<TableModelEvent, TableModelListener>
+    implements TableModelListener {
+
+    //
+    // Static data
+    //
+
+    private static final EventDispatcher<TableModelEvent, TableModelListener>
+	dispatcher = new EventDispatcher<TableModelEvent, TableModelListener>()
+	{
+	    public void dispatch(TableModelListener listener,
+		TableModelEvent event) {
+		listener.tableChanged(event);
+	    }
+	};
+
+    //
+    // Constructors
+    //
+
+    public TableModelListeners(boolean mtSafe) {
+	super(mtSafe);
+    }
+
+    //
+    // TableModelListener methods
+    //
+
+    @Override
+    public void tableChanged(TableModelEvent event) {
+	dispatch(dispatcher, event);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/event/TreeModelListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -0,0 +1,103 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.os.vp.swing.event;
+
+import javax.swing.event.*;
+import org.opensolaris.os.vp.util.event.*;
+
+public class TreeModelListeners
+    extends EventListeners<TreeModelEvent, TreeModelListener>
+    implements TreeModelListener {
+
+    //
+    // Static data
+    //
+
+    private static final EventDispatcher<TreeModelEvent, TreeModelListener>
+	cDispatcher = new EventDispatcher<TreeModelEvent, TreeModelListener>() {
+	    public void dispatch(TreeModelListener listener,
+		TreeModelEvent event) {
+		listener.treeNodesChanged(event);
+	    }
+	};
+
+    private static final EventDispatcher<TreeModelEvent, TreeModelListener>
+	iDispatcher = new EventDispatcher<TreeModelEvent, TreeModelListener>() {
+	    public void dispatch(TreeModelListener listener,
+		TreeModelEvent event) {
+		listener.treeNodesInserted(event);
+	    }
+	};
+
+    private static final EventDispatcher<TreeModelEvent, TreeModelListener>
+	rDispatcher = new EventDispatcher<TreeModelEvent, TreeModelListener>() {
+	    public void dispatch(TreeModelListener listener,
+		TreeModelEvent event) {
+		listener.treeNodesRemoved(event);
+	    }
+	};
+
+    private static final EventDispatcher<TreeModelEvent, TreeModelListener>
+	sDispatcher = new EventDispatcher<TreeModelEvent, TreeModelListener>() {
+	    public void dispatch(TreeModelListener listener,
+		TreeModelEvent event) {
+		listener.treeStructureChanged(event);
+	    }
+	};
+
+    //
+    // Constructors
+    //
+
+    public TreeModelListeners(boolean mtSafe) {
+	super(mtSafe);
+    }
+
+    //
+    // TreeModelListener methods
+    //
+
+    @Override
+    public void treeNodesChanged(TreeModelEvent event) {
+	dispatch(cDispatcher, event);
+    }
+
+    @Override
+    public void treeNodesInserted(TreeModelEvent event) {
+	dispatch(iDispatcher, event);
+    }
+
+    @Override
+    public void treeNodesRemoved(TreeModelEvent event) {
+	dispatch(rDispatcher, event);
+    }
+
+    @Override
+    public void treeStructureChanged(TreeModelEvent event) {
+	dispatch(sDispatcher, event);
+    }
+}
--- a/usr/src/java/util/org/opensolaris/os/vp/swing/tree/NotifyingTreeNode.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/tree/NotifyingTreeNode.java	Tue Nov 11 09:59:40 2008 -0500
@@ -29,6 +29,7 @@
 import java.util.*;
 import javax.swing.event.*;
 import javax.swing.tree.*;
+import org.opensolaris.os.vp.swing.event.TreeModelListeners;
 
 /**
  * The {@code NotifyingTreeNode} class propagates insertions/deletions to the
@@ -43,8 +44,7 @@
     // Instance data
     //
 
-    private List<TreeModelListener> listeners =
-	new ArrayList<TreeModelListener>(1);
+    private TreeModelListeners listeners = new TreeModelListeners(false);
 
     //
     // Constructors
@@ -70,11 +70,7 @@
      */
     @Override
     public void treeNodesChanged(TreeModelEvent e) {
-	synchronized (listeners) {
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).treeNodesChanged(e);
-	    }
-	}
+	listeners.treeNodesChanged(e);
     }
 
     /**
@@ -82,11 +78,7 @@
      */
     @Override
     public void treeNodesInserted(TreeModelEvent e) {
-	synchronized (listeners) {
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).treeNodesInserted(e);
-	    }
-	}
+	listeners.treeNodesInserted(e);
     }
 
     /**
@@ -94,11 +86,7 @@
      */
     @Override
     public void treeNodesRemoved(TreeModelEvent e) {
-	synchronized (listeners) {
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).treeNodesRemoved(e);
-	    }
-	}
+	listeners.treeNodesRemoved(e);
     }
 
     /**
@@ -106,11 +94,7 @@
      */
     @Override
     public void treeStructureChanged(TreeModelEvent e) {
-	synchronized (listeners) {
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).treeStructureChanged(e);
-	    }
-	}
+	listeners.treeStructureChanged(e);
     }
 
     //
@@ -141,9 +125,7 @@
     //
 
     public void addTreeModelListener(TreeModelListener listener) {
-	synchronized (listeners) {
-	    listeners.add(listener);
-	}
+	listeners.add(listener);
     }
 
     /**
@@ -209,8 +191,6 @@
     }
 
     public void removeTreeModelListener(TreeModelListener listener) {
-	synchronized (listeners) {
-	    listeners.remove(listener);
-	}
+	listeners.remove(listener);
     }
 }
--- a/usr/src/java/util/org/opensolaris/os/vp/swing/tree/TableModelAdapter.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/swing/tree/TableModelAdapter.java	Tue Nov 11 09:59:40 2008 -0500
@@ -22,8 +22,6 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- *
- * ident	"@(#)TableModelAdapter.java	1.4	08/05/11 SMI"
  */
 
 package org.opensolaris.os.vp.swing.tree;
@@ -32,6 +30,7 @@
 import javax.swing.event.*;
 import javax.swing.table.TableModel;
 import javax.swing.tree.TreeNode;
+import org.opensolaris.os.vp.swing.event.TableModelListeners;
 
 @SuppressWarnings({"serial"})
 public class TableModelAdapter implements TableModel, TreeModelListener {
@@ -41,9 +40,7 @@
 
     private List<ModelRowData> rows = new ArrayList<ModelRowData>();
     private TreeTableModel model;
-
-    private List<TableModelListener> listeners =
-	new ArrayList<TableModelListener>();
+    private TableModelListeners listeners = new TableModelListeners(false);
 
     //
     // Constructors
@@ -62,9 +59,7 @@
 
     @Override
     public void addTableModelListener(TableModelListener l) {
-	synchronized (listeners) {
-	    listeners.add(l);
-	}
+	listeners.add(l);
     }
 
     @Override
@@ -99,9 +94,7 @@
 
     @Override
     public void removeTableModelListener(TableModelListener l) {
-	synchronized (listeners) {
-	    listeners.remove(l);
-	}
+	listeners.remove(l);
     }
 
     @Override
@@ -190,12 +183,7 @@
     //
 
     public void fireTableChanged(TableModelEvent e) {
-	synchronized (listeners) {
-	    // Iterate backwards to allow listener removal during iteration
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).tableChanged(e);
-	    }
-	}
+	listeners.tableChanged(e);
     }
 
     protected ModelRowData getParent(ModelRowData row) {
--- a/usr/src/java/util/org/opensolaris/os/vp/util/ChangeableMonitor.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/util/ChangeableMonitor.java	Tue Nov 11 09:59:40 2008 -0500
@@ -22,14 +22,13 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- *
- * ident	"@(#)ChangeableMonitor.java	1.10	08/05/28 SMI"
  */
 
 package org.opensolaris.os.vp.util;
 
 import java.util.*;
 import javax.swing.event.*;
+import org.opensolaris.os.vp.swing.event.ChangeListeners;
 
 public class ChangeableMonitor implements Changeable {
     //
@@ -61,14 +60,8 @@
 	//
 
 	private void setChanged(boolean changed) {
-	    synchronized (listeners) {
-		this.changed = changed;
-
-		// Iterate backwards to allow listener removal during iteration
-		for (int i = listeners.size() - 1; i >= 0; i--) {
-		    listeners.get(i).stateChanged(event);
-		}
-	    }
+	    this.changed = changed;
+	    listeners.stateChanged(event);
 	}
     };
 
@@ -77,7 +70,7 @@
     //
 
     private List<Changeable> changeables = new ArrayList<Changeable>();
-    private List<ChangeListener> listeners = new ArrayList<ChangeListener>();
+    private ChangeListeners listeners = new ChangeListeners(false);
     private ChangeListener changeListener = new ChangeAggregator();
 
     //
@@ -86,9 +79,7 @@
 
     @Override
     public void addChangeListener(ChangeListener listener) {
-	synchronized (listeners) {
-	    listeners.add(listener);
-	}
+	listeners.add(listener);
     }
 
     @Override
@@ -109,9 +100,7 @@
 
     @Override
     public boolean removeChangeListener(ChangeListener listener) {
-	synchronized (listeners) {
-	    return listeners.remove(listener);
-	}
+	return listeners.remove(listener);
     }
 
     @Override
--- a/usr/src/java/util/org/opensolaris/os/vp/util/event/ChangeListeners.java	Mon Nov 10 14:20:25 2008 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-package org.opensolaris.os.vp.util.event;
-
-import javax.swing.event.*;
-
-public class ChangeListeners
-    extends EventListeners<ChangeEvent, ChangeListener>
-    implements ChangeListener {
-
-    //
-    // Static data
-    //
-
-    private static final EventDispatcher<ChangeEvent, ChangeListener>
-	dispatcher = new EventDispatcher<ChangeEvent, ChangeListener>() {
-	    public void dispatch(ChangeListener listener, ChangeEvent event) {
-		listener.stateChanged(event);
-	    }
-	};
-
-    //
-    // ChangeListener methods
-    //
-
-    @Override
-    public void stateChanged(ChangeEvent e) {
-	dispatch(dispatcher, e);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/util/org/opensolaris/os/vp/util/event/ConnectionListListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.os.vp.util.event;
+
+import org.opensolaris.os.vp.panel.common.*;
+
+public class ConnectionListListeners
+    extends EventListeners<ConnectionEvent, ConnectionListListener>
+    implements ConnectionListListener {
+
+    //
+    // Static data
+    //
+
+    private static final EventDispatcher<ConnectionEvent,
+	ConnectionListListener> aDispatcher = new EventDispatcher<
+	ConnectionEvent, ConnectionListListener>() {
+	    public void dispatch(ConnectionListListener listener,
+		ConnectionEvent event) {
+		listener.connectionAdded(event);
+	    }
+	};
+
+    private static final EventDispatcher<ConnectionEvent,
+	ConnectionListListener> rDispatcher = new EventDispatcher<
+	ConnectionEvent, ConnectionListListener>() {
+	    public void dispatch(ConnectionListListener listener,
+		ConnectionEvent event) {
+		listener.connectionRemoved(event);
+	    }
+	};
+
+    //
+    // Constructors
+    //
+
+    public ConnectionListListeners(boolean mtSafe) {
+	super(mtSafe);
+    }
+
+    //
+    // ConnectionListListener methods
+    //
+
+    @Override
+    public void connectionAdded(ConnectionEvent event) {
+	dispatch(aDispatcher, event);
+    }
+
+    @Override
+    public void connectionRemoved(ConnectionEvent event) {
+	dispatch(rDispatcher, event);
+    }
+}
--- a/usr/src/java/util/org/opensolaris/os/vp/util/event/EventListeners.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/util/event/EventListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -29,41 +29,125 @@
 import java.util.*;
 
 /**
- * Class that encapsulates MT-safe event listener management.
- *
- * A thread can safely add or remove itself from the set of
- * listeners at any time.  Because events may be being generated
- * by a different thread at the time, external locking is required
- * to ensure all subsequent events are received by new listeners,
- * and no amount of locking can prevent events from being delivered
- * to a listener after it has been removed.
+ * The {@code EventListeners} class encapsulates event listener management.
+ * <p/>
+ * If {@link #isThreadSafe thread-safe}, this {@code EventListeners}'s {@link
+ * #dispatch(EventDispatcher,Object,boolean)} method allows for the possibility
+ * of another thread manipulating its listener list during iteration.  In such a
+ * case, the listener list will be copied prior to notification, and that list
+ * copy will be iterated over instead.
+ * <p/>
+ * The cost of thread-safety, then, is the time and memory needed to copy the
+ * listener list every time an event is dispatched.
+ * <p/>
+ * In thread-safe mode, a listener can safely add or remove itself from the set
+ * of listeners at any time.  Because events may be being generated by a
+ * different thread at the time, external locking is required to ensure all
+ * subsequent events are received by new listeners, and no amount of locking can
+ * prevent events from being delivered to a listener after it has been removed.
+ * <p/>
+ * Note that in most cases, thread safety is not necessary.  In non-thread-safe
+ * mode, the listener list is iterated backwards, so that any listener may still
+ * safely remove itself from the listener list upon notification.  This
+ * technique is used throughout much of the JDK.
  */
-public class EventListeners<E extends EventObject, L>
-{
+public class EventListeners<E extends EventObject, L> {
+    //
+    // Instance data
+    //
+
     private List<L> listeners_ = new LinkedList<L>();
+    private boolean mtSafe;
 
-    public void addListener(L listener)
-    {
+    //
+    // Constructors
+    //
+
+    /**
+     * Constructs an {@code EventListeners}.
+     *
+     * @param	    mtSafe
+     *		    see {@link #isThreadSafe}
+     */
+    public EventListeners(boolean mtSafe) {
+	this.mtSafe = mtSafe;
+    }
+
+    //
+    // EventListeners methods
+    //
+
+    /**
+     * Adds a listener to the list to be notified by {@link
+     * #dispatch(EventDispatcher,Object,boolean)}.
+     */
+    public void add(L listener) {
 	synchronized (listeners_) {
 	    listeners_.add(listener);
 	}
     }
 
-    public boolean removeListener(L listener)
-    {
+    /**
+     * Notifies each listener of the given event.
+     *
+     * @param	    dispatcher
+     *		    the dispatcher that knows how to deliver the event
+     *
+     * @param	    event
+     *		    the event to be delivered
+     *
+     * @param	    mtSafe
+     *		    overrides the {@link #isThreadSafe default setting}
+     */
+    protected void dispatch(EventDispatcher<E, L> dispatcher, E event,
+	boolean mtSafe) {
+
+	List<L> local;
+	if (mtSafe) {
+	    synchronized (listeners_) {
+		local = new ArrayList<L>(listeners_);
+	    }
+	} else {
+	    local = listeners_;
+	}
+
+	synchronized (local) {
+	    // Iterate backwards to allow listener removal during iteration
+	    for (int i = local.size() - 1; i >= 0; i--) {
+		L listener = local.get(i);
+		dispatcher.dispatch(listener, event);
+	    }
+	}
+    }
+
+    /**
+     * Calls {@link #dispatch(EventDispatcher,Object,boolean)} with the {@link
+     * default mtSafe} setting.
+     */
+    protected void dispatch(EventDispatcher<E, L> dispatcher, E event) {
+	dispatch(dispatcher, event, mtSafe);
+    }
+
+    /**
+     * Indicates whether {@link #dispatch(EventDispatcher,Object,boolean)}
+     * should allow for the possibility of another thread manipulating its
+     * listener list during an iteration.  If {@code true}, the listener list
+     * will be copied prior to notification, and the list copy will be iterated
+     * over instead.
+     */
+    public boolean isThreadSafe() {
+	return mtSafe;
+    }
+
+    /**
+     * Removes a listener from the list to be notified by {@link #dispatch}.
+     *
+     * @return	    {@code true} if the list contained the given element, {@code
+     *		    false} otherwise
+     */
+    public boolean remove(L listener) {
 	synchronized (listeners_) {
 	    return (listeners_.remove(listener));
 	}
     }
-
-    protected void dispatch(EventDispatcher<E, L> e, E event)
-    {
-	List<L> local;
-	synchronized (listeners_) {
-	    local = new ArrayList<L>(listeners_);
-	}
-
-	for (L listener : local)
-	    e.dispatch(listener, event);
-    }
 }
--- a/usr/src/java/util/org/opensolaris/os/vp/util/event/IntervalEventSource.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/util/event/IntervalEventSource.java	Tue Nov 11 09:59:40 2008 -0500
@@ -22,8 +22,6 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- *
- * ident	"@(#)IntervalEventSource.java	1.3	08/05/11 SMI"
  */
 
 package org.opensolaris.os.vp.util.event;
@@ -46,7 +44,7 @@
      * For use by IntervalEventQueue.
      */
 
-    void fireIntervalAdded(IntervalEvent e);
+    void fireIntervalAdded(IntervalEvent event);
 
-    void fireIntervalRemoved(IntervalEvent e);
+    void fireIntervalRemoved(IntervalEvent event);
 }
--- a/usr/src/java/util/org/opensolaris/os/vp/util/event/IntervalListener.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/util/event/IntervalListener.java	Tue Nov 11 09:59:40 2008 -0500
@@ -22,8 +22,6 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- *
- * ident	"@(#)IntervalListener.java	1.6	08/05/11 SMI"
  */
 
 package org.opensolaris.os.vp.util.event;
@@ -31,7 +29,7 @@
 import java.util.EventListener;
 
 public interface IntervalListener extends EventListener {
-    void intervalAdded(IntervalEvent e);
+    void intervalAdded(IntervalEvent event);
 
-    void intervalRemoved(IntervalEvent e);
+    void intervalRemoved(IntervalEvent event);
 }
--- a/usr/src/java/util/org/opensolaris/os/vp/util/event/IntervalListeners.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/util/event/IntervalListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -28,6 +28,7 @@
 
 public class IntervalListeners
     extends EventListeners<IntervalEvent, IntervalListener>
+    implements IntervalListener
 {
     private static final EventDispatcher<IntervalEvent, IntervalListener> aid =
 	new EventDispatcher<IntervalEvent, IntervalListener>() {
@@ -45,13 +46,27 @@
 	    }
 	};
 
-    public void intervalAdded(IntervalEvent e)
-    {
-	dispatch(aid, e);
+    //
+    // Constructors
+    //
+
+    public IntervalListeners(boolean mtSafe) {
+	super(mtSafe);
     }
 
-    public void intervalRemoved(IntervalEvent e)
+    //
+    // IntervalListener methods
+    //
+
+    @Override
+    public void intervalAdded(IntervalEvent event)
     {
-	dispatch(rid, e);
+	dispatch(aid, event);
+    }
+
+    @Override
+    public void intervalRemoved(IntervalEvent event)
+    {
+	dispatch(rid, event);
     }
 }
--- a/usr/src/java/util/org/opensolaris/os/vp/util/event/PropertyChangeListeners.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/util/event/PropertyChangeListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -26,11 +26,11 @@
 
 package org.opensolaris.os.vp.util.event;
 
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
+import java.beans.*;
 
 public class PropertyChangeListeners
     extends EventListeners<PropertyChangeEvent, PropertyChangeListener>
+    implements PropertyChangeListener
 {
     private static final EventDispatcher<PropertyChangeEvent,
 	PropertyChangeListener> pcd =
@@ -42,8 +42,21 @@
 	    }
 	};
 
-    public void propertyChange(PropertyChangeEvent e)
+    //
+    // Constructors
+    //
+
+    public PropertyChangeListeners(boolean mtSafe) {
+	super(mtSafe);
+    }
+
+    //
+    // PropertyChangeListener methods
+    //
+
+    @Override
+    public void propertyChange(PropertyChangeEvent event)
     {
-	dispatch(pcd, e);
+	dispatch(pcd, event);
     }
-}
\ No newline at end of file
+}
--- a/usr/src/java/util/org/opensolaris/os/vp/wrapper/AbstractDataWrapper.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/util/org/opensolaris/os/vp/wrapper/AbstractDataWrapper.java	Tue Nov 11 09:59:40 2008 -0500
@@ -22,14 +22,12 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- *
- * ident	"@(#)AbstractDataWrapper.java	1.7	08/05/11 SMI"
  */
 
 package org.opensolaris.os.vp.wrapper;
 
-import java.util.*;
 import javax.swing.event.*;
+import org.opensolaris.os.vp.swing.event.ChangeListeners;
 import org.opensolaris.os.vp.util.ObjectUtil;
 import org.opensolaris.os.vp.util.converter.StringConverter;
 
@@ -39,7 +37,7 @@
     //
 
     private T saved;
-    private List<ChangeListener> listeners = new ArrayList<ChangeListener>();
+    private ChangeListeners listeners = new ChangeListeners(false);
     private ChangeEvent event = new ChangeEvent(this);
 
     //
@@ -48,9 +46,7 @@
 
     @Override
     public void addChangeListener(ChangeListener listener) {
-	synchronized (listeners) {
-	    listeners.add(listener);
-	}
+	listeners.add(listener);
     }
 
     /**
@@ -65,9 +61,7 @@
 
     @Override
     public boolean removeChangeListener(ChangeListener listener) {
-	synchronized (listeners) {
-	    return listeners.remove(listener);
-	}
+	return listeners.remove(listener);
     }
 
     //
@@ -119,11 +113,6 @@
      * Notifies listeners of a change in the value of this {@code DataWrapper}.
      */
     public void valueChanged() {
-	synchronized (listeners) {
-	    // Iterate backwards to allow listener removal during iteration
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).stateChanged(event);
-	    }
-	}
+	listeners.stateChanged(event);
     }
 }
--- a/usr/src/java/vpanels/client/org/opensolaris/os/vp/client/common/ConnectionManager.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/vpanels/client/org/opensolaris/os/vp/client/common/ConnectionManager.java	Tue Nov 11 09:59:40 2008 -0500
@@ -30,7 +30,7 @@
 import java.util.*;
 import javax.management.remote.JMXConnector;
 import org.opensolaris.os.vp.panel.common.*;
-import org.opensolaris.os.vp.panel.common.ConnectionEvent.Type;
+import org.opensolaris.os.vp.util.event.ConnectionListListeners;
 
 public class ConnectionManager {
     //
@@ -41,8 +41,8 @@
     private Map<ConnectionInfo, Set<Object>> connections =
 	new HashMap<ConnectionInfo, Set<Object>>();
 
-    private List<ConnectionListListener> listeners =
-	new ArrayList<ConnectionListListener>();
+    private ConnectionListListeners listeners =
+	new ConnectionListListeners(false);
 
     //
     // ConnectionManager methods
@@ -68,31 +68,20 @@
     }
 
     public void addConnectionListListener(ConnectionListListener listener) {
-	synchronized (listeners) {
-	    listeners.add(listener);
-	}
+	listeners.add(listener);
     }
 
     protected void fireAddEvent(ConnectionInfo info) {
 	ConnectionEvent event = new ConnectionEvent(
 	    this, ConnectionEvent.Type.ADD, info);
-
-	synchronized (listeners) {
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).connectionAdded(event);
-	    }
-	}
+	listeners.connectionAdded(event);
     }
 
     protected void fireRemoveEvent(ConnectionInfo info) {
 	ConnectionEvent event = new ConnectionEvent(
 	    this, ConnectionEvent.Type.REMOVE, info);
 
-	synchronized (listeners) {
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).connectionRemoved(event);
-	    }
-	}
+	listeners.connectionRemoved(event);
     }
 
     public Set<ConnectionInfo> getConnections() {
@@ -137,8 +126,6 @@
     public boolean removeConnectionListListener(
 	ConnectionListListener listener) {
 
-	synchronized (listeners) {
-	    return listeners.remove(listener);
-	}
+	return listeners.remove(listener);
     }
 }
--- a/usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/AppInstance.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/AppInstance.java	Tue Nov 11 09:59:40 2008 -0500
@@ -53,7 +53,7 @@
     private ConnectionInfo info;
     private PanelDescriptorFactory factory;
     private Navigator navigator;
-    private ConnectionListeners listeners = new ConnectionListeners();
+    private ConnectionListeners listeners = new ConnectionListeners(true);
 
     // Wrap the AppFrame's BusyIndicator in non-UI-thread-accessible methods
     private BusyIndicator busyIndicator = new BusyIndicator() {
@@ -124,7 +124,7 @@
 
     @Override
     public void addConnectionListener(ConnectionListener listener) {
-	listeners.addListener(listener);
+	listeners.add(listener);
     }
 
     @Override
@@ -154,7 +154,7 @@
 
     @Override
     public boolean removeConnectionListener(ConnectionListener listener) {
-	return (listeners.removeListener(listener));
+	return (listeners.remove(listener));
     }
 
     @Override
--- a/usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/ConsoleCategoryControl.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/ConsoleCategoryControl.java	Tue Nov 11 09:59:40 2008 -0500
@@ -38,9 +38,9 @@
 import org.opensolaris.os.vp.panel.common.*;
 import org.opensolaris.os.vp.panel.common.control.*;
 import org.opensolaris.os.vp.panel.common.model.*;
-import org.opensolaris.os.vp.panel.common.model.ManagedObject.Util;
 import org.opensolaris.os.vp.panel.swing.control.SwingControl;
 import org.opensolaris.os.vp.util.*;
+import org.opensolaris.os.vp.util.event.PropertyChangeListeners;
 
 @SuppressWarnings({"serial"})
 public class ConsoleCategoryControl extends SwingControl<PanelLozengeList> {
@@ -58,8 +58,8 @@
     private PanelCategory category;
 
     private PanelStatus status;
-    private List<PropertyChangeListener> listeners =
-	new ArrayList<PropertyChangeListener>();
+    private PropertyChangeListeners listeners =
+	new PropertyChangeListeners(false);
 
     private Map<PanelDescriptor, String> descriptors;
     private Object descriptorsLock = new Object();
@@ -164,9 +164,7 @@
     //
 
     public void addPropertyChangeListener(PropertyChangeListener listener) {
-	synchronized (listeners) {
-	    listeners.add(listener);
-	}
+	listeners.add(listener);
     }
 
     /**
@@ -174,11 +172,7 @@
      * registered {@code PropertyChangeListener}s.
      */
     protected void firePropertyChange(PropertyChangeEvent e) {
-	synchronized (listeners) {
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).propertyChange(e);
-	    }
-	}
+	listeners.propertyChange(e);
     }
 
     public PanelCategory getPanelCategory() {
@@ -256,9 +250,7 @@
 
     public boolean removePropertyChangeListener(
 	PropertyChangeListener listener) {
-	synchronized (listeners) {
-	    return listeners.remove(listener);
-	}
+	return listeners.remove(listener);
     }
 
     protected void setStatus() {
--- a/usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/PanelLozenge.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/PanelLozenge.java	Tue Nov 11 09:59:40 2008 -0500
@@ -32,14 +32,13 @@
 import java.awt.image.BufferedImage;
 import java.beans.*;
 import java.util.*;
-import java.util.List;
 import javax.swing.*;
-import org.opensolaris.os.vp.client.swing.PanelLozengeLayout.Constraint;
 import org.opensolaris.os.vp.common.panel.PanelStatus;
 import org.opensolaris.os.vp.panel.common.model.PanelDescriptor;
 import org.opensolaris.os.vp.panel.common.view.PanelIconUtil;
 import org.opensolaris.os.vp.panel.swing.model.SwingPanelDescriptor;
 import org.opensolaris.os.vp.swing.*;
+import org.opensolaris.os.vp.swing.event.ActionListeners;
 import org.opensolaris.os.vp.swing.layout.*;
 
 @SuppressWarnings({"serial"})
@@ -362,7 +361,7 @@
     // Size of circular border as percentage of total height of lozenge
     private float borderPct = .07f;
 
-    private List<ActionListener> listeners = new ArrayList<ActionListener>();
+    private ActionListeners listeners = new ActionListeners(false);
 
     //
     // Constructors
@@ -515,17 +514,11 @@
     //
 
     public void addActionListener(ActionListener listener) {
-	synchronized (listeners) {
-	    listeners.add(listener);
-	}
+	listeners.add(listener);
     }
 
     protected void fireActionPerformed(ActionEvent e) {
-	synchronized (listeners) {
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).actionPerformed(e);
-	    }
-	}
+	listeners.actionPerformed(e);
     }
 
     /**
@@ -572,9 +565,7 @@
     }
 
     public boolean removeActionListener(ActionListener listener) {
-	synchronized (listeners) {
-	    return listeners.remove(listener);
-	}
+	return listeners.remove(listener);
     }
 
     public void setPanelDescriptor(PanelDescriptor descriptor) {
--- a/usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/PanelLozengeList.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/PanelLozengeList.java	Tue Nov 11 09:59:40 2008 -0500
@@ -33,6 +33,7 @@
 import javax.swing.*;
 import org.opensolaris.os.vp.panel.common.model.*;
 import org.opensolaris.os.vp.swing.*;
+import org.opensolaris.os.vp.swing.event.ActionListeners;
 import org.opensolaris.os.vp.swing.layout.*;
 import org.opensolaris.os.vp.util.Finder;
 
@@ -64,15 +65,13 @@
 
     private JPanel cardPanel;
     private JPanel contentPanel;
-    private List<ActionListener> listeners = new ArrayList<ActionListener>();
+    private ActionListeners listeners = new ActionListeners(false);
 
     private ActionListener lozengeListener =
 	new ActionListener() {
 	    @Override
 	    public void actionPerformed(ActionEvent e) {
-		synchronized (listeners) {
-		    fireActionPerformed(e);
-		}
+		fireActionPerformed(e);
 	    }
 	};
 
@@ -99,24 +98,15 @@
     //
 
     public void addActionListener(ActionListener listener) {
-	synchronized (listeners) {
-	    listeners.add(listener);
-	}
+	listeners.add(listener);
     }
 
     protected void fireActionPerformed(ActionEvent e) {
-	synchronized (listeners) {
-	    // Iterate backwards to allow listener removal during iteration
-	    for (int i = listeners.size() - 1; i >= 0; i--) {
-		listeners.get(i).actionPerformed(e);
-	    }
-	}
+	listeners.actionPerformed(e);
     }
 
     public void removeActionListener(ActionListener listener) {
-	synchronized (listeners) {
-	    listeners.remove(listener);
-	}
+	listeners.remove(listener);
     }
 
     public void setPanelDescriptors(Collection<PanelDescriptor> descriptors) {
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/ConnectionListeners.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/ConnectionListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -26,11 +26,11 @@
 
 package org.opensolaris.os.vp.panel.common;
 
-import org.opensolaris.os.vp.util.event.EventDispatcher;
-import org.opensolaris.os.vp.util.event.EventListeners;
+import org.opensolaris.os.vp.util.event.*;
 
 public class ConnectionListeners
     extends EventListeners<ConnectionEvent, ConnectionListener>
+    implements ConnectionListener
 {
     private static final EventDispatcher<ConnectionEvent,
 	ConnectionListener> ccd =
@@ -42,6 +42,19 @@
 	    }
 	};
 
+    //
+    // Constructors
+    //
+
+    public ConnectionListeners(boolean mtSafe) {
+	super(mtSafe);
+    }
+
+    //
+    // ConnectionListener methods
+    //
+
+    @Override
     public void connectionChanged(ConnectionEvent e)
     {
 	dispatch(ccd, e);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/control/NavigationListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.os.vp.panel.common.control;
+
+import org.opensolaris.os.vp.util.event.*;
+
+public class NavigationListeners
+    extends EventListeners<NavigationEvent, NavigationListener>
+    implements NavigationListener {
+
+    //
+    // Static data
+    //
+
+    private static final EventDispatcher<NavigationEvent, NavigationListener>
+	aDispatcher = new EventDispatcher<NavigationEvent, NavigationListener>()
+	{
+	    public void dispatch(NavigationListener listener,
+		NavigationEvent event) {
+		listener.navigationStarted(event);
+	    }
+	};
+
+    private static final EventDispatcher<NavigationEvent, NavigationListener>
+	zDispatcher = new EventDispatcher<NavigationEvent, NavigationListener>()
+	{
+	    public void dispatch(NavigationListener listener,
+		NavigationEvent event) {
+		listener.navigationStopped(event);
+	    }
+	};
+
+    //
+    // Constructors
+    //
+
+    public NavigationListeners(boolean mtSafe) {
+	super(mtSafe);
+    }
+
+    //
+    // NavigationListener methods
+    //
+
+    @Override
+    public void navigationStarted(NavigationEvent e) {
+	dispatch(aDispatcher, e);
+    }
+
+    @Override
+    public void navigationStopped(NavigationEvent e) {
+	dispatch(zDispatcher, e);
+    }
+}
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/control/Navigator.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/control/Navigator.java	Tue Nov 11 09:59:40 2008 -0500
@@ -44,19 +44,9 @@
     //
 
     private Thread dispatchThread;
-
-    // Use a thread pool with a single core thread to autmatically handle
-    // uncaught exceptions and queued requests
     private ThreadPoolExecutor threadPool;
-
     private StackList<Control> stack = new StackList<Control>();
-
-    private List<NavigationListener> listeners =
-	new ArrayList<NavigationListener>();
-
-    private List<NavigationListener> roListeners =
-	Collections.unmodifiableList(listeners);
-
+    private NavigationListeners listeners = new NavigationListeners(false);
     private String name;
 
     //
@@ -81,6 +71,8 @@
 	// Unbounded
 	BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
 
+	// Use a thread pool with a single core thread to autmatically handle
+	// uncaught exceptions and queued requests
 	threadPool = new ThreadPoolExecutor(
 	    1, 1, 10, TimeUnit.MINUTES, queue, factory);
 
@@ -196,10 +188,7 @@
      * begun.
      */
     protected void fireNavigationStarted(NavigationEvent e) {
-	// Iterate backwards to allow listener removal during iteration
-	for (int i = listeners.size() - 1; i >= 0; i--) {
-	    listeners.get(i).navigationStarted(e);
-	}
+	listeners.navigationStarted(e);
     }
 
     /**
@@ -207,10 +196,7 @@
      * stopped.
      */
     protected void fireNavigationStopped(NavigationEvent e) {
-	// Iterate backwards to allow listener removal during iteration
-	for (int i = listeners.size() - 1; i >= 0; i--) {
-	    listeners.get(i).navigationStopped(e);
-	}
+	listeners.navigationStopped(e);
     }
 
     /**
@@ -227,10 +213,6 @@
 	return name;
     }
 
-    public List<NavigationListener> getNavigationListeners() {
-	return roListeners;
-    }
-
     /**
      * Gets the current path.  This method is not thread-safe; it is up to
      * callers to ensure the that navigation is not currently modifying this
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/model/AbstractManagedObject.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/model/AbstractManagedObject.java	Tue Nov 11 09:59:40 2008 -0500
@@ -31,7 +31,6 @@
 import org.opensolaris.os.vp.common.panel.PanelStatus;
 import org.opensolaris.os.vp.util.*;
 import org.opensolaris.os.vp.util.event.*;
-import org.opensolaris.os.vp.util.event.IntervalEventQueue.Type;
 
 public abstract class AbstractManagedObject<C extends ManagedObject>
     implements ManagedObject<C>, IntervalEventSource {
@@ -151,8 +150,10 @@
     private String name;
     private IntervalEventQueue eventQueue = new IntervalEventQueue(this);
 
-    private IntervalListeners iListeners = new IntervalListeners();
-    private PropertyChangeListeners pListeners = new PropertyChangeListeners();
+    private IntervalListeners iListeners = new IntervalListeners(true);
+
+    private PropertyChangeListeners pListeners =
+	new PropertyChangeListeners(true);
 
     protected List<C> children = new ArrayList<C>();
     private List<C> roChildren = Collections.unmodifiableList(children);
@@ -185,7 +186,7 @@
 
     @Override
     public void addPropertyChangeListener(PropertyChangeListener l) {
-	pListeners.addListener(l);
+	pListeners.add(l);
     }
 
     /**
@@ -256,7 +257,7 @@
 
     @Override
     public boolean removePropertyChangeListener(PropertyChangeListener l) {
-	return (pListeners.removeListener(l));
+	return (pListeners.remove(l));
     }
 
     //
@@ -265,12 +266,12 @@
 
     @Override
     public void addIntervalListener(IntervalListener l) {
-	iListeners.addListener(l);
+	iListeners.add(l);
     }
 
     @Override
     public boolean removeIntervalListener(IntervalListener l) {
-	return (iListeners.removeListener(l));
+	return (iListeners.remove(l));
     }
 
     @Override
@@ -412,7 +413,8 @@
 
 			    child.addPropertyChangeListener(sortListener);
 
-			    eventQueue.addIndex(index, Type.ADD);
+			    eventQueue.addIndex(index,
+				IntervalEventQueue.Type.ADD);
 			    children.add(index, child);
 
 			    result.addAdded(child);
@@ -554,7 +556,8 @@
 
 			    child.removePropertyChangeListener(sortListener);
 
-			    eventQueue.addIndex(index, Type.REMOVE);
+			    eventQueue.addIndex(index,
+				IntervalEventQueue.Type.REMOVE);
 			    children.remove(index);
 
 			    result.addRemoved(child);
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/model/FilterManagedObject.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/model/FilterManagedObject.java	Tue Nov 11 09:59:40 2008 -0500
@@ -43,8 +43,10 @@
     private ManagedObject<T> inner_;	/** The wrapped object */
     private Predicate<T> pred_;		/** The selection predicate */
 
-    private IntervalListeners iListeners_ = new IntervalListeners();
-    private PropertyChangeListeners pListeners_ = new PropertyChangeListeners();
+    private IntervalListeners iListeners_ = new IntervalListeners(true);
+
+    private PropertyChangeListeners pListeners_ =
+	new PropertyChangeListeners(true);
 
     /*
      * These four are protected by synchronizing on "children_"
@@ -259,7 +261,7 @@
     @Override
     public void addPropertyChangeListener(PropertyChangeListener l)
     {
-	pListeners_.addListener(l);
+	pListeners_.add(l);
     }
 
     @Override
@@ -301,13 +303,13 @@
     @Override
     public boolean removePropertyChangeListener(PropertyChangeListener l)
     {
-	return (pListeners_.removeListener(l));
+	return (pListeners_.remove(l));
     }
 
     @Override
     public void addIntervalListener(IntervalListener l)
     {
-	iListeners_.addListener(l);
+	iListeners_.add(l);
     }
 
     @Override
@@ -325,7 +327,7 @@
     @Override
     public boolean removeIntervalListener(IntervalListener l)
     {
-	return (iListeners_.removeListener(l));
+	return (iListeners_.remove(l));
     }
 
     /*
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/control/WizardControl.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/control/WizardControl.java	Tue Nov 11 09:59:40 2008 -0500
@@ -35,8 +35,8 @@
 import org.opensolaris.os.vp.panel.common.control.*;
 import org.opensolaris.os.vp.panel.swing.view.WizardPanel;
 import org.opensolaris.os.vp.swing.*;
+import org.opensolaris.os.vp.swing.event.ChangeListeners;
 import org.opensolaris.os.vp.util.*;
-import org.opensolaris.os.vp.util.event.ChangeListeners;
 
 /**
  * Implements a simple linear wizard out of a list of other controls.
@@ -96,7 +96,7 @@
     private List<Navigable> roChildren =
 	(List<Navigable>)(List)Collections.unmodifiableList(children);
 
-    private ChangeListeners listeners = new ChangeListeners();
+    private ChangeListeners listeners = new ChangeListeners(false);
     private ChangeEvent changeEvent = new ChangeEvent(this);
 
     //
@@ -161,7 +161,7 @@
 
     @Override
     public void stop() throws NavigationAbortedException {
-	if (!confirmCancelWizard()) {
+	if (rootControl.getRunningChild() != null && !confirmCancelWizard()) {
 	    throw new NavigationAbortedException();
 	}
 
@@ -193,7 +193,7 @@
 
     @Override
     public void addChangeListener(ChangeListener l) {
-	listeners.addListener(l);
+	listeners.add(l);
     }
 
     @Override
@@ -289,7 +289,7 @@
 
     @Override
     public void removeChangeListener(ChangeListener l) {
-	listeners.addListener(l);
+	listeners.add(l);
     }
 
     //
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/view/ObjectsFilterPanel.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/view/ObjectsFilterPanel.java	Tue Nov 11 09:59:40 2008 -0500
@@ -30,12 +30,11 @@
 import java.awt.event.*;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
-import java.util.*;
-import java.util.List;
 import javax.swing.*;
 import javax.swing.border.Border;
 import org.opensolaris.os.vp.panel.common.model.ManagedObject;
 import org.opensolaris.os.vp.swing.*;
+import org.opensolaris.os.vp.swing.event.ActionListeners;
 
 /**
  * The {@code ObjectsFilterPanel} displays a {@link CustomObjectsFilter} in an
@@ -62,9 +61,7 @@
     private JPanel contentPanel;
     private ObjectsFilter<C> filter;
 
-    private List<ActionListener> listeners = new ArrayList<ActionListener>();
-    private List<ActionListener> roListeners =
-	Collections.unmodifiableList(listeners);
+    private ActionListeners listeners = new ActionListeners(false);
 
     private Action okayListener =
 	new AbstractAction() {
@@ -222,9 +219,7 @@
     }
 
     protected void fireActionPerformed(ActionEvent e) {
-	for (int i = listeners.size() - 1; i >= 0; i--) {
-	    listeners.get(i).actionPerformed(e);
-	}
+	listeners.actionPerformed(e);
     }
 
     protected void fireActionPerformed(String action) {
@@ -233,10 +228,6 @@
 	fireActionPerformed(event);
     }
 
-    public List<ActionListener> getActionListeners() {
-	return roListeners;
-    }
-
     public SettingsButtonBar getButtonBar() {
 	return buttonBar;
     }
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/view/ObjectsView.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/view/ObjectsView.java	Tue Nov 11 09:59:40 2008 -0500
@@ -28,10 +28,11 @@
 
 import java.awt.Component;
 import java.beans.*;
-import java.util.*;
+import java.util.List;
 import javax.swing.event.*;
 import org.opensolaris.os.vp.panel.common.action.StructuredAction;
 import org.opensolaris.os.vp.panel.common.model.ManagedObject;
+import org.opensolaris.os.vp.util.event.PropertyChangeListeners;
 
 /**
  * The {@code ObjectsView} class represents a unique view of a {@link
@@ -56,12 +57,8 @@
 
     private int count;
     private List<C> selection;
-
-    private List<PropertyChangeListener> pListeners =
-	new ArrayList<PropertyChangeListener>();
-
-    private List<PropertyChangeListener> roPListeners =
-	Collections.unmodifiableList(pListeners);
+    private PropertyChangeListeners listeners =
+	new PropertyChangeListeners(false);
 
     // Notify PropertyChangeListeners of changes in a list's selection model
     protected ListSelectionListener updateActionSelectionListener =
@@ -101,9 +98,7 @@
     //
 
     public void addPropertyChangeListener(PropertyChangeListener l) {
-	synchronized (pListeners) {
-	    pListeners.add(l);
-	}
+	listeners.add(l);
     }
 
     /**
@@ -122,12 +117,7 @@
     }
 
     protected void firePropertyChange(PropertyChangeEvent e) {
-	synchronized (pListeners) {
-	    // Iterate backwards to allow listener removal during iteration
-	    for (int i = pListeners.size() - 1; i >= 0; i--) {
-		pListeners.get(i).propertyChange(e);
-	    }
-	}
+	listeners.propertyChange(e);
     }
 
     /**
@@ -172,14 +162,6 @@
     public abstract String getName();
 
     /**
-     * Returns a read-only wrapper around the registered {@code
-     * PropertyChangeListener}s.
-     */
-    public List<PropertyChangeListener> getPropertyChangeListeners() {
-	return roPListeners;
-    }
-
-    /**
      * Gets the selected {@code ManagedObject}s in this view.
      * <p>
      * Note: Implementations of this class <strong>must</strong> call {@link
@@ -196,8 +178,6 @@
     public abstract int getObjectCount();
 
     public boolean removePropertyChangeListener(PropertyChangeListener l) {
-	synchronized (pListeners) {
-	    return pListeners.remove(l);
-	}
+	return listeners.remove(l);
     }
 }
--- a/usr/src/java/vpanels/panels/sysid/org/opensolaris/system/sysid/client/swing/LocationPicker.java	Mon Nov 10 14:20:25 2008 -0500
+++ b/usr/src/java/vpanels/panels/sysid/org/opensolaris/system/sysid/client/swing/LocationPicker.java	Tue Nov 11 09:59:40 2008 -0500
@@ -31,8 +31,7 @@
 import java.awt.geom.Point2D;
 import java.util.*;
 import java.util.List;
-import javax.swing.Icon;
-import javax.swing.JLabel;
+import javax.swing.*;
 import org.opensolaris.os.vp.swing.ScaledIcon;
 
 public class LocationPicker<T> extends JLabel
@@ -163,10 +162,13 @@
     private Map<T, LocationLabel> objects_ = new HashMap<T, LocationLabel>();
     private LocationLabel current_;
     private LocationLabel selection_;
-    private List<LocationSelectionListener<T>> selectionListeners_ =
-	new LinkedList<LocationSelectionListener<T>>();
-    private List<LocationSelectionListener<T>> highlightListeners_ =
-	new LinkedList<LocationSelectionListener<T>>();
+
+    private LocationSelectionListeners<T> selectionListeners_ =
+	new LocationSelectionListeners<T>(false);
+
+    private LocationSelectionListeners<T> highlightListeners_ =
+	new LocationSelectionListeners<T>(false);
+
     private ScaledIcon icon_;
 
     LocationPicker(Icon background, List<T> objects, LocationMapper<T> mapper)
@@ -272,14 +274,14 @@
      * LocationPicker methods
      */
 
-    private void sendEvent(List<LocationSelectionListener<T>> listeners,
+    private void sendEvent(LocationSelectionListeners<T> listeners,
 	LocationSelectionEvent.Type type, LocationLabel location)
     {
 	LocationSelectionEvent<T> event =
 	    new LocationSelectionEvent<T>(this, type,
 	    location == null ? null : location.getObject());
-	for (LocationSelectionListener<T> listener : listeners)
-	    listener.locationChanged(event);
+
+	listeners.locationChanged(event);
     }
 
     private void setCurrent(LocationLabel newloc)
@@ -334,9 +336,10 @@
 	selectionListeners_.add(listener);
     }
 
-    public void removeSelectionListener(LocationSelectionListener<T> listener)
+    public boolean removeSelectionListener(
+	LocationSelectionListener<T> listener)
     {
-	selectionListeners_.remove(listener);
+	return selectionListeners_.remove(listener);
     }
 
     public void addHighlightListener(LocationSelectionListener<T> listener)
@@ -344,8 +347,9 @@
 	highlightListeners_.add(listener);
     }
 
-    public void removeHighlightListener(LocationSelectionListener<T> listener)
+    public boolean removeHighlightListener(
+	LocationSelectionListener<T> listener)
     {
-	highlightListeners_.remove(listener);
+	return highlightListeners_.remove(listener);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/panels/sysid/org/opensolaris/system/sysid/client/swing/LocationSelectionListeners.java	Tue Nov 11 09:59:40 2008 -0500
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.system.sysid.client.swing;
+
+import org.opensolaris.os.vp.util.event.*;
+
+public class LocationSelectionListeners<T>
+    extends EventListeners<LocationSelectionEvent<T>,
+    LocationSelectionListener<T>> implements LocationSelectionListener<T> {
+
+    //
+    // Instance data
+    //
+
+    private EventDispatcher<LocationSelectionEvent<T>,
+	LocationSelectionListener<T>> dispatcher = new EventDispatcher<
+	LocationSelectionEvent<T>, LocationSelectionListener<T>>() {
+	    public void dispatch(LocationSelectionListener<T> listener,
+		LocationSelectionEvent<T> event) {
+		listener.locationChanged(event);
+	    }
+	};
+
+    //
+    // Constructors
+    //
+
+    public LocationSelectionListeners(boolean mtSafe) {
+	super(mtSafe);
+    }
+
+    //
+    // LocationSelectionListener methods
+    //
+
+    @Override
+    public void locationChanged(LocationSelectionEvent<T> event) {
+	dispatch(dispatcher, event);
+    }
+}