HashMap的ObservableMap作为值类型不触发MapChangeListener

时间:2017-05-31 08:50:46

标签: java javafx

我试图建立一个ObservableMap>在我的视图中与监听器链接。

这是我使用的代码:

ObservableMap<Integer, HashMap<String, Integer>> map = FXCollections.observableHashMap();

    map.addListener((MapChangeListener.Change<? extends Integer, ? extends HashMap<String, Integer>> change) -> {
        System.out.println("Changed key: " + change.getKey());
    });

    HashMap<String, Integer> store1 = new HashMap<>();
    store1.put("apple", 100);
    store1.put("strawberry", 123);
    store1.put("lemon", 165);
    map.put(1, store1);

    HashMap<String, Integer> store2 = new HashMap<>();
    store2.put("peach", 45);
    store2.put("blackberry", 90);
    store2.put("melon", 10);
    map.put(2, store2);

    HashMap<String, Integer> cpStore2 = map.get(2);
    cpStore2.put("peach", 40);
    map.put(2, cpStore2);

如果我执行,我得到这个:

Changed key: 1
Changed key: 2

所以我的问题是,当我在地图上进行更新时,没有触发任何事件。我实际上需要这个。

任何人都知道我该怎么办?

2 个答案:

答案 0 :(得分:1)

如果值更改,则会触发事件。但是你用相同的密钥放置相同的地图。因此,很明显没有更改事件。要确保触发事件,您可以使用现有值创建新地图并放置新地图:

HashMap<String, Integer> cpStore2 = new HashMap<String, Integer>(map.get(2));
// cpStore2 is another map than store2 but with the same values
cpStore2.put("peach", 40);
map.put(2, cpStore2);

答案 1 :(得分:0)

我看到ObservableMapWrapper类的实现返回FXCollections.observableHashMap();,代码如下:

@Override
public V put(K key, V value) {
    V ret;
    if (backingMap.containsKey(key)) {
        ret = backingMap.put(key, value);
        if (ret == null && value != null || ret != null && !ret.equals(value)) {
            callObservers(new SimpleChange(key, ret, value, true, true));
        }
    } else {
        ret = backingMap.put(key, value);
        callObservers(new SimpleChange(key, ret, value, true, false));
    }
    return ret;

因此,您可以在添加或更新新值时触发侦听器。但在您的代码中:

HashMap<String, Integer> cpStore2 = map.get(2);
cpStore2.put("peach", 40);
map.put(2, cpStore2);

cpStore2是键2的旧值,你可以这样做:

HashMap<String, Integer> cpStore2 = new HashMap<>();
    cpStore2.put("peach", 40);
    map.put(2, cpStore2);

你将触发听众。见上面代码的结果:

Changed key: 1
Changed key: 2
Changed key: 2