MATLAB: Scroll function inside an app does not work scroll(app.ListBox, ‘bottom’), but it works when called on the app object from the command line. Why

appMATLABscroll

I have a simple app, where user can input words in an EditField or in a DropDown.
The entered words are then displayed in a ListBox.
Problem 1:
scroll(app.ListBox, 'bottom')
does not work when called from "DropDownValueChanged" function.
However, if I create the app as an object, and call the scroll function from the command line:
h = histroryscroll
scroll(h.ListBox, 'bottom')
then it works as expected. Is this a bug or am I missing something?
Problem 2:
I want to be able to enter the same words several times in a row, i.e. anytime I press Enter from within DropDown componenet. However, the ValueChanged function DropDownValueChanged gets triggered only when the value is actually changed, so i cannot enter the same word twice in a row. Any idea for a solution?
The test code (histroryscroll.m)
%
classdef historyscroll < matlab.apps.AppBase
% usage:
% h = histrorycall
% scroll(h.ListBox, 'bottom')
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
EditFieldLabel matlab.ui.control.Label
EditField matlab.ui.control.EditField
ListBoxLabel matlab.ui.control.Label
ListBox matlab.ui.control.ListBox
DropDownLabel matlab.ui.control.Label
DropDown matlab.ui.control.DropDown
Label matlab.ui.control.Label
end
methods (Access = private)
% Value changed function: EditField
function EditFieldValueChanged(app, event)
value = app.EditField.Value;
app.EditField.Value = '';
app.ListBox.Items(end+1) = {value};
scroll(app.ListBox, 'bottom'); % This does not work

end
% Value changed function: DropDown
function DropDownValueChanged(app, event)
value = app.DropDown.Value;
app.DropDown.Items(end+1) = {value};
app.DropDown.Value = '';
app.ListBox.Items(end+1) = {value};
scroll(app.ListBox, 'bottom'); % This does not work
end
end
% App initialization and construction
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create UIFigure
app.UIFigure = uifigure;
app.UIFigure.Position = [100 100 249 294];
app.UIFigure.Name = 'UI Figure';
% Create EditFieldLabel
app.EditFieldLabel = uilabel(app.UIFigure);
app.EditFieldLabel.HorizontalAlignment = 'right';
app.EditFieldLabel.Position = [9 176 56 22];
app.EditFieldLabel.Text = 'Edit Field';
% Create EditField
app.EditField = uieditfield(app.UIFigure, 'text');
app.EditField.ValueChangedFcn = createCallbackFcn(app, @EditFieldValueChanged, true);
app.EditField.Position = [80 176 151 22];
app.EditField.Value = 'Enter Cmds here ...';
% Create DropDownLabel
app.DropDownLabel = uilabel(app.UIFigure);
app.DropDownLabel.HorizontalAlignment = 'right';
app.DropDownLabel.Position = [8 144 66 22];
app.DropDownLabel.Text = 'Drop Down';
% Create DropDown
app.DropDown = uidropdown(app.UIFigure);
app.DropDown.Items = {'... or here ...'};
app.DropDown.Editable = 'on';
app.DropDown.ValueChangedFcn = createCallbackFcn(app, @DropDownValueChanged, true);
app.DropDown.BackgroundColor = [1 1 1];
app.DropDown.Position = [89 144 142 22];
app.DropDown.Value = {'... or here ...'};
% Create ListBoxLabel
app.ListBoxLabel = uilabel(app.UIFigure);
app.ListBoxLabel.HorizontalAlignment = 'right';
app.ListBoxLabel.Position = [19 259 48 22];
app.ListBoxLabel.Text = 'List Box';
% Create ListBox
app.ListBox = uilistbox(app.UIFigure);
app.ListBox.Items = {'Commands History', ''};
app.ListBox.Position = [82 209 149 74];
app.ListBox.Value = 'Commands History';
% Create Label
app.Label = uilabel(app.UIFigure);
app.Label.VerticalAlignment = 'top';
app.Label.Position = [19 1 212 110];
app.Label.Text = {'Problem1: List Box does not '; ' scroll to the bottom i.e.'; 'scroll(app.ListBox'; '''bottom'') does not work'; ''; 'Problem2: I cannot enter the same '; 'command twice'; ''; ''};
end
end
methods (Access = public)
% Construct app
function app = historyscroll
% Create and configure components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.UIFigure)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFigure)
end
end
end

Best Answer

I had the same problem when trying to write a GUI with App Designer that included a scrolling status window that would scroll up when a new message was displayed. After reading other posts I implemented this as a listbox, however I found that scrolling didn't work if I called:
scroll(app.ListBox, 'bottom');
within the function that added the message to the list. However, it would work if I called the same function from another callback or from the command line, neither of which solved my problem. The solution turned out to be to call pause with a short delay between updating the list box entries and calling scroll, e.g.:
{Code to update list box entries}
pause(0.01);
scroll(app.ListBox, 'bottom');
Presumably the call to pause() gives Matlab a chance to do something important in the background - the same strategy has got me out of trouble with other graphics issues in the past.
I hope this helps someone,
Alec