Created
July 7, 2011 12:22
-
-
Save Riduidel/1069394 to your computer and use it in GitHub Desktop.
Un Set capable d'envoyer des événements. Vous savez très bien à quoi ça va servir ....
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.beans.PropertyChangeEvent; | |
| import java.beans.PropertyChangeListener; | |
| import java.beans.PropertyChangeSupport; | |
| import java.util.ArrayList; | |
| import java.util.Collection; | |
| import java.util.Iterator; | |
| import java.util.List; | |
| import java.util.Set; | |
| /** | |
| * Set envoyant des événements à chaque modification | |
| * @author ndx | |
| * | |
| * @param <E> | |
| */ | |
| public class PropertySenderSet<E> implements Set<E> { | |
| private static final String DELEGATE_COLLECTION = "delegate.collection"; | |
| private static final String DELEGATE_ELEMENT = "delegate.element"; | |
| /** | |
| * Vous pensiez vraiment que j'allais m'amuser à tout réimplémenter à la main ? | |
| * Non, je préfère largement laisser les gens de chez Sun faire ce qu'il savent | |
| */ | |
| private final Set<E> delegate; | |
| private final PropertyChangeSupport support = new PropertyChangeSupport(this); | |
| /** | |
| * Crée le Set avec comme implémentation "réelle" le delegate fourni | |
| * @param delegate | |
| */ | |
| public PropertySenderSet(Set<E> delegate) { | |
| super(); | |
| this.delegate = delegate; | |
| } | |
| /** | |
| * La, il y a une modification : lorsqu'on ajoute un élément, on envoie un événement spécial. | |
| * En fait, il s'agit d'un {@link PropertyChangeEvent} où l'ancienne valeur est null et la nouvelle non null (pour indiquer qu'on a ajouté quelque chose). | |
| * En revanche, bien sûr, le nom de la propriété n'est ... pas vraiment signifiant | |
| * @param e | |
| * @return | |
| * @see java.util.Set#add(java.lang.Object) | |
| */ | |
| @Override | |
| public boolean add(E e) { | |
| // Si la collection a été modifiée par l'ajout,c 'est que l'élément n'était pas encore dans le Set, on envoie donc dans ce cas un événement | |
| boolean returned = delegate.add(e); | |
| if(returned) { | |
| // On indique ainsi qu'il y a maintenant une valeur là où il n'y en avait pas | |
| support.firePropertyChange(DELEGATE_ELEMENT, null, e); | |
| } | |
| return returned; | |
| } | |
| /** | |
| * Là, on fait presque la même chose que pour le add à une importante nuance près : comme on ajoute une collection, et pour faciliter la détection du type par les listeners, | |
| * on indique un autre nom de champ modifié | |
| * @param c | |
| * @return | |
| * @see java.util.Set#addAll(java.util.Collection) | |
| */ | |
| @Override | |
| public boolean addAll(Collection<? extends E> c) { | |
| // Si la collection a été modifiée par l'ajout,c 'est que les éléments n'étaient pas tous dans le Set | |
| boolean returned = delegate.addAll(c); | |
| if(returned) { | |
| // On indique ainsi qu'il y a maintenant une valeur là où il n'y en avait pas | |
| support.firePropertyChange(DELEGATE_COLLECTION, null, c); | |
| } | |
| return returned; | |
| } | |
| @Override | |
| public void clear() { | |
| if(delegate.size()>0) { | |
| Collection<E> deleted = new ArrayList<E>(delegate); | |
| delegate.clear(); | |
| support.firePropertyChange(DELEGATE_COLLECTION, deleted, null); | |
| } | |
| } | |
| /** | |
| * D'une manière analogue à {@link #add(Object)} lorsqu'on enlève un élément, on l'indique | |
| * @param o | |
| * @return | |
| * @see java.util.Set#remove(java.lang.Object) | |
| */ | |
| @Override | |
| public boolean remove(Object o) { | |
| // Si la collection a été modifiée par l'ajout,c 'est que l'élément n'était pas encore dans le Set, on envoie donc dans ce cas un événement | |
| boolean returned = delegate.remove(o); | |
| if(returned) { | |
| // On indique ainsi qu'il n'y a maintenant plus de valeur là où il y en avait une | |
| support.firePropertyChange(DELEGATE_ELEMENT, o, null); | |
| } | |
| return returned; | |
| } | |
| @Override | |
| public boolean removeAll(Collection<?> c) { | |
| // Si la collection a été modifiée par l'ajout,c 'est que les éléments n'étaient pas tous dans le Set | |
| boolean returned = delegate.removeAll(c); | |
| if(returned) { | |
| // On indique ainsi qu'il y a maintenant une valeur là où il n'y en avait pas | |
| support.firePropertyChange(DELEGATE_COLLECTION, c, null); | |
| } | |
| return returned; | |
| } | |
| /** | |
| * Cette méthode m'a toujours paru bizarre : qu'est-ce qui reste dans la collection quand on a apelé retainAll ? Le contenu de c. | |
| * Du coup, qu'est-ce qu'on en a supprimé ? Et bien tout le reste. Evidement, pour le détecter, c'est un peu pénible. | |
| * @param c | |
| * @return | |
| * @see java.util.Set#retainAll(java.util.Collection) | |
| */ | |
| @Override | |
| public boolean retainAll(Collection<?> c) { | |
| // Il faut d'abord copier le delegate ailleurs | |
| // J'utilise un tableau par pure flemme, hein | |
| List<E> deleted = new ArrayList<E>(delegate); | |
| boolean returned = delegate.retainAll(c); | |
| if(returned) { | |
| deleted.removeAll(delegate); | |
| support.firePropertyChange(DELEGATE_COLLECTION, deleted, null); | |
| } | |
| return returned; | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * @category delegate | |
| * @param listener | |
| * @see java.beans.PropertyChangeSupport#addPropertyChangeListener(java.beans.PropertyChangeListener) | |
| * @category delegate | |
| */ | |
| public void addPropertyChangeListener(PropertyChangeListener listener) { | |
| support.addPropertyChangeListener(listener); | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * @category delegate | |
| * @param listener | |
| * @see java.beans.PropertyChangeSupport#removePropertyChangeListener(java.beans.PropertyChangeListener) | |
| * @category delegate | |
| */ | |
| public void removePropertyChangeListener(PropertyChangeListener listener) { | |
| support.removePropertyChangeListener(listener); | |
| } | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // Pas la peine de lire plus loin, le reste nous permet d'implémenter l'interface Set | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| /** | |
| * {@inheritDoc} | |
| * @category delegate | |
| * @param o | |
| * @return | |
| * @see java.util.Set#contains(java.lang.Object) | |
| */ | |
| @Override | |
| public boolean contains(Object o) { | |
| return delegate.contains(o); | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * @category delegate | |
| * @param c | |
| * @return | |
| * @see java.util.Set#containsAll(java.util.Collection) | |
| */ | |
| @Override | |
| public boolean containsAll(Collection<?> c) { | |
| return delegate.containsAll(c); | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * @category delegate | |
| * @return | |
| * @see java.util.Set#isEmpty() | |
| */ | |
| @Override | |
| public boolean isEmpty() { | |
| return delegate.isEmpty(); | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * @category delegate | |
| * @return | |
| * @see java.util.Set#iterator() | |
| */ | |
| @Override | |
| public Iterator<E> iterator() { | |
| return delegate.iterator(); | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * @category delegate | |
| * @return | |
| * @see java.util.Set#size() | |
| */ | |
| @Override | |
| public int size() { | |
| return delegate.size(); | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * @category delegate | |
| * @return | |
| * @see java.util.Set#toArray() | |
| */ | |
| @Override | |
| public Object[] toArray() { | |
| return delegate.toArray(); | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * @category delegate | |
| * @param <T> | |
| * @param a | |
| * @return | |
| * @see java.util.Set#toArray(T[]) | |
| */ | |
| @Override | |
| public <T> T[] toArray(T[] a) { | |
| return delegate.toArray(a); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment