MATLAB: Notification when data in a uitable changes

guidelisteneruitable

I am creating a GUI that contains a uitable whose contents I will be saving to a file. There are multiple ways to change the data in the table (buttons to add/remove rows, entering text into the text fields, making a selection from the choice lists, etc.). Rather than putting callbacks on all of these different controls, is there a single callback that gets called when the data in the uitable gets changed? I want to provide a visual indicator to the user that the data has changed and they need to save their work.

Best Answer

Stuart - I think that you can minimize the coding to achieve what you want if you use a listener against a certain property of the uitable. For example, your push buttons to add or remove a row (or column?) from your table probably do something like
% add a new row to table
function pushbutton1_Callback(hObject, eventdata, handles)
data = get(handles.uitable1,'Data');
data = [data ; cell(1,size(data,2))];
set(handles.uitable1,'Data',data);
% remove the last row
function pushbutton2_Callback(hObject, eventdata, handles)
data = get(handles.uitable1,'Data');
if ~isempty(data)
data(end,:) = [];
end
set(handles.uitable1,'Data',data);
In both cases, we update the Data property of the table. So if we listen to a change in this property then we can notify the user that he or she must save their changes.
If using GUIDE, in the _OpeningFcn of your GUI, we need to create the listener as
function UITableListenerExample_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
handles.saveBtnDefaultBColour = get(handles.pushbutton3,'BackgroundColor');
handles.hUitableListener = ...
addlistener(handles.uitable1,'Data','PostSet', ...
@(src,event)uitableDataChangeCallback(handles.uitable1,src,event));
% Update handles structure
guidata(hObject, handles);
The saveBtnDefaultBColour is just to save the default background colour of the button (see how used later) and the listener will listen for Data "change" events for uitable1. When such an event occurs, the uitableDataChangeCallback will fire. By default (?) there are the source src and event input parameters. We add a third one which is just the handle to the uitable. This callback does the following
function uitableDataChangeCallback(hObject,~,~)
handles = guidata(hObject);
set(handles.pushbutton3,'BackgroundColor','g');
Given the handle to the uitable, we use guidata to get the handles to all controls and user-defined data of the GUI. In this case, we are interested in the "save" button whose background we change to green to indicate to the user that their changes need to be saved.
The above only seems to work (on R2014a) when a change is made to Data explicitly. This same callback is not called when the user modifies a cell in the table. If you want the uitableDataChangeCallback to be called when a cell is modified, you would need to call this callback from the table's cell edit callback as
function uitable1_CellEditCallback(hObject, eventdata, handles)
uitableDataChangeCallback(hObject,[],[]);
See the attached for a working example. Perhaps some of it will be of use to you.