JavaFx:将列表中的元素索引绑定到元素的属性

时间:2018-06-14 09:49:45

标签: java javafx binding javafx-8

我有ObservableList<Model>,其中模型有IntegerProperty,我想将丢失的元素的位置(索引)绑定到此IntegerProperty。因此,如果我移动该列表中的元素,我也想要更改属性。

我发现了一个类似的问题,但我不知道为什么它的答案被接受了,当答案与问题无关时...... 我在说这个:How to bind the position in a List to an attribute of that element?

我不需要对所选项目做任何事情,只需将listOf绑定到其属性列表。

我尝试了这个原因,但它没有更新ID我移动列表中的元素:

item.indexProperty().bind(Bindings.createIntegerBinding(() -> observableList.indexOf(item), observableList));

如果您在不使用ListChangeListener的情况下有任何其他建议,我将不胜感激。

2 个答案:

答案 0 :(得分:2)

ListChangeListener是一种很好的方法,因为它只需要使用一个监听器。

public static class Item {

    private final IntegerProperty index = new SimpleIntegerProperty();

    @Override
    public String toString() {
        return Integer.toString(index.get());
    }

}
ObservableList<Item> items = FXCollections.observableArrayList();
items.addListener((ListChangeListener.Change<? extends Item> c) -> {
    boolean hadNext;
    while ((hadNext = c.next()) && c.wasPermutated()) {
        int to = c.getTo();
        for (int i = c.getFrom(); i < to; i++) {
            items.get(i).index.set(i);
        }
    }

    while (hadNext) {
        if (c.wasReplaced()) {
            int to = c.getTo();
            for (int i = c.getFrom(); i < to; i++) {
                items.get(i).index.set(i);
            }
        } else {
            if (!c.wasUpdated()) {
                // add/remove change
                int to = items.size();
                for (int i = c.getFrom(); i < to; i++) {
                    items.get(i).index.set(i);
                }
            }
            break;
        }
        hadNext = c.next();
    }

});

或者你可以使用FXCollections.observableList并让支持列表处理:

private static class ItemsList extends AbstractList<Item> {

    private final List<Item> data = new ArrayList<>();

    @Override
    public Item get(int index) {
        return data.get(index);
    }

    @Override
    public int size() {
        return data.size();
    }

    private void updateFromIndex(int index) {
        int size = size();

        for (; index < size; index++) {
            data.get(index).index.set(index);
        }
    }

    @Override
    public Item remove(int index) {
        Item result = data.remove(index);
        updateFromIndex(index);
        return result;
    }

    @Override
    public void add(int index, Item element) {
        data.add(index, element);
        updateFromIndex(index);
    }

    @Override
    public Item set(int index, Item element) {
        element.index.set(index);
        return data.set(index, element);
    }

}
ObservableList<Item> items = FXCollections.observableList(new ItemsList());

请注意,处理操作的优化可以对备份列表进行多次插入/删除。

在这两种情况下

for (int i = 0; i < 5; i++) {
    System.out.println(items);
    items.add(new Item());
}
System.out.println(items);
Collections.swap(items, 0, 4);
System.out.println(items);
Collections.swap(items, 2, 3);
System.out.println(items);
Collections.swap(items, 0, 2);
System.out.println(items);

产生以下控制台打印输出:

[]
[0]
[0, 1]
[0, 1, 2]
[0, 1, 2, 3]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]

答案 1 :(得分:0)

“一个更简单易读的解决方案”可能是

"Authorization: Bearer ". $_Acceess-token,
"Accept: application/json",
"Content-type: application/json",
"odata.metadata: full",
"client-request-id: ".$_Client_ID,
"return-client-request-id: FALSE",
"X-AnchorMailbox: ".$_preferred_username_OR_EmailID
);

它首先初始化items.addListener((ListChangeListener.Change<? extends Model> c) -> { int i=0; for (Model model : c.getList()) { model.setIndex(i++); } }) 上的所有属性,并保持更新所有属性。
注意法比安的评论:

  

你可能做的工作超过必要的工作