I'm trying to create a listbox where I can dynamically add or remove items.
The setup looks like this:
Unfortunately - as one can see from the picture - when I delete elements the total length of the list stays the same and instead of shrinking the list the displayed list now contains holes.
Does anyone know how to avoid this kind of behavior?
This is my code for the delete button so far:
function btnDeleteLabel_Callback(hObject, eventdata, handles)
selectedId = get(handles.listbox_labels, 'Value'); % get id of selectedLabelName
existingItems = get(handles.listbox_labels, 'String'); % get current listbox list
existingItems{selectedId} = []; % delete the id
set(handles.listbox_labels, 'String', existingItems); % restore cropped version of label list
The simplest way to remove the "empty" entries is update the listbox
string with the remaining items.
There are three possibilities:
upd_list={existingItems{2:end}}
upd_list={existingItems{1:end-1}}
upd_list={existingItems{1:selectedId-1} existingItems{selectedId+1:end}}
You can also check if all the element of the list have been deleted and, in this case, disable the "Delete" pushbutton
; in this case, you have to enable it in the "Add" callback
.
A possible implementation of your btnDeleteLabel_Callback
could be:
% --- Executes on button press in btnDeleteLabel.
function btnDeleteLabel_Callback(hObject, eventdata, handles)
% hObject handle to btnDeleteLabel (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
selectedId = get(handles.listbox_labels, 'Value') % get id of selectedLabelName
existingItems = get(handles.listbox_labels, 'String') % get current listbox list
%
% It is not necessary
%
% existingItems{selectedId} = [] % delete the id
% Identify the items: if in the list only one item has been added the
% returned list is a char array
if(class(existingItems) == 'char')
upd_list=''
set(handles.listbox_labels, 'String', upd_list)
else
% If the returned list is a cell array there are three cases
n_items=length(existingItems)
if(selectedId == 1)
% The first element has been selected
upd_list={existingItems{2:end}}
elseif(selectedId == n_items)
% The last element has been selected
upd_list={existingItems{1:end-1}}
% Set the "Value" property to the previous element
set(handles.listbox_labels, 'Value', selectedId-1)
else
% And element in the list has been selected
upd_list={existingItems{1:selectedId-1} existingItems{selectedId+1:end}}
end
end
% Update the list
set(handles.listbox_labels, 'String', upd_list) % restore cropped version of label list
% Disable the delete pushbutton if there are no more items
existingItems = get(handles.listbox_labels, 'String')
if(isempty(existingItems))
handles.btnDeleteLabel.Enable='off'
end