首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自动更新嵌套项的TreeView

自动更新嵌套项的TreeView
EN

Stack Overflow用户
提问于 2014-09-04 01:41:37
回答 1查看 452关注 0票数 0

我有一个目标,它有一个目标清单。目标有一系列的策略。一种战略有一系列的战术。一种战术有一系列的任务。

我希望能够在TreeView中显示这一点,并且希望树能够与项同步。也就是说,如果我删除一个目标,这个目标以及它的孩子们也将从TreeView中消失。

到目前为止,这是我一直在尝试的。

代码语言:javascript
复制
/**
 * The base class for all PlanItems, which include ActionItems down to
 * ActionTasks, and Objectives down to Tasks.
 *
 * @author Toni-Tran
 */
public class PlanItem implements Comparable<PlanItem> {
    protected ObservableList<PlanItem> childPlanItems = FXCollections
            .observableArrayList();
    protected TreeItem<PlanItem> treeItem = new TreeItem<>(this);

这是所有这些项的基类。在其构造函数中:

代码语言:javascript
复制
public PlanItem() {
    CustomBinding.bindLists(treeItem.getChildren(), childPlanItems, PlanItem::getTreeItem);
}

我正在使用我的自定义绑定,它将两个不同对象的列表绑定在一起。(或者,我可以使用EasyBind)。

代码语言:javascript
复制
/**
 * Binds a source list's elements to a destination list. Any changes made in
 * the source list will reflect in the destination list.
 *
 * @param <SRC> The source list's object type.
 * @param <DEST> The destination list's object type.
 * @param dest The destination list that will be bound to the src list.
 * @param src The source list to watch for changes, and propagate up to the
 * destination list.
 * @param transformer A function that will transform a source list data
 * type, A, into a destination list data type, B.
 */
public static <SRC extends Object, DEST extends Object> void bindLists(
        ObservableList<DEST> dest, ObservableList<SRC> src, Function<SRC, DEST> transformer) {
    /*Add the initial data into the destination list.*/
    for (SRC a : src) {
        dest.add(transformer.apply(a));
    }
    /*Watch for future data to add to the destination list. Also watch for removal
     of data form the source list to remove its respective item in the destination
     list.*/
    src.addListener((ListChangeListener.Change<? extends SRC> c) -> {
        while (c.next()) {
            /*Watch for removed data.*/
            if (c.wasRemoved()) {
                for (SRC a : c.getRemoved()) {
                    int from = c.getFrom();
                    dest.remove(from);
                }
            }
            /*Watch for added data.*/
            if (c.wasAdded()) {
                for (SRC a : c.getAddedSubList()) {
                    int indexAdded = src.indexOf(a);
                    dest.add(indexAdded, transformer.apply(a));
                }
            }
        }
    });
}

我不确定这是不是正确的方法。子项列表通常是扩展PlanItem的对象列表,而不仅仅是PlanItem本身。那不是应该是ObservableList<? extends PlanItem>吗?这样做会使我的其余代码变得复杂。

计划是创建一个包装TreeItem的PlanItem。然后,将TreeItem的子TreeItems与PlanItem的子PlanItems同步。对于每个嵌套的PlanItem,这也是递归的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-04 13:00:24

您的bindLists方法是相当通用的,并且可以编写(就像现在一样),而不需要引用您现在正在处理的列表(即不引用PlanItem类)。所以我很可能会成功

代码语言:javascript
复制
public static <SRC, DEST> void bindLists(ObservableList<DEST> dest, ObservableList<SRC> src, ...) { ... }

不过,请注意,映射函数只需能够应用于src的元素(因此它必须对src元素是一个类型的事物采取行动),并产生一些可以放在dest列表中的内容。因此,使用Function<SRC, DEST>可能会限制太大。试一试

代码语言:javascript
复制
public static <SRC, DEST> void bindLists(ObservableList<DEST> dest, ObservableList<SRC> src, 
     Function<? super SRC, ? extends DEST> transformer) { ... }

现在你可以打电话了

代码语言:javascript
复制
bindLists(ObservableList<TreeItem<PlanItem>>, ObservableList<T>, PlanItem::getTreeItem)

其中TPlanItem或任何子类,而且应该很容易使用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25656094

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档