首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PropertyChangeSupport和equals方法

PropertyChangeSupport和equals方法
EN

Stack Overflow用户
提问于 2009-10-22 16:29:40
回答 2查看 1.3K关注 0票数 0

我将尽可能清楚地解释我的问题:)。我使用PropertyChangeSupport通知已注册的视图属性中的更改。其中一个属性是一个对象,它的属性每隔几秒钟就会更改一次。我不想每次更新时都为这个特定的对象创建新实例(为了让propertychangelistener注意到变化),所以我编写了自己的equals方法,其中省略了对自身的比较。

代码语言:javascript
复制
@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;
}

不幸的是,这并没有达到我想要的效果。如果我创建一个对象的副本,并在其上触发属性更改方法,那么它工作得很好。

这里我漏掉了什么?

--编辑

我意识到,因为我使用的是相同的实例,而不是它的副本,所以属性指向相同的位置,因此比较总是正确的。是否有解决方法(除了创建副本之外)。或者每秒创建一个对象的副本是多么糟糕,例如。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-10-22 16:38:02

您必须始终返回true以告诉PropertyChangeSupport您的对象没有更改。但这意味着这个类的所有对象的equals()都失效了(例如,您不能再在集合或映射中使用它们)。

一种更好的方法是为这类对象提供一个特殊的方法firePropertyChange(),它执行特殊的处理。这样,您甚至还可以避免创建PropertyChangeEvent的实例。下面是一个处理BigDecimal的示例( equals()根本不能工作):

代码语言:javascript
复制
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));
}

您所做的编辑完全是另外一回事:您有一个父进程和一个子进程,并且希望父进程的侦听器在子进程发生更改时接收事件。

这里的正确方法是将PropertyChangeSupport添加到子级。将子进程添加到父进程中时,父进程必须在子进程中安装必要的侦听器。当一个事件被触发时,它必须触发第二个事件,该事件通知父进程的监听器该子进程中的更改(父进程必须转发事件)。

票数 1
EN

Stack Overflow用户

发布于 2009-10-22 18:03:13

这是一个链式属性chained的例子:

TransferQueueItem应该启动它们自己的PropertychangeEvents,它必须被插入其中的TransferQueue监听

作为响应,TransferQueue必须通知它们的侦听器拥有的项目已更改。

每次我遇到像这样的问题,一个对象必须重新启动事件时,我都会使用(我的工作团队的)这个约定:

1对象只能启动源为自身的事件。

2如果它想要委托事件,它会像这样启动一个事件: new PropertyChangeEvent(this,"DELEGATED_EVENT",null,receivedEvent)。这样监听者就可以跟随事件链。

另外,我在Util类中有一个静态方法,它遵循events链并返回第一个事件,这个事件的属性不是"DELEGATED_EVENT“

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1605762

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档