Why is my HandleCompatible class out-of-date when accessed in callback?

1 view (last 30 days)
I'm trying to write a MATLAB (2019b) class to encompass a group of UI components. Despite setting my class to "HandleCompatible", which I thought meant it would effectively be passed by reference rather than by value, I find that when using an class method as a callback to a UI event, my instance is out of date, as though it had been cached or copied at the time the callback was registered. Help!
I created a minimal working example to explain what I mean. Here's the class - it consists of a gridlayout and two edit fields. The first edit field has a callback that updates the second edit field when the first edit field value is changed.
classdef (HandleCompatible) HandleExample
layout matlab.ui.container.GridLayout
field1 matlab.ui.control.EditField
field2 matlab.ui.control.EditField
methods %(Access = public)
function obj = HandleExample(parentLayout)
% Create GridLayout
obj.layout = uigridlayout(parentLayout);
obj.layout.ColumnWidth = {'1x', '1x'};
obj.layout.RowHeight = {'1x'};
% Create field 1
obj.field1 = uieditfield(obj.layout);
obj.field1.Layout.Row = 1;
obj.field1.Layout.Column = 1;
obj.field1.ValueChangedFcn = @obj.field1ChangeHandler;
% Create field 2
obj.field2 = uieditfield(obj.layout);
obj.field2.Layout.Row = 1;
obj.field2.Layout.Column = 2;
function field1ChangeHandler(obj, thrower, event)
obj.field2.Text = 'This won''t work :(';
Here's how I instantiate the class and here's the error:
>> x = HandleExample(uifigure)
x =
HandleExample with properties:
layout: [1×1 GridLayout]
field1: [1×1 EditField]
field2: [1×1 EditField]
After I change the text in edit field 1, I get this output/error:
HandleExample with properties:
layout: [1×1 GridLayout]
field1: [1×1 EditField]
field2: [0×0 EditField]
EditField (hi) with properties:
Value: 'hi'
ValueChangedFcn: @(varargin)obj.field1ChangeHandler(varargin{:})
ValueChangingFcn: ''
Position: [11 11 265 400]
Show all properties
ValueChangedData with properties:
Value: 'hi'
PreviousValue: ''
Source: [1×1 EditField]
EventName: 'ValueChanged'
Property assignment is not allowed when the object is empty. Use subscripted assignment to
create an array element.
Error in HandleExample/field1ChangeHandler (line 29)
obj.field2.Text = 'This won''t work :(';
Error in HandleExample>@(varargin)obj.field1ChangeHandler(varargin{:}) (line 18)
obj.field1.ValueChangedFcn = @obj.field1ChangeHandler;
Error using matlab.ui.control.internal.controller.ComponentController/executeUserCallback (line 378)
Error while evaluating EditField PrivateValueChangedFcn.
Notice that inside the callback. obj.field2 is 0x0, as though my class instance was frozen by value at the line where I register the callback! I thought this is exactly what the "HandleCompatible" keyword was supposed to avoid, but I must be misunderstanding something. This is my first MATLAB classdef.
Thank you in advance for the help!

Answers (1)

Brian Kardon
Brian Kardon on 28 Apr 2020
Wow, ok, I searched a lot for the answer to this question, and minutes after I finally asked, I seem to have found the answer:
Apparently setting the class to "HandleCompatible" is not enough. In fact, I'm not sure it's even necessary. What I was missing is making my class a subclass of "handle". So, while this doesn't work,
classdef (HandleCompatible) HandleExample
this does:
classdef (HandleCompatible) HandleExample < handle
(also, incidentally, the correct property name for the text of an uieditfield is "Value", not "Text".
  1 Comment
per isakson
per isakson on 8 May 2020
"In fact, I'm not sure it's even necessary." No it is neither necessary nor meaningful. (Why doesn't the Code Analyzer show a warning? (R2018b)) HandleCompatible doesn't add anything to a class that subclasses the handle class.
The documentation, Handle Compatible Classes , says:
Handle-compatible class — a class that you can include with handle classes in a class hierarchy, even if the class is not a handle class.

Sign in to comment.


Find more on Migrate GUIDE Apps in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!