【问题标题】:Is there a way to bind a ObservableList to a ObservableMap?有没有办法将 ObservableList 绑定到 ObservableMap?
【发布时间】:2019-12-25 15:10:47
【问题描述】:

我以ObservableMap<T, Foo> 的格式获取数据。 要在视图中实现此数据,我需要该映射的值,格式为 ObservableList<Foo>

因为我需要地图集合中的数据(以避免重复和其他原因),我想知道是否可以绑定这两个集合。

类似:

ObservableMap<Integer, Foo> data = FXCollections.observableHashMap();
ObservableList<Foo> target = FXCollections.observableArrayList();

// Won't work 
Bindings.bindContent(target, data.values());

绑定,因为数据可以在运行时更改。

编辑: 使用地图值初始化列表不起作用,因为地图中会添加额外的 Foo: 以字符串作为映射值的示例:

ObservableMap<Integer, String> map = FXCollections.observableHashMap();
map.put(1, "a");
map.put(2, "b");

ObservableList<String> list = FXCollections.observableArrayList(map.value());

//map = {1=a, 2=b}
//list = [a, b]
// ok

map.put(3, "c");

//map = {1=a, 2=b, 3=c}
//list = [a, b]
// no update    

【问题讨论】:

  • 你试过流吗?就像 Alexis C. 在这篇文章中所描述的那样 stackoverflow.com/questions/4138364/…
  • @ConstantinBeer 我的数据地图会随着时间的推移获得新值,因此我想保持地图和列表具有相同的值。据我所知,如果有变化,流不会更新。
  • 可观察列表是否需要修改?如果没有,实现一个由地图支持的自定义 TransformedList 相对容易(细节和魔鬼是亲密的朋友
  • 最简单的情况下(只改变map,list是只读的)可以手动监听map的变化,替换list中的item

标签: java javafx arraylist hashmap javafx-8


【解决方案1】:

从 ObservableMap 到 ObservableList

ObservableMap<Integer, Foo> data = FXCollections.observableHashMap();
ObservableList<Foo> target = FXCollections.observableArrayList(data.values());

【讨论】:

  • 我想保持目标更新。一旦使用 data.values() 进行初始化,就不会识别出任何数据变化。
  • 不,因为 observableArrayList(Collection) 的 api doc 明确指出 创建一个新的 observable 数组列表并添加一个 collection col 的内容。
  • @kleopatra 是的,但他想绑定它们,并且在向地图添加新值后将其自动放入列表中而无需再次更新,因此您的解决方案将无法正常工作。
  • @SURU a) 从来没有(不过,也许我稍后会做)发布解决方案。如果您的意思是我的评论/s:b)手动侦听器将始终有效 c)我在建议自定义 transformList 时是错误的(要求支持源是列表) - 由 ObservableMap 支持的自定义 ObservableList 可以,尽管
【解决方案2】:

我还没有在 Java 中找到内置的解决方案。当 Map 为数据源时,我使用了一个简单的 MapChangeListener,而 List 仅用于跟踪 Map 值列表的更改。

    ObservableMap<String, String> map = FXCollections.observableHashMap();
    ObservableList<String> list = FXCollections.observableArrayList();

    MapChangeListener<String, String> listener = c -> {
        if (c.wasRemoved()) {
            list.remove(c.getValueRemoved());
        }

        if (c.wasAdded()) {
            list.add(c.getValueAdded());
        }
    };

    map.addListener(listener);

    map.put("1", "A");
    map.put("2", "B");
    map.put("1", "A'");

    assertThat(list).containsExactlyInAnyOrder("A'", "B");

您应该保持可观察列表私有,并且只在外部公开不可修改的ObservableList,以防止意外添加不在地图中的列表条目。

【讨论】:

  • 我为此创建了一个实用程序类。这样就很容易重用代码。你可以找到要点here
猜你喜欢
  • 2012-07-07
  • 2010-12-19
  • 2017-10-20
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-13
相关资源
最近更新 更多