我将尽可能清楚地解释我的问题:)。我使用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;
}不幸的是,这并没有达到我想要的效果。如果我创建一个对象的副本,并在其上触发属性更改方法,那么它工作得很好。
这里我漏掉了什么?
--编辑
我意识到,因为我使用的是相同的实例,而不是它的副本,所以属性指向相同的位置,因此比较总是正确的。是否有解决方法(除了创建副本之外)。或者每秒创建一个对象的副本是多么糟糕,例如。
发布于 2009-10-22 16:38:02
您必须始终返回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添加到子级。将子进程添加到父进程中时,父进程必须在子进程中安装必要的侦听器。当一个事件被触发时,它必须触发第二个事件,该事件通知父进程的监听器该子进程中的更改(父进程必须转发事件)。
发布于 2009-10-22 18:03:13
这是一个链式属性chained的例子:
TransferQueueItem应该启动它们自己的PropertychangeEvents,它必须被插入其中的TransferQueue监听
作为响应,TransferQueue必须通知它们的侦听器拥有的项目已更改。
每次我遇到像这样的问题,一个对象必须重新启动事件时,我都会使用(我的工作团队的)这个约定:
1对象只能启动源为自身的事件。
2如果它想要委托事件,它会像这样启动一个事件: new PropertyChangeEvent(this,"DELEGATED_EVENT",null,receivedEvent)。这样监听者就可以跟随事件链。
另外,我在Util类中有一个静态方法,它遵循events链并返回第一个事件,这个事件的属性不是"DELEGATED_EVENT“
https://stackoverflow.com/questions/1605762
复制相似问题