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?

1 view (last 30 days)
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

Accepted Answer

Alec Duncan
Alec Duncan on 12 Feb 2020
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
  3 Comments
Michael
Michael on 11 Oct 2023
I'm using 2023b and this hack is still apparently needed to get scroll() working inside AppDesigner - could you sort this bug out please Mathworks?

Sign in to comment.

More Answers (0)

Categories

Find more on Develop uifigure-Based Apps in Help Center and File Exchange

Tags

Products


Release

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!