ObservableMap

每当有一个值被修改时,可观察的映射(observable map)都会触发一个PropertyChangeEvent。我们也可以通过“as”关键字把一个普通的映射转换为一个可观察的映射:

// 不要忘了导入
import java.beans.*
def map = [:] as ObservableMap
map.addPropertyChangeListener({ evt ->
   println "${evt.propertyName}: ${evt.oldValue} -> ${evt.newValue}"
} as PropertyChangeListener)
 
map.key = 'value'  // 输出 key: null -> value
map.key = 'Groovy' // 输出 key: value -> Groovy

我们也可以把一个已存在的映射包装为一个ObservableMap

import java.beans.*
def sorted = [a:1,b:2] as TreeMap
def map = new ObservableMap(sorted)
map.addPropertyChangeListener({ evt ->
   println "${evt.propertyName}: ${evt.oldValue} -> ${evt.newValue}"
} as PropertyChangeListener)
map.key = 'value'
assert ['a','b','key'] == (sorted.keySet() as List)
assert ['a','b','key'] == (map.keySet() as List)

最后一点,我们可以指定一个闭包作为一个附加的参数,它会像一个属性的过滤器一样,过滤当它们的值改变时是否应该触发一个PropertyChangeEvent,在与Expando一起使用的时候这点非常有用。这个过滤闭包可能需要2个参数(属性的名称和它的值)或更少(属性的值)。

import java.beans.*
def map = new ObservableMap({!(it instanceof Closure)})
map.addPropertyChangeListener({ evt ->
   println "${evt.propertyName}: ${evt.oldValue} -> ${evt.newValue}"
} as PropertyChangeListener)
def bean = new Expando( map )
bean.lang = 'Groovy'  // 输出 lang: null -> Groovy
bean.sayHello = { name -> "Hello ${name}" } // 没有输出,事件被略过了
assert 'Groovy' == bean.lang
assert 'Hello Groovy' == bean.sayHello(bean.lang)
 
wiki/user_guide/observablemap.txt · 最后更改: 2008-09-30 21:39 由 johnny
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki