Slow SizeChangedFcn or ResizeFcn

48 views (last 30 days)
Jan
Jan on 26 Jul 2020
Commented: Clinten Graham on 26 Jun 2023
When a SizeChangedFcn or ResizeFcn takes some time, the figure size can be changed, until the display is updated. Example:
function ResizeTest
FigH = figure('Units', 'Pixels');
siz = get(FigH, 'Position');
AxesH = axes('Units', 'Pixels', 'Position', [5, 5, siz(3:4)-10], 'Box', 'on');
set(FigH, 'ResizeFcn', {@resize, AxesH}); % Same for SizeChangedFcn
end
function resize(FigH, EventData, AxesH)
siz = get(FigH, 'Position');
pause(1.0); % Of course here are some real calculations
set(AxesH, 'Position', [5, 5, siz(3:4)-10]);
end
The real calculations are e.g. a re-wrapping of a large text displayed in the axes object.
During the mouse is moved to change the figure, the display is smartly changed, but when the axes object is adjusted, its size is likely out of date.
What is a good strategy to solve this problem? It would be best to trigger the callback, when the mouse button is released. But in Matlab 6.5 to 2018b (most likely newer versions also) the motion of the mouse calls the callback already. Setting the figure property Interruptible to 'on' and the BusyAction to 'queue' does not solve the problem - this is the default already.
  1 Comment
Clinten Graham
Clinten Graham on 26 Jun 2023
This helped solve my problem. Thank you for sharing!

Sign in to comment.

Accepted Answer

Jan
Jan on 4 Aug 2020
The first version was not sufficient in all cases. In addition it is required to prevent a repeated entering of the code:
function resize(FigH, EventData, AxesH)
persistent blockCalls % Reject calling this function again until it is finished
if any(blockCalls), return, end
blockCalls = true;
doResize = true;
while doResize % Repeat until the figure does not change its size anymore
siz = get(FigH, 'Position');
pause(1.0); % Of course here are some real calculations
set(AxesH, 'Position', [5, 5, siz(3:4)-10]);
drawnow;
doResize = ~isequal(siz, get(FigH, 'Position'));
end
blockCalls = false; % Allow further calls again
end
I'm surprised that nobody else seems to have this problem.
  2 Comments
Jiri Hajek
Jiri Hajek on 10 Jun 2021
Hi Jan,
I do have a related problem with a SizeChangedFcn, for which I have no solution so far. I need to make an adjustment to the position of certain objects in app gui after all auto resizing is done. While debugging, the adjustments work fine, but when I run the app without interruption, the adjustments are done before all automatic resizing is finished, which effectively makes them useless... Would you care you share your ideas about solving such a situation?
Jan
Jan on 10 Jun 2021
I do not use the AppDesigner yet, because I have to write stable software with minimal dependencies on the Matlab version.
Are you sure than an Auto-Reflow and a grid layout cannot solve your needs?
Did you try to use the SizeChangedFcn as given in my example above?

Sign in to comment.

More Answers (1)

Jan
Jan on 29 Jul 2020
Edited: Jan on 29 Jul 2020
One solution is to ignore the built-in resize methods and use a specific WindowsButtonDownFcn to emulate a resizing. But reinventing the wheel is awkward.
Another idea is a checking the actual figure size at the end of the callback and start it again in a recursion or loop - not satisfying also:
function resize(FigH, EventData, AxesH)
doResize = true;
while doResize
siz = get(FigH, 'Position');
pause(1.0); % Of course here are some real calculations
set(AxesH, 'Position', [5, 5, siz(3:4)-10]);
drawnow;
doResize = ~isequal(siz, get(FigH, 'Position'));
end
end
Of course, this is more a workaround than a solution. It would be much nicer to catch the Mouse-Release event after the resizing of the window was triggered.
Perhaps this is a question for Yair and the undocumented Java methods.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!