PropertyChangeSupport和equals方法 [英] PropertyChangeSupport and equals method

查看:72
本文介绍了PropertyChangeSupport和equals方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将尽力解释我的问题:).我正在使用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));
}

您所做的完全是另外一回事:您有一个父母和一个孩子,并且您希望 parent 的侦听器在 child 更改时接收事件.

此处正确的方法是将PropertyChangeSupport添加到.将子级添加到父级后,父级必须在子级中安装必要的侦听器.触发事件后,它必须触发第二个事件,该事件将 child 中的更改通知 parent 的侦听器(父级必须转发事件).

I'll try to explain my problem as clear as possible :). I am using PropertyChangeSupport to notify registered views for changes in the properties. One of the property is an object which properties are changed every view seconds. I don't want to create for this particular object new instance every time it is being updated (for the propertychangelistener to notice the change), so I wrote my own equals method where I ommit the comparation to itself.

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

Unfortunatelly that doesn't have the effect I was looking for. If I create a copy of the object and fire the property change method on it, then it works fine.

What am I missing here?

-- Edit

I realized, that since I am using the same instance and not a copy of it, the properties are pointig the same place, thus the comparation would always come out true. Is there a workaround to that (besides creating a copy). Or how bad is to create a copy of an object every second, eg.

解决方案

You must always return true to tell PropertyChangeSupport that your object did not change. But that means equals() is broken for all objects of this class (so you can't use them in sets or maps anymore, for example).

A better way would be to have a special method firePropertyChange() for this kind of object which does the special handling. This way, you can even avoid to create an instance of PropertyChangeEvent, too. Here is an example for handling BigDecimal (where equals() doesn't work at all):

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] What you do is something else entirely: You have a parent and a child and you want listeners of the parent to receive events when the child changes.

The correct approach here is to add PropertyChangeSupport to the child. When the child is added to the parent, the parent must install the necessary listeners in the child. When an event is fired, it must fire a second event which informs the listeners of the parent of the change in the child (the parent must forward the events).

这篇关于PropertyChangeSupport和equals方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆