2009-10-22 5 views
0

Je vais essayer d'expliquer mon problème le plus clairement possible :). J'utilise PropertyChangeSupport pour notifier les vues enregistrées pour les changements dans les propriétés. L'une des propriétés est un objet dont les propriétés sont modifiées à chaque vue secondes. Je ne veux pas créer pour cet objet particulier une nouvelle instance à chaque fois qu'il est mis à jour (pour que le propriétaire de la propriété remarque le changement), j'ai donc écrit ma propre méthode d'égal à égal où je me suis comparé à lui-même.PropertyChangeSupport et équivaut à la méthode

@Override 
public boolean equals(Object item) { 
    // do not compare 
    // if (this == item) { return true; } 

    if (!(item instanceof TransferQueueItem) || 
     item == null) { 

     return false; 
    } 

    TransferQueueItem newItem = (TransferQueueItem) item; 
    boolean value = 
      // ommited... properties comparation 
    return value; 
} 

Malheureusement, cela n'a pas eu l'effet que je recherchais. Si je crée une copie de l'objet et déclenche la méthode de changement de propriété, alors cela fonctionne bien.

Qu'est-ce qui me manque ici?

- Modifier

je me suis aperçu que depuis que je suis en utilisant la même instance et non une copie de celui-ci, les propriétés sont pointig au même endroit, donc le comparation serait toujours sortir vrai. Y at-il une solution de contournement à cela (en plus de créer une copie). Ou quelle est la difficulté de créer une copie d'un objet chaque seconde, par exemple.

+0

Cela ne devrait pas d'importance puisque toute modification de la même instance devrait déclencher des événements à tous les auditeurs de cette instance. Vous omettez des informations vitales ici. –

Répondre

1

Vous devez toujours revenir true dire PropertyChangeSupport que votre objet ne pas changement. Mais cela signifie que equals() est cassé pour tous les objets de cette classe (donc vous ne pouvez plus les utiliser dans les ensembles ou les cartes, par exemple).

Une meilleure façon serait d'avoir une méthode spéciale firePropertyChange() pour ce genre d'objet qui fait la manipulation spéciale. De cette façon, vous pouvez même éviter de créer une instance de PropertyChangeEvent. Voici un exemple pour le traitement BigDecimal (où equals() ne fonctionne pas du tout):

protected transient PropertyChangeSupport changeSupport = null; 

public void addPropertyChangeListener (String propertyName, PropertyChangeListener listener) 
{ 
    if (changeSupport == null) 
     changeSupport = new PropertyChangeSupport (this); 

    changeSupport.addPropertyChangeListener (propertyName, listener); 
} 

public void firePropertyChange (String propertyName, BigDecimal oldValue, BigDecimal newValue) 
{ 
    if (changeSupport == null) 
     return; 

    if (oldValue != null && newValue != null && oldValue.compareTo (newValue) == 0) { 
     return; 
    } 
    changeSupport.firePropertyChange(new PropertyChangeEvent(this, propertyName, 
               oldValue, newValue)); 
} 

[EDIT] Ce que vous faites est tout autre chose: Vous avez un parent et un enfant et que vous voulez les auditeurs de la parent pour recevoir des événements lorsque l'enfant change.

L'approche correcte ici consiste à ajouter PropertyChangeSupport au enfant. Lorsque l'enfant est ajouté au parent, le parent doit installer les écouteurs nécessaires dans l'enfant. Lorsqu'un événement est déclenché, il doit déclencher un second événement qui informe les écouteurs du parent du changement dans l'enfant (le parent doit transférer les événements).

+0

En fait, je veux le contraire de cela. Et pour toujours retourner la valeur codée en dur n'est pas exactement ce que devrait être égal. – stefita

+0

Dans ce cas, votre question n'est pas claire. Voulez-vous éviter les événements de déclenchement pour toute modification apportée à TransferQueueItem? Voulez-vous toujours un événement lorsque TransferQueueItem change? Voulez-vous toujours un événement lorsqu'une propriété de TransferQueueItem change? –

+0

Notez que c'est une différence si vous définissez un nouvel objet TransferQueueItem ou lorsque vous modifiez les propriétés de TransferQueueItem. –

1

c'est un cas de propertychangelisteners enchaînées:

TransferQueueItem devrait lancer leur propre PropertyChangeEvents qui doit être écouté par le TransferQueue dans lequel est inséré

Et en réponse TransferQueue doivent informer leurs auditeurs qu'un élément appartenant a modifié.

Chaque fois que j'ai un problème comme celui-ci dans lequel un objet doit relancer les événements que j'utilise cette convention (de mon équipe de travail):

1 Un objet ne peut lancer des événements qui lui-même est la source.

2 Si elle souhaite un événement délégué, elle lance un événement comme ceci: new PropertyChangeEvent (this, "DELEGATED_EVENT", null, receivedEvent).Alors que les auditeurs peuvent suivre la chaîne des événements.

Addicionally i ont une méthode statique dans une classe Util qui suivent la chaîne des événements et renvoie le tout premier événement, une whick propriété n'est pas « DELEGATED_EVENT »

+0

Merci pour les pointeurs! Il est logique de l'appliquer de cette façon. – stefita

Questions connexes