【问题标题】:ListChangeListener.Change: how to properly handle updated and permutated itemsListChangeListener.Change:如何正确处理更新和排列的项目
【发布时间】:2017-02-09 11:01:31
【问题描述】:

来自 JavaDoc:

ObservableList theList = ...;

 theList.addListener(new ListChangeListener<Item>() {
     public void onChanged(Change<tem> c) {
         while (c.next()) {
             if (c.wasPermutated()) {
                     for (int i = c.getFrom(); i < c.getTo(); ++i) {
                          //permutate
                     }
                 } else if (c.wasUpdated()) {
                          //update item
                 } else {
                     for (Item remitem : c.getRemoved()) {
                         remitem.remove(Outer.this);
                     }
                     for (Item additem : c.getAddedSubList()) {
                         additem.add(Outer.this);
                     }
                 }
             }
         }
     });
 }

添加和删除项目很简单,但是//update item// permutate 呢?

我如何知道哪些项目已被哪些其他项目置换?

更新到底是什么意思?是否只是再次将相同的项目添加到列表中?

然后呢

for (Item remitem : c.getRemoved()) {
remitem.remove(Outer.this);
}
or (Item additem : c.getAddedSubList()) {
additem.add(Outer.this);
}

Outer.this 是什么意思?

【问题讨论】:

    标签: javafx changelistener


    【解决方案1】:

    我如何知道哪些项目已被哪些其他项目置换?

    更改有一个getPermutation() 方法,用于描述元素是如何排列的。


    更新到底是什么意思?

    如果属于某个元素的属性发生更改,则列表会更新,尽管相同的元素仍保留在列表中(以相同的顺序)。例如,给定一个类

    public class Item {
    
        private final IntegerProperty value = new SimpleIntegerProperty();
    
        public final IntegerProperty valueProperty() {
            return value ;
        }
    
        public final int getValue() {
            return valueProperty().get();
        }
    
        public final void setValue(int value) {
            valueProperty().set(value);
        }
    
        public Item(int value) {
            setValue(value);
        }
    }
    

    在列表元素上调用setValue() 可能会触发更新。请注意,documentation 声明更新是“可选的”并且可能不会被所有列表触发。具体来说,要获取触发更新的列表,请使用extractor 创建它:

    ObservableList<Item> list = FXCollections.observableArrayList(
        item -> new Observable[] {item.valueProperty()});
    
    list.addAll(new Item(1), new Item(2), new Item(3));
    
    list.addListener((Change<? extends Item> c) -> {
        while (c.next()) {
            if (c.wasUpdated()) {
                System.out.println("Items from "+c.getFrom()+" to "+c.getTo()+" changed");
            }
        }
    });
    
    list.get(1).setValue(42);
    

    最后一行代码不会更改列表中的哪些元素或它们的顺序,但会更改其中一个元素的属性。因此,此更改将触发更新。


    Outer.this 是什么意思?

    它只是对周围类的当前对象的引用(假定类名Outer);即不是ListChangeListener 的匿名内部类实现的当前对象。请参阅What is the difference between Class.this and this in Java(和许多其他人)。我认为文档中代码 sn-p 的上下文应该是一个实现ObservableList 并维护自己的ObservableList 实例(装饰器模式)的类。它观察列表实例并更新自身以与它保持同步。

    【讨论】:

    • 非常感谢您的解释!关于 Outer.this 的另一个问题。代码不应该是Outer.this.remove(remitem)Outer.this.add(additem) intead 吗?
    • 我想在我的解释中,您建议的代码会更直观。也许这个想法是周围的类 (Outer) 是某种监听器,并且代码正在注册/取消注册监听器到添加和删除的项目。不完全确定文档中的意图。
    猜你喜欢
    • 2012-06-17
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 1970-01-01
    • 2017-09-07
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多