JavaFX - ObservableList和列表的项目更改 [英] JavaFX – ObservableList and list's item change

查看:154
本文介绍了JavaFX - ObservableList和列表的项目更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

This答案可观察列表提供解决方案,如果列表元素的属性列表更新 通知 >改变。

This answer provides a solution for an observable list that will send "list updated" notifications if properties of elements of the list change.

在我的例子中,这种可观察列表的元素(元素类)很复杂,我不知道喜欢为每个成员变量实现属性。因此,我在元素类中添加了一个 BooleanProperty ,表示类的更改。

In my case, elements (a Element class) of such observable list are complex and I don't like to implement property for each member variable. Due to this, I added into the Element class a BooleanProperty that indicates change of the class.

元素类

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());
    }
}






Observable List

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())。这很奇怪,不是吗?


My question is about this approach. Repeatedly set the changeIndicatorProperty to true not fire the change event. So, I need to reverse changeIndicatorProperty value changeIndicatorWrapper.set(!changeIndicatorWrapper.get()) each time. It is strange, isn't it?

我可以以编程方式强制更新事件吗?

Can I force programatically the update event?

推荐答案


这很奇怪,不是吗?

It is strange, isn't it?

不,这不是'令人惊讶的。要触发更改,需要进行更改。如果 BooleanProperty 确定没有发生任何更改,因此听众没有收到任何通知,这仍然符合 Property 。

No this isn't surprising. For a change to be triggered a change needs to happen. If the BooleanProperty determines no change does happen and therefore the listeners are not notified of anything, this still satisfies the contract of Property.

实际上不需要 Property 。我们需要的是一个 Observable ,它会通知它的观察者。您可以通过使用以下类并调用使无效来执行此操作:

Actually a Property isn't needed anyways. What is needed is a Observable that notifies it's observers. You could do this by using the following class and calling 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();
    }

}

这篇关于JavaFX - ObservableList和列表的项目更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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