ListenerHandle

Nicolai Parlog edited this page Mar 8, 2015 · 6 revisions

This feature provides a way to add and remove listeners to/from observables without keeping a reference to both. I blogged about why this is desirable.

The feature's concept is described below before examples demonstrates its use. A small, self-contained demo showcases it. The comment on the package org.codefx.libfx.listener.handle provides further documentation and the main types to access this feature are ListenerHandle and ListenerHandles.

Concept

In the easy case, a listener is added to an observable instance and is never removed. It is then not necessary to hold on to any references to either the listener or the observable. But if the listener is supposed to be removed at some point in the future, this changes and it becomes necessary to hold on to both references.

With listener handles it is enough to hold on to the handle. The interface ListenerHandle provides two simple methods, namely attach() and detach(), which either add or remove the listener.

All LibFX features are aware of listener handles and return them wherever possible. The utility class ListenerHandles allows to create them for all JavaFX' observables. For other cases the ListenerHandleBuilder can be used to create a handle which executes attach and detach operations specified during construction.

Examples

Use ListenerHandles to create a handle for a listener on observable JavaFX classes:

Property<String> property;
ChangeListener<String> listener;

// this immediately adds the listener to the property
ListenerHandle initiallyAttachedHandle =
		ListenerHandles.createAttached(property, listener);

// it is also possible to create a handle
// without immediately adding the listener
ListenerHandle initiallyDetachedHandle =
		ListenerHandles.createDetached(property, listener);

Using a ListenerHandleBuilder it is easy to create a handle for custom objects. They do not have to fulfill any requirements (e.g. no interface to implement):

MyCustomObservable customObservable = new MyCustomObservable();
MyCustomListener customListener = new MyCustomListener();

// use 'ListenerHandles' to get a 'ListenerHandleBuilder'
ListenerHandles
		.createFor(customObservable, customListener)
		.onAttach((obs, listener) -> obs.doTheAdding(listener))
		.onDetach((obs, listener) -> obs.doTheRemoving(listener))
		.buildAttached();

Attaching and detaching the listener from the observable is trivial:

listenerHandle.attach();
listenerHandle.detach();