1 /*
2  * CollectionChangeSupport.java 28 oct. 2008
3  *
4  * Sweet Home 3D, Copyright (c) 2008 Emmanuel PUYBARET / eTeks <info@eteks.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 package com.eteks.sweethome3d.model;
21 
22 import java.util.ArrayList;
23 import java.util.List;
24 
25 /**
26  * A helper class for {@link CollectionListener CollectionListener} management.
27  * <code>T</code> is the type of item stored in the collection.
28  * @author Emmanuel Puybaret
29  */
30 public class CollectionChangeSupport<T> {
31   private final Object                      source;
32   private final List<CollectionListener<T>> collectionListeners;
33 
34   /**
35    * Creates a collection change support.
36    * @param source  the collection to which data will be added.
37    */
CollectionChangeSupport(Object source)38   public CollectionChangeSupport(Object source) {
39     this.source = source;
40     this.collectionListeners = new ArrayList<CollectionListener<T>>(5);
41   }
42 
43   /**
44    * Adds the <code>listener</code> in parameter to the list of listeners that may be notified.
45    * @param listener  the listener to add
46    */
addCollectionListener(CollectionListener<T> listener)47   public void addCollectionListener(CollectionListener<T> listener) {
48     this.collectionListeners.add(listener);
49   }
50 
51   /**
52    * Removes the <code>listener</code> in parameter to the list of listeners that may be notified.
53    * @param listener  the listener to remove. If it doesn't exist, it's simply ignored.
54    */
removeCollectionListener(CollectionListener<T> listener)55   public void removeCollectionListener(CollectionListener<T> listener) {
56     this.collectionListeners.remove(listener);
57   }
58 
59   /**
60    * Fires a collection event about <code>item</code>.
61    * @param item     the added ore deleted item
62    * @param eventType <code>CollectionEvent.Type.ADD</code> or <code>CollectionEvent.Type.DELETE</code>
63    */
fireCollectionChanged(T item, CollectionEvent.Type eventType)64   public void fireCollectionChanged(T item, CollectionEvent.Type eventType) {
65     fireCollectionChanged(item, -1, eventType);
66   }
67 
68   /**
69    * Fires a collection event about <code>item</code> at a given <code>index</code>.
70    * @param item     the added ore deleted item
71    * @param index    the optional index at which the item was added or deleted
72    * @param eventType <code>CollectionEvent.Type.ADD</code> or <code>CollectionEvent.Type.DELETE</code>
73    */
74   @SuppressWarnings("unchecked")
fireCollectionChanged(T item, int index, CollectionEvent.Type eventType)75   public void fireCollectionChanged(T item, int index,
76                                     CollectionEvent.Type eventType) {
77     if (!this.collectionListeners.isEmpty()) {
78       CollectionEvent<T> event = new CollectionEvent<T>(this.source, item, index, eventType);
79       // Work on a copy of collectionListeners to ensure a listener
80       // can modify safely listeners list
81       CollectionListener<T> [] listeners = this.collectionListeners.
82         toArray(new CollectionListener [this.collectionListeners.size()]);
83       for (CollectionListener<T> listener : listeners) {
84         listener.collectionChanged(event);
85       }
86     }
87   }
88 }
89