Events and Listeners — Syntax and Techniques

Naming Events

Define an event by declaring an event name inside an events block, typically in the class that generates the event. For example, the following class creates an event called ToggledState, which might be triggered whenever a toggle button's state changes.

classdef ToggleButton < handle
   properties
      State = false
   end
   events
      ToggledState
   end
end

Triggering Events

At this point, the ToggleButton class has defined a name that it associates with the toggle button state changes—toggling on and toggling off. However, a class method controls the actual firing of the events. To accomplish this, the ToggleButton class adds a method to trigger the event:

classdef ToggleButton < handle
   properties
      State = false
   end
   events
      ToggledState
   end
   methods
   ...
      function OnStateChange(obj,newState)
      % Call this method to check for state change
         if newState ~= obj.State
            obj.State = newState;
            notify(obj,'ToggledState'); % Broadcast notice of event
         end
      end 
   end
end

The OnStateChange method calls notify to trigger the event, using the handle of the ToggleButton object that owns the event and the string name of the event.

Listening to Events

Once the call to notify triggers an event, MATLAB® broadcasts a message to all registered listeners. To register a listener for a specific event, use the addlistener handle class method. For example, the following class defines objects that listen for the ToggleState event defined in the class ToggleButton.

classdef RespondToToggle < handle
   methods
      function obj = RespondToToggle(toggle_button_obj)
         addlistener(toggle_button_obj,'ToggledState',@RespondToToggle.handleEvnt);
      end
   end
   methods (Static)
      function handleEvnt(src,evtdata)
         if src.State
            disp('ToggledState is true')  % Respond to true ToggleState here
         else 
            disp('ToggledState is false')  % Respond to false ToggleState here
         end 
      end
   end
end

The class RespondToToggle adds the listener from within its constructor. The class defines the callback (handleEvnt) as a static method that accepts the two standard arguments:

  • src — the handle of the object triggering the event (i.e., a ToggleButton object)

  • evtdata — an event.EventData object

The listener executes the callback when the specific ToggleButton object executes the notify method, which it inherits from the handle class.

For example, create instances of both classes:

tb = ToggleButton;
rtt = RespondToToggle(tb);

Whenever you call the ToggleButton object's OnStateChange method, notify triggers the event:

tb.OnStateChange(true)
ToggledState is true

tb.OnStateChange(false)
ToggledState is false

Removing Listeners

You can remove a listener object by calling delete on its handle. For example, if the class RespondToToggle above saved the listener handle as a property, you could delete the listener:

classdef RespondToToggle < handle
   properties
      ListenerHandle
   end
   methods
      function obj = RespondToToggle(toggle_button_obj)
         hl = addlistener(toggle_button_obj,'ToggledState',@RespondToToggle.handleEvnt);
         obj.ListenerHandle = hl; 
      end
   end
   ...
end

With this code change, you can remove the listener from an instance of the RespondToToggle class. For example:

tb = ToggleButton;
rtt = RespondToToggle(tb); 

At this point, the object rtt is listening for the ToggleState event triggered by object tb. To remove the listener, call delete on the property containing the listener handle:

delete(rtt.ListenerHandle)

You do not need to explicitly delete a listener. MATLAB automatically deletes the listener when the object's lifecycle ends (e.g., when the rtt object is deleted).

See Limiting Listener Scope — Constructing event.listener Objects Directly for related information.

Defining Event-Specific Data

Suppose that you want to pass the state of the toggle button as a result of the event to the listener callback. You can add more data to the default event data by subclassing the event.EventData class and adding a property to contain this information. You then can pass this object to the notify method.

    Note:   To save and load objects that are subclasses of event.EventData, such as ToggleEventData, enable the ConstructOnLoad class attribute for the subclass.

classdef (ConstructOnLoad) ToggleEventData < event.EventData
   properties
      NewState
   end

   methods
      function data = ToggleEventData(newState)
         data.NewState = newState;
      end
   end
end

The call to notify uses the ToggleEventData constructor to create the necessary argument.

notify(obj,'ToggledState',ToggleEventData(newState));

Ways to Create Listeners

When you call the notify method, the MATLAB runtime sends the event data to all registered listener callbacks. There are two ways to create a listener:

  • Use the addlistener method, which binds the listener to the lifecycle of the object(s) that will generate the event. The listener object persists until the object it is attached to is destroyed.

  • Use the event.listener class constructor. In this case, the listeners you create are not tied to the lifecycle of the object(s) being listened to. Instead the listener is active so long as the listener object remains in scope and is not deleted.

Attach Listener to Event Source — Using addlistener

The following code defines a listener for the ToggleState event:

lh = addlistener(obj,'ToggleState',@CallbackFunction)

The arguments are:

  • obj — The object that is the source of the event

  • ToggleState — The event name passed as a string

  • @CallbackFunction — A function handle to the callback function

The listener callback function must accept at least two arguments, which are automatically passed by the MATLAB runtime to the callback. The arguments are:

The callback function must be defined to accept these two arguments:

function CallbackFunction(src,evnt)
   ...
end

In cases where the event data (evnt) object is user defined, it must be constructed and passed as an argument to the notify method. For example, the following statement constructs a ToggleEventData object and passes it to notify as the third argument:

notify(obj,'ToggledState',ToggleEventData(newState));

Defining Listener Callback Functions provides more information on callback syntax.

Limiting Listener Scope — Constructing event.listener Objects Directly

You can also create listeners by calling the event.listener class constructor directly. When you call the constructor instead of using addlistener to create a listener, the listener exists only while the listener object you create is in scope (e.g., within the workspace of an executing function). It is not tied to the event-generating object's existence.

The event.listener constructor requires the same arguments as used by addlistener — the event-naming object, the event name, and a function handle to the callback:

lh = event.listener(obj,'ToggleState',@CallbackFunction)

If you want the listener to persist beyond the normal variable scope, you should use addlistener to create it.

Temporarily Deactivating Listeners

The addlistener method returns the listener object so that you can set its properties. For example, you can temporarily disable a listener by setting its Enabled property to false:

lh.Enabled = false;

To re-enable the listener, set Enabled to true.

Enabling and Disabling the Listeners provides an example.

Permanently Deleting Listeners

Calling delete on a listener object destroys it and permanently removes the listener:

delete(lh) % Listener object is removed and destroyed

Defining Listener Callback Functions

Callbacks are functions that execute when the listener receives notification of an event. Typically, you define a method in the class that creates the listener as the callback function. Pass a function handle that references the method to addlistener or the event.listener constructor when creating the listener.

function_handle provides more information on function handles.

All callback functions must accept at least two arguments:

  • The handle of the object that is the source of the event

  • An event.EventData object or an object that is derived from the event.EventData class (see Defining Event-Specific Data for an example that extends this class).

Callback Syntax

For an function:

@functionName

For an ordinary method called with an object of the class:

@obj.methodName

For an static method:

@ClassName.methodName

Adding Arguments to a Callback Function

Ordinary class methods (i.e., not static methods) require a class object as an argument, so you need to add another argument to the callback function definition. If your listener callback is a method of the class of an object, obj, then your call to addlistener would use this syntax:

hlistener = addlistener(eventSourceObj,'MyEvent',@obj.listenMyEvent)

Another option is to use an anonymous function.

For example, create a method to use as your callback function and reference this method as a function handle in a call to addlistener or the event.listener constructor:

hlistener = addlistener(eventSourceObj,'MyEvent',@(src,evnt)listenMyEvent(obj,src,evnt))

Then define the method in a method block as usual:

methods
   function listenMyEvent(obj,src,evnt)
      % obj - instance of this class
      % src - object generating event
      % evnt - the event data
      ...
   end
end

For general information on anonymous functions, see Anonymous Functions.

For information on variables used in anonymous functions, see Variables in the Expression.

Callback Execution

Listeners execute their callback function when notified that the event has occurred. Listeners are passive observers in the sense that errors in the execution of a listener callback does not prevent the execution of other listeners responding to the same event, or execution of the function that triggered the event.

Callback function execution continues until the function completes. If an error occurs in a callback function, execution stops and control returns to the calling function. Then any remaining listener callback functions execute.

Listener Order of Execution

The order in which listeners callback functions execute after the firing of an event is undefined. However, all listener callbacks execute synchronously with the event firing.

The handle class notify method calls all listeners before returning execution to the function that called notify.

Callbacks That Call notify

Do not modify and reuse or copy and reuse the event data object that you pass to notify, which is then passed to the listener callback.

Listener callbacks can call notify to trigger events, including the same event that invoked the callback. When a function calls notify, MATLAB sets the property values of the event data object that is passed to callback functions. To ensure these properties have appropriate values for subsequently called callbacks, you should always create a new event data object if you call notify with custom event data.

Managing Callback Errors

If you want to control how your program responds to errors, use a try/catch statement in your listener callback function to handle errors.

See Respond to an Exception and the MException class.

Was this topic helpful?