ControlPropertyListener

nicolaiparlog edited this page Nov 22, 2014 · 4 revisions

This feature is concerned with the property map of JavaFX controls. The map is used by the control to provide a back door which allows its skin and behavior to change its state. ControlPropertyListener makes creating and handling of the necessary map listeners easier and more readable.

The feature's concept is described below before examples demonstrate its use. More examples can be found in a demo file in the code. The packages and classes provide further documentation. The best entry point is the comment on the package org.codefx.libfx.control.properties.

Concept

Each JavaFX Control has a property map, which can be publicly accessed with getProperties(). This can (and should only) be used by the control's skin and behavior to suggest changes to the control's state. The control adds a MapChangeListener to the map and processes each change.

Implementing such a listener is not difficult, but some details have to be considered. This makes the code a little lengthy and hinders readability while at the same time repeating the same pattern over and over.

This feature provides usability functions to create such a listener in a concise and readable way. It is aware of listener handles and returns them when adding a listener.

Examples

The control has a read only property which indicates whether something is dragged over it. The behavior is responsible for informing the control when this is the case but can not set the property directly because it is read only. Instead, it adds the key Dragged with either true or false to the control's property map whenever the dragged state changes.

The control now has to listen to those changes. It creates a listener as follows:

ControlProperties.on(getProperties())
	.forKey("Dragged")
	.processValue(dragged -> draggedProperty().set(dragged))
	.buildAttached();

If the listener needs to be detached and reattached, the returned instance provides the means:

ControlPropertyListenerHandle draggedListener = ControlProperties
		.on(getProperties())
		.forKey("Dragged")
		.processValue(dragged -> draggedProperty().set(dragged))
		.buildAttached();

// code...

draggedListener.detach()

// code...

draggedListener.attach()