我有一个目标,它有一个目标清单。目标有一系列的策略。一种战略有一系列的战术。一种战术有一系列的任务。
我希望能够在TreeView中显示这一点,并且希望树能够与项同步。也就是说,如果我删除一个目标,这个目标以及它的孩子们也将从TreeView中消失。
到目前为止,这是我一直在尝试的。
/**
* 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);这是所有这些项的基类。在其构造函数中:
public PlanItem() {
CustomBinding.bindLists(treeItem.getChildren(), childPlanItems, PlanItem::getTreeItem);
}我正在使用我的自定义绑定,它将两个不同对象的列表绑定在一起。(或者,我可以使用EasyBind)。
/**
* 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,这也是递归的。
发布于 2014-09-04 13:00:24
您的bindLists方法是相当通用的,并且可以编写(就像现在一样),而不需要引用您现在正在处理的列表(即不引用PlanItem类)。所以我很可能会成功
public static <SRC, DEST> void bindLists(ObservableList<DEST> dest, ObservableList<SRC> src, ...) { ... }不过,请注意,映射函数只需能够应用于src的元素(因此它必须对src元素是一个类型的事物采取行动),并产生一些可以放在dest列表中的内容。因此,使用Function<SRC, DEST>可能会限制太大。试一试
public static <SRC, DEST> void bindLists(ObservableList<DEST> dest, ObservableList<SRC> src,
Function<? super SRC, ? extends DEST> transformer) { ... }现在你可以打电话了
bindLists(ObservableList<TreeItem<PlanItem>>, ObservableList<T>, PlanItem::getTreeItem)其中T是PlanItem或任何子类,而且应该很容易使用。
https://stackoverflow.com/questions/25656094
复制相似问题