【问题标题】:JavaFX – ObservableList and list's item changeJavaFX – ObservableList 和列表的项目变化
【发布时间】:2017-01-06 20:02:03
【问题描述】:

This answer可观察列表 提供了一个解决方案,如果列表元素的属性 “更新列表” 通知,该列表将发送强>改变。

就我而言,这种可观察列表的元素(元素类)很复杂,我不喜欢为每个成员变量实现属性。因此,我在 Element 类 中添加了一个 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())。很奇怪,不是吗?

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

【问题讨论】:

    标签: javafx observable


    【解决方案1】:

    很奇怪,不是吗?

    不,这并不奇怪。为了触发更改,需要发生更改。如果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();
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-21
      • 1970-01-01
      • 1970-01-01
      • 2017-08-20
      • 2017-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多