How to carry out a function when a cell is deselected on UItable.

1 view (last 30 days)
I have a uitable with a cellSelectionCallback that works when the cell is selected (the function plots a graph with multiple data sets depending on which cell is selected). However, I want to immediately negate the effects if the cell is deselected (i.e. delete the plot that was created by clicking the cell). Is there something like cellDeselectionCallback?

Accepted Answer

Geoff Hayes
Geoff Hayes on 6 Jun 2017
Kyle - rather than using cellSelectionCallback (which only seems to fire when you select a new cell within the uitable), you could try to use the CellEditCallback instead. Since selecting and deselecting a checkbox within a uitable (which I'm assuming that you are doing based on a previous post) changes the state of the checkbox from checked (true) to unchecked (false) then this is equivalent to editing the cell.
On R2014a, I was able to create the table (using your past post as a guide) as
t = uitable('Units','normalized','Position',...
[0.1 0.1 0.9 0.9], 'Data', tableData,...
'ColumnName', columnNames, ...
'ColumnEditable', true,...
'CellEditCallback', @onCellSelected);
The callback would then be something like
function onCellSelected(hObject, data)
fprintf('selecting cell (%d,%d)\n', data.Indices(1), data.Indices(2));
col = data.Indices(2);
if col == 2 % if the column of checkboxes is selected
row = data.Indices(1); % get the row
myData = get(t,'Data'); % get the uitable data
isChecked = myData{row, col}; % is the checkbox checked (true) or not (false)
if isChecked
% plot the function
else
% delete the drawn function
end
end
You can delete the drawn function if you keep a handle to its graphics object. To do this, create a local variable within your parent function (and so is visible to the nested callback function) that is an array of handles for each of the three graphics objects (assuming that you are drawing one for sin, cos, and tan).
function createMyTable
f = ...;
t = ...;
plotHandles = zeros(3,1);
function onCellSelected(hObject, data)
...
end
end
Then, in the callback, we would save the plot graphics object handle as
if isChecked
plotHandles(row) = plot(...);
elseif ishandle(plotHandles(row))
delete(plotHandles(row));
plotHandles(row) = 0;
end
We use ishandle to verify that the object we are going to delete is a valid handle (to a graphics object).
  1 Comment
Kyle Reagan
Kyle Reagan on 6 Jun 2017
Thanks, Geoff. This does exactly what I needed it to do. For anyone who may come across this, my working code is as follows.
function createMyTable2
f = figure('Position',[100 100 900 500],'Visible','on');
ax = axes('Drawmode','Fast','Units','pixels');
hold on
grid;
tableData = {'Sin(x)', false; 'Cos(x)', false; 'y = x', false};
columnNames = {'Function', 'Show'};
t = uitable('Units','normalized','Position',...
[0.8 0.8 0.2 0.2], 'Data', tableData,...
'ColumnName', columnNames, ...
'ColumnEditable', true,...
'CellEditCallback', @onCellSelected2);
plotHandles = zeros(3,1);
function onCellSelected2(hObject, data)
fprintf('selecting cell (%d,%d)\n', data.Indices(1), data.Indices(2));
col = data.Indices(2);
if col == 2 % if the column of checkboxes is selected
row = data.Indices(1); % get the row
myData = get(t,'Data'); % get the uitable data
isChecked = myData{row, col}; % is the checkbox checked (true) or not (false)
if isChecked
if row == 1
x = 0:pi/6:2*pi;
y = sin(x);
hold on
plotHandles(row) = plot(x,y,'--','color','b'); % plot the function
elseif row == 2
u = 0:pi/6:2*pi;
p = cos(u);
plotHandles(row) = plot(u,p,'--','color','m'); % plot the function
elseif row == 3
j = 0:1:6;
k = j;
hold on
plotHandles(row) = plot(j,k,'--','color','k'); % plot the function
end
elseif ishandle(plotHandles(row))
delete(plotHandles(row));
plotHandles(row) = 0; % delete the drawn function
end
end
end
end

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 6 Jun 2017
Sorry, No.
However, for each selection callback you could start by removing the previous plot. You could combine that with figure WindowButtonDown callbacks in all of your figures to detect that you had clicked one of them, at which point you would remove the plot as well (that is, to deselect something you need to click somewhere else, so you detect the click elsewhere.) You would, though, need to avoid tools such as msgbox() or menu() or inputdlg(), each of which generates a figure outside your control that you could not drop a callback into (for the situation where you want to consider clicking OK on a msgbox or entering input in a menu, etc., to constitute deselection of the uitable cell.)

Categories

Find more on Programming 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!