Groovy @Bindable and @Vetoable annotations
Рубрика: Groovy | 2 July 2008, 22:48 |
Vadim Voituk
Начиная с первых “бэт” версии 1.6 в Groovy были добавлены 2 встроенные аннотации (да-да! Groovy наконец-то полностью поддержирживает все возможности Java5!) : groovy.beans.Bindable и groovy.beans.Vetoable
Обе аннотации содержат в себе функионал который призван заменить стандартные Java-интерфейсы java.beans.PropertyChangeListener и java.beans.VetoableChangeListener и избавить разработчика от обилия классов-слушателей (listeners) и декларации дополнительных интерфейсов для бина.
Об этих нововведениях и их назначении было напечатано/перепечатано в каждом обзоре новых “фич” версии 1.6, но при этом нигде не встречалось описания как же все-таки “повесить” свой обработчик событий (listener).
Немного поковырявшись в исходниках Groovy удалось узнать такое:
1. При использовании аннотации @Bindable, сообщение об изменении значния свойства обьекта передается в замыкание, указанное в специальном свойстве propertyChange (имя совпадает с именем метода в PropertyChangeListener), в пределах того же бина, в котором произошло изменение.
При этом аргументом замыкания является экземпляр класса java.beans.PropertyChangeEvent.
2. Аналогично при использовании аннотации Vetoable используется замыкание, определенное в свойстве vetoableChange с тем же типом параметра замыкания (PropertyChangeEvent).
Пример использования аннотация @Bindable
import groovy.beans.Bindable
class MyClass {
@Bindable int id
@Bindable String name
def MyClass() {
//this.propertyChange = {
// println it.propertyName + " changed from " + it.oldValue + " to " + it.newValue
//}
}
}
def x = new MyClass()
x.propertyChange = {
println it.propertyName + " changed from " + it.oldValue + " to " + it.newValue
}
x.id = 10
x.name = "Hello"
Результат будет выглядеть так:
groovy Test.groovy
id changed from 0 to 10
name changed from null to Hello
Причем инициализацию свойства propertyChange можно проводить и в конструкторе (см. закомментированный код), но при этом нельзя восплользоваться статической инициализацией (почему? Не знаю).
Тоесть такой пример работать не будет:
class MyClass {
def propertyChange = {println it}
@Bindable int id
}
def x = new MyClass()
x.id = 10
Tweet
