gpt4 book ai didi

java - ChangeListener 没有给出正确的旧值

转载 作者:行者123 更新时间:2023-11-30 08:48:56 26 4
gpt4 key购买 nike

代码如下:

package sample;

import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;

/**
* Created by IDEA on 29/07/15.
*/
public class ListPropertyTest {
public static void main(String[] args) {
ListProperty<String> lp =
new SimpleListProperty<>(FXCollections.observableArrayList());
lp.addListener(new ListChangeListener<String>() {
@Override
public void onChanged(Change<? extends String> c) {
while(c.next()) {
String action = c.wasPermutated() ? "perm"
: c.wasUpdated() ? "upd"
: c.wasRemoved() ? "rem"
: c.wasAdded() ? "add" : "";
System.out.println("Action: " + action);
System.out.println("Removed: " + c.getRemoved());
System.out.println("Added: " + c.getAddedSubList());
}
}
});

lp.addListener(new ChangeListener<ObservableList<String>>() {
@Override
public void changed(ObservableValue<? extends ObservableList<String>> observable, ObservableList<String> oldValue, ObservableList<String> newValue) {
System.out.println("List changed.");
System.out.println("Old: " + oldValue);
System.out.println("New: " + newValue);
}
});

lp.addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
System.out.println("List invalid");
}
});

System.out.println("Add =========");
lp.addAll("one", "two");
System.out.println("Set =========");
lp.set(FXCollections.observableArrayList("two", "three"));
System.out.println("Remove ============");
lp.remove("two");
}
}

结果:

Add =========
List invalid
List changed.
Old: [one, two]
New: [one, two]
Action: add
Removed: []
Added: [one, two]
Set =========
List invalid
List changed.
Old: [one, two]
New: [two, three]
Action: rem
Removed: [one, two]
Added: [two, three]
Remove ============
List invalid
List changed.
Old: [three]
New: [three]
Action: rem
Removed: [two]
Added: []

如您所见,更改监听器仅在“设置”部分表现正确。

最佳答案

其中大部分是预期行为。

A ListProperty既是 ObjectProperty<ObservableList>和一个 ObservableList .

成为 ObjectProperty<ObservableList>意味着它包装(包含对ObservableList的引用)并且有 setValue(ObservableList) (或 set(...) )和 getValue()方法。作为ObjectProperty<ObservableList> , 你可以注册一个 ChangeListener<ObservableList>用它。如果对包装列表的引用发生变化,由某人调用setValue(ObservableList) , ChangeListener<ObservableList>.changed(...)方法在任何已注册的 ChangeListener 上被调用, 传入对 ListProperty 的引用本身,旧ObservableList引用,以及新的 ObservableList引用。当您调用 set 时,您会看到此行为在您的代码中。

然而,当您简单地更改列表的内容时,包装列表仍然是相同的物理对象。因此,“旧列表”和“新列表”是一回事。这是一个 bug在这种情况下,更改监听器会触发通知;感谢@kleopatra 指出这一点。

A ListProperty还实现了 ObservableList , 通过委派 ObservableList对包装列表实例的方法调用。这意味着如果列表的内容发生变化,任何 ListChangeListener已在 ListProperty 注册得到通知。再次注意,在这种情况下只有一个列表对象;只是修改了内容。

您可以获得有关 ObservableList 发生的更改的详细信息通过 Change传递给 onChanged(...) 的对象方法,正如您在 onChanged 的输出中观察到的那样方法。注意 c.getFrom()c.getTo()也会为您提供已更改项目的索引。

我几乎从不需要 ListProperty : 在绝大多数用例中,我只使用普通的 ObservableList 就足够了执行。基于对象列表的控件(例如 ListViewTableView )使用它们,因此您可以调用 setItems(...)传递现有的 ObservableList如果你需要,或者(可能更常见)你可以调用getItems()检索当前列表并修改它。从上面的解释可以看出,ListProperty允许这些控件观察任何一种变化。但很可能在您自己的代码中,您将使用 ObservableList直接使用的次数远多于使用 ListProperty .

关于java - ChangeListener 没有给出正确的旧值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31688493/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com