I have a GUI with a UITable (built in GUIDE). I read in two numerical values and through a series of steps convert the floating-point value to a string. I want the user to have the ability to click on a specific cell in the UITable containing the two values (now as strings), and read those values back as floating-point values. For whatever reason, I can only ever get my code to read in the first floating-point value. My code (in order) is below.
Step 1: Access data and convert to string and place string in corresponding column.
function fillAnnotRangeInfo(obj, selectedAxes)
selectedAxesTag = selectedAxes.Tag;
rawAxesTag = obj.rawDataDisplayAxes.Tag;
psdAxesTag = obj.psdDataDisplayAxes.Tag;
% Depending on which axes the user clicks on, the units will either be Hz or s
if strcmp(selectedAxesTag, rawAxesTag)
dataRange = strcat(num2str(obj.t1), {'s'}, {' - '}, num2str(obj.t2), {'s'});
elseif strcmp(selectedAxesTag, psdAxesTag)
dataRange = strcat(num2str(obj.t1), {'Hz'}, {' - '}, num2str(obj.t2), {'Hz'});
end
obj.nextRow.AnnotRange = dataRange;
end
Step 2: Determine if user clicked in correct cell and attempt to read two floating-point values out.
% --- Executes when selected cell(s) is changed in existingAnnotationsTable.
function existingAnnotationsTable_CellSelectionCallback(hObject, eventdata, handles)
% hObject handle to existingAnnotationsTable (see GCBO)
% eventdata structure with the following fields (see MATLAB.UI.CONTROL.TABLE)
% Indices: row and column indices of the cell(s) currently selecteds
% handles structure with handles and user data (see GUIDATA)
% AE = handles.UserData;
Indices = eventdata.Indices;
% Determine if column is column of interest
if Indices(2) == 4
rangeData = handles.existingAnnotationsTable.Data;
rangeData = rangeData{Indices(1), Indices(2)};
annoRange = sscanf(rangeData, '%f')
else
end
return
Ultimately, the result I get is if I have a string exactly as follows: "7.4250Hz - 32.502Hz" (or replace Hz with "s"), my program will only produce "7.4250". Nothing more nothing less. I've tried textscan, sscanf, and strread. Each one I explicitly set my filter to floating-point (%f). With strread I tried setting it to cycle through more than once (strread('string', %f, 2)
). I have no idea what else to do or try or change.
REGARDING THE ANSWERS BELOW FOR FUTURE READERS: Technically any one of the answers is "correct" (I tried them). They all are applicable to a slightly different situation. Ben's answer is good for getting a result in a single step if you have a fixed format. My own answer works to break down a string across multiple steps giving access to the data each step (useful for performing multiple operations) whilst still being able to deal with varying formats. Andras' answer is useful for getting it done in one step providing a result instantly whilst still being able to deal with varying formats.
Ben's answer is the correct answer in the case of a fixed format. However, in my case, my format changes. Therefore my proposed solution (tested and verified) is to use strtok
to "break-down" the string into two separate strings, making it much more manageable and easier to parse. Code below. Thoughts?
% --- Executes when selected cell(s) is changed in existingAnnotationsTable.
function existingAnnotationsTable_CellSelectionCallback(hObject, eventdata, handles)
% hObject handle to existingAnnotationsTable (see GCBO)
% eventdata structure with the following fields (see MATLAB.UI.CONTROL.TABLE)
% Indices: row and column indices of the cell(s) currently selecteds
% handles structure with handles and user data (see GUIDATA)
% AE = handles.UserData;
Indices = eventdata.Indices;
% Determine if column is column of interest
if Indices(2) == 4
rangeData = handles.existingAnnotationsTable.Data;
rangeData = rangeData{Indices(1), Indices(2)};
[dataStart, dataRemain] = strtok(rangeData);
% In this case, since there will be just a '-' as the token...
% ...we don't care about the token and only save the remainder.
[~, dataEnd] = strtok(dataRemain);
dataStart = sscanf(dataStart, '%f')
dataEnd = sscanf(dataEnd, '%f')
else
end