如何将observableset转换为observablelist

时间:2014-07-17 15:54:08

标签: java java-8 javafx-8 observable

我正在尝试将项目设置为tableview,但是当我在模型中有一个observableset时,setitems方法需要一个observablelist.FXCollections实用程序类没有一个方法来创建一个可观察集合的可观察列表。我尝试了但是这导致了类强制转换异常(如预期的那样)。

目前我正在使用这种代码

new ObservableListWrapper<E>(new ArrayList<E>(pojo.getObservableSet()));

我遇到了一些问题:

  • 在表格中对此进行编辑是否会按预期更新基础集合?
  • 是对的&#39;这样做的方式

所以简而言之,我需要一个样式指南或最佳实践来在可观察集和可观察列表之间进行转换,因为我希望在构建java fx GUI时能够做很多事情

2 个答案:

答案 0 :(得分:4)

在表格中对此进行编辑会更新基础集合吗?

不,因为,您正在复制该集:

new ArrayList<E>(pojo.getObservableSet()

这是“正确”的做法吗?

我认为正确的方法不是这样做的。 Set不是List,反之亦然。两者都有特定的约束力。例如,列表是有序的,而集合不包含重复的元素。

此外,FXCollectionsBindings也不提供此类内容。

我希望将该集合保留为一组以强制执行唯一性

我猜您可以编写自定义ObservableList,例如Parent::children有类似的行为。如果添加了重复的子项,则会抛出IllegalArgumentException。如果您查看源代码,您会看到它是VetoableListDecorator扩展名。你可以写自己的:

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import com.sun.javafx.collections.VetoableListDecorator;

public class CustomObservableList<E> extends VetoableListDecorator<E> {

    public CustomObservableList(ObservableList<E> decorated) {
        super(decorated);
    }

    @Override
    protected void onProposedChange(List<E> toBeAdded, int... indexes) {
        for (E e : toBeAdded) {
            if (contains(e)) {
                throw new IllegalArgumentException("Duplicament element added");
            }
        }
    }
}

class Test {
    public static void main(String[] args) {
        Object o1 = new Object();
        Object o2 = new Object();

        Set<Object> set = new HashSet<Object>();
        set.add(o1);
        CustomObservableList<Object> list = new CustomObservableList<Object>(FXCollections.observableArrayList(set));
        list.add(o2);
        list.add(o1); // throw Exception
    }
}

答案 1 :(得分:2)

以防万一有人偶然发现这个问题寻找将ObservableSet转换为ObservableList的单向方式......我发布了我的解决方案。它不支持将数据反馈给集合(在我看来这不会很好,因为TableView没有无法更改值的概念)但支持集合的更新并保留(在此case)排序顺序。

.image-radio {
  cursor:pointer;
  box-sizing:border-box;
  -moz-box-sizing:border-box;
  -webkit-box-sizing:border-box;
  border:4px solid transparent;
  outline:0;
}

.image-radio input[type="radio"] {
 visibility:hidden;
}

.image-radio img {display:none;}
.image-radio input[type="radio"]:checked ~ img {display:block;}
.image-radio-checked {
  border-color:#f58723;
}

input[type=radio] {
  display:none;
}

.item-detail .item-price {
  font-weight:bold;
  color:#201E20;
  padding-bottom:10px;
}