我会尽可能清楚地解释我的问题:)。我正在使用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));
}

[编辑]你所做的完全是另一回事:你有一个父母和一个孩子,你希望的听众在孩子改变时接收事件。

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

其他提示

这是一个链式propertychangelisteners的案例:

TransferQueueItem应该启动自己的PropertychangeEvents,必须由插入的TransferQueue监听

作为回应,TransferQueue必须通知其听众已拥有的项目已更改。

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

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

2如果它想要委托事件,它会启动这样的事件:new PropertyChangeEvent(this,“DELEGATED_EVENT”,null,receivedEvent)。这样听众就可以跟随事件链。

Addicionally我在Util类中有一个静态方法,它遵循事件链并返回第一个事件,一个whick属性不是“DELEGATED_EVENT”

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top