In this Kotlin tutorial, we’re gonna look at how to make an observable property by using Kotlin delegated property.
>>> Refer to: JavaSampleApproach.com
I. Technology
– Java 1.8
– Kotlin 1.1.2
II. Overview
We will create an example that can notify listener when a property of an object changes.
Java has a mechanism for this notification: PropertyChangeSupport
class manages a list of listeners and dispatches PropertyChangeEvent
events to them.
To use it, we will create a helper class that will store a PropertyChangeSupport
instance and keep track of PropertyChangeListener
.
1 2 3 4 5 |
open class PropertyChangeAware { protected val propertyChangeSupport = PropertyChangeSupport(this) fun add/remove PropertyChangeListener(listener) } |
Then the class that has property to be notified will extend this helper class:
1 2 3 4 5 6 7 |
class Person(val name: String, age: Int, message: String) : PropertyChangeAware() { private val observer = {...} var age: Int by Delegates.observable(age, observer) var message: String by Delegates.observable(message, observer) } |
– name
is read-only property
– everytime age
or message
is changed, class will notify its listeners via observer
with PropertyChangeSupport.firePropertyChange()
method:
1 2 3 4 5 |
private val observer = { property: KProperty<*>, oldValue: Any, newValue: Any -> propertyChangeSupport.firePropertyChange(property.name, oldValue, newValue) } |
property
is represented as an object of type KProperty
. We can access the name of the property as KProperty.name
.
Add listener to Person
object using PropertyChangeAware.addPropertyChangeListener()
method or remove listener using PropertyChangeAware.removePropertyChangeListener()
method:
1 2 |
person.addPropertyChangeListener(PropertyChangeListener) person.removePropertyChangeListener(PropertyChangeListener) |
Now, everytime we change value of the property, PropertyChangeEvent
event will be dispatched to listener.
III. Practice
1. Helper Class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.kotlination.observableproperty import java.beans.PropertyChangeSupport import java.beans.PropertyChangeListener open class PropertyChangeAware { protected val propertyChangeSupport = PropertyChangeSupport(this) fun addPropertyChangeListener(listener: PropertyChangeListener) { propertyChangeSupport.addPropertyChangeListener(listener) } fun removePropertyChangeListener(listener: PropertyChangeListener) { propertyChangeSupport.removePropertyChangeListener(listener) } } |
2. Class with delegated property
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package com.kotlination.observableproperty import kotlin.properties.ObservableProperty import kotlin.properties.Delegates import kotlin.reflect.KProperty class Person(val name: String, age: Int, message: String) : PropertyChangeAware() { private val observer = { property: KProperty<*>, oldValue: Any, newValue: Any -> propertyChangeSupport.firePropertyChange(property.name, oldValue, newValue) } var age: Int by Delegates.observable(age, observer) var message: String by Delegates.observable(message, observer) } |
3. Run and check Result
Run the code below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package com.kotlination.observableproperty import java.beans.PropertyChangeListener fun main(args: Array<String>) { val person = Person("Andrien", 27, "Kotlination.com is good!") person.addPropertyChangeListener( PropertyChangeListener { event -> println("Property [${event.propertyName}] changed " + "from [${event.oldValue}] to [${event.newValue}]") } ) person.age = 28 person.message = "Be a Kotlineer." } |
Check Result:
1 2 |
Property [age] changed from [27] to [28] Property [message] changed from [Kotlination.com is good!] to [Be a Kotlineer.] |