Вопрос

Я постараюсь объяснить мою проблему как можно яснее :). Я использую PropertyChangeSupport для уведомления зарегистрированных представлений об изменениях в свойствах. Одним из свойств является объект, свойства которого меняются каждые секунды просмотра. Я не хочу создавать для этого конкретного объекта новый экземпляр каждый раз, когда он обновляется (чтобы propertychangelistener заметил это изменение), поэтому я написал свой собственный метод equals, в котором я пропускаю сравнение для себя.

@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;
}

К сожалению, это не имеет эффекта, который я искал. Если я создаю копию объекта и запускаю метод изменения свойства, он работает нормально.

Что мне здесь не хватает?

- Изменить

Я понял, что, поскольку я использую один и тот же экземпляр, а не его копию, свойства указывают на одно и то же место, поэтому сравнение всегда будет выполнено. Есть ли обходной путь к этому (помимо создания копии). Или как плохо создавать копию объекта каждую секунду, например.

Это было полезно?

Решение

Вы всегда должны возвращать true , чтобы сообщить PropertyChangeSupport , что ваш объект не изменился. Но это означает, что equals () не работает для всех объектов этого класса (например, вы больше не можете использовать их в наборах или картах).

Лучшим способом было бы иметь специальный метод firePropertyChange () для этого типа объекта, который выполняет специальную обработку. Таким образом, вы даже можете избежать создания экземпляра PropertyChangeEvent . Вот пример для обработки BigDecimal (где equals () вообще не работает):

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] Что вы делаете, это совсем другое: у вас есть родитель и ребенок, и вы хотите, чтобы слушатели parent получали события, когда child изменяется.

Правильный подход здесь - добавить PropertyChangeSupport в child . Когда дочерний элемент добавляется к родительскому элементу, родительский компонент должен установить необходимые дочерние элементы в дочернем элементе. Когда событие вызывается, оно должно запустить второе событие, которое информирует слушателей parent об изменении в child (родитель должен пересылать события).

Другие советы

это случай цепочки измененных свойств:

TransferQueueItem должен запустить свои собственные PropertychangeEvents, которые должны прослушиваться TransferQueue, в который вставлено

И в ответ TransferQueue должен уведомить своих слушателей, что принадлежащий элемент изменился.

Каждый раз, когда у меня возникает такая проблема, когда объект должен перезапускать события, я использую это соглашение (моей рабочей команды):

1 Объект может запускать только события, источником которых является сам.

2 Если ему нужно делегировать событие, оно запускает событие, подобное следующему: new PropertyChangeEvent (this, " DELEGATED_EVENT " ;, null, receiveEvent). Чтобы слушатели могли следить за цепочкой событий.

У меня есть статический метод в классе Util, который следует за цепочкой событий и возвращает самое первое событие, свойство whick не является " DELEGATED_EVENT "

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top