This answer为可观察列表提供解决方案,该列表将发送"列表更新" 通知列表元素的属性更改。
在我的例子中,这种可观察列表的元素(元素类)很复杂,我不想为每个成员变量实现属性。因此,我在元素类中添加了一个 BooleanProperty ,表示类的更改。
元素类
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyBooleanWrapper;
public class Element {
// ...
private ReadOnlyBooleanWrapper changeIndicatorWrapper;
public Element() {
//...
changeIndicatorWrapper = new ReadOnlyBooleanWrapper(false);
}
public ReadOnlyBooleanProperty changeIndicatorProperty() {
return changeIndicatorWrapper.getReadOnlyProperty();
}
public void someMethod() {
// Some update
changeIndicatorWrapper.set(!changeIndicatorWrapper.get());
}
}
可观察名单
ObservableList<Element> elementsObservableList = FXCollections.observableList(
new ArrayList<>(),
(Element element) -> new Observable[] { element.changeIndicatorProperty() }
);
elementsObservableList.addListener(new ListChangeListener<Element>() {
@Override
public void onChanged(Change<? extends Element> c) {
System.out.println("CHANGE");
while(c.next()) {
if (c.wasUpdated()) {
for (int i = c.getFrom(); i < c.getTo(); ++i)
System.out.println(elementsObservableList.get(i));
}
}
}
});
我的问题是关于这种方法。重复将 changeIndicatorProperty 设置为true,而不是触发更改事件。所以,我每次都需要反转 changeIndicatorProperty值 changeIndicatorWrapper.set(!changeIndicatorWrapper.get())
。这很奇怪,不是吗?
我可以以编程方式强制更新事件吗?
答案 0 :(得分:3)
很奇怪,不是吗?
不,这并不令人惊讶。要触发更改,需要进行更改。如果BooleanProperty
确定没有发生任何变化,因此听众没有得到任何通知,这仍然符合Property
的合同。
实际上还不需要Property
。我们需要的是Observable
通知它的观察者。您可以使用以下类并调用invalidate
来执行此操作:
public class SimpleObservable implements Observable {
private final List<InvalidationListener> listeners = new LinkedList<>();
@Override
public void addListener(InvalidationListener listener) {
listeners.add(listener);
}
@Override
public void removeListener(InvalidationListener listener) {
listeners.remove(listener);
}
public void invalidate() {
for (InvalidationListener listener : listeners) {
try {
listener.invalidated(this);
} catch (RuntimeException ex) {
}
}
}
}
示例:
public class Element {
protected final SimpleObservable observable = new SimpleObservable();
public Observable getObservable() {
return observable;
}
public static <T extends Element> ObservableList<T> observableArrayList() {
return FXCollections.observableArrayList(e -> new Observable[]{e.observable});
}
private void update() {
observable.invalidate();
}
public static void main(String[] args) {
ObservableList<Element> list = Element.observableArrayList();
list.addListener((ListChangeListener.Change<? extends Element> c) -> {
while (c.next()) {
if (c.wasUpdated()) {
System.out.println("update: [" + c.getFrom() + ", " + c.getTo() + ")");
}
}
});
list.addAll(new Element(), new Element(), new Element());
list.get(1).update();
}
}