Javafx如何使绑定到属性列表

Def*_*ine 0 binding javafx properties observablelist

我想根据节点的宽度订购随机数量的节点。但是我无法计算宽度的总和(使用它们的属性),我有以下示例代码-我无法得知其中一个属性的变化:

@Override
public void start(Stage arg0) throws Exception {
    List<SimpleIntegerProperty> l = IntStream.range(0, 10)
            .mapToObj(SimpleIntegerProperty::new)
            .collect(Collectors.toList());
    ObservableList<IntegerProperty> widthAr = FXCollections.observableArrayList();
    widthAr.addAll(l);

    IntegerBinding nextheight = Bindings.createIntegerBinding(() -> widthAr.stream()
            .mapToInt(IntegerProperty::get)
            .sum(), widthAr);

    nextheight.addListener((v, o, n) -> System.out.println("New value: " + v.getValue()));

    //Now change randomly one of the IntegerProperties 
    ScheduledExecutorService tfsqueryScheduler = Executors.newScheduledThreadPool(1);

    tfsqueryScheduler.scheduleAtFixedRate(() -> {
        System.out.println("Changing");
        int i = (int) Math.round(Math.random() * 9.4);
        SimpleIntegerProperty v = l.get(i);
        v.set(0);
    }, 0, 3, TimeUnit.SECONDS);

    System.out.println("Start...");
}
Run Code Online (Sandbox Code Playgroud)

再也不会调用nextheight.addListener :( ...有什么想法吗?谢谢!

Jam*_*s_D 5

默认, ObservableList仅当列表的结构发生更改(例如,将项目添加到列表或从列表中删除)时,才触发更新,而不是在列表中的各个元素的状态发生更改时才触发更新。要创建一个列表,如果属于其任何元素的属性发生更改,则将触发通知,您需要使用extractor创建列表。

在这种情况下,您感兴趣的属性只是list元素本身,因此您需要替换

ObservableList<IntegerProperty> widthAr = FXCollections.observableArrayList();
Run Code Online (Sandbox Code Playgroud)

ObservableList<IntegerProperty> widthAr = 
    FXCollections.observableArrayList(w -> new Observable[] {w});
Run Code Online (Sandbox Code Playgroud)

还要注意,根据您的实际用例,可能需要通过将其设置为字段而不是局部变量,以确保未过早地垃圾回收您的绑定。