Skip to content

Instantly share code, notes, and snippets.

@Riduidel
Created July 7, 2011 12:22
Show Gist options
  • Select an option

  • Save Riduidel/1069394 to your computer and use it in GitHub Desktop.

Select an option

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 ....
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