Hello,
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
properties
layout matlab.ui.container.GridLayout
field1 matlab.ui.control.EditField
field2 matlab.ui.control.EditField
end
methods
function obj = HandleExample(parentLayout)
obj.layout = uigridlayout(parentLayout);
obj.layout.ColumnWidth = {'1x', '1x'};
obj.layout.RowHeight = {'1x'};
obj.field1 = uieditfield(obj.layout);
obj.field1.Layout.Row = 1;
obj.field1.Layout.Column = 1;
obj.field1.ValueChangedFcn = @obj.field1ChangeHandler;
obj.field2 = uieditfield(obj.layout);
obj.field2.Layout.Row = 1;
obj.field2.Layout.Column = 2;
end
function field1ChangeHandler(obj, thrower, event)
disp(obj)
disp(thrower)
disp(event)
obj.field2.Text = 'This won''t work :(';
end
end
end
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!