MATLAB: GUI flickers when customly resized

flickerguiresize

When I select the checkbox "Show stats" the GUI is resized w/o any flicker, whereas selecting "Show buttons" causes the GUI to flicker due to the custom resize. How can I eliminate the flicker?
Run the following example GUI (any other best-practice advises are really welcome):
function example
% Figure Window
S.fh = figure('Units','pixels','Pos',[600 500 370 225],...
'Menubar','none','Resize','off');
% Uipanel for buttons
S.upB = uipanel('Title','Show buttons','Units','pixels','Pos',[10 90 351 65]);
% Buttons check box
S.cbB = setdiff(findall(S.upB),S.upB);
set(S.cbB,'Style','checkbox','Parent',S.fh,'Visible','on',...
'Value',1,'Pos',[20 148 90 15],'Callback',{@cb_call,S.upB});
% Uipanel for stats
S.upS = uipanel('Title','Show stats','Units','pixels','Pos',[10 10 351 65]);
% Stats check box
S.cbS = setdiff(findall(S.upS),S.upS);
set(S.cbS,'Style','checkbox','Parent',S.fh,'Visible','on',...
'Value',1,'Pos',[20 68 90 15],'Callback',{@cb_call,S.upS});
% textbox
S.txDisp = uicontrol('Style','text','Pos',[10 170 200 55]);
S.txComp = uicontrol('Style','text','Pos',[225 178 115 33]);
% cb_call -----------------------------------------------------------------
function cb_call(varargin)
if get(varargin{1},'Value')
resizeFig(get(varargin{3},'Pos') - 5,...
unique([varargin{1},S.cbB]),S.upB,S.txComp,S.txDisp,S.fh)
set(varargin{3},'Visible','on');
else
set(varargin{3},'Visible','off');
resizeFig(-get(varargin{3},'Pos') + 5,...
unique([varargin{1},S.cbB]),S.upB,S.txComp,S.txDisp,S.fh)
end
setFocusFig(varargin{1})
end
% resizeFig ---------------------------------------------------------------
function resizeFig(height,varargin)
set(varargin{end},'Pos', get(varargin{end},'Pos') + [0 -height(end) 0 height(end)])
for h = [varargin{1:end-1}]
set(h,'Pos', get(h,'Pos') + [0 height(end) 0 0])
end
end
% setFocusFig -------------------------------------------------------------
function setFocusFig(hObject)
% Workaround to set focus to figure
set(hObject, 'Enable', 'off');
drawnow;
set(hObject, 'Enable', 'on');
end
end

Best Answer

  • I think your approach looks like what I have done in the past. I tried to do a couple of things which I think might make a slight difference in speed, but perhaps not. (Some things I changed just to help me understand the code.)
    One thing I did notice was this setFocusFig function. When I comment out the call to that, the GUI does seem to resize smoother. I wonder what the purpose of this function is? The only thing that I can see it doing is making the callback object lose focus after the resize. Anyway, I doubt this will help, but give it a try. It is difficult for me to do much without seeing the flickering that you are.
    function S = example3()
    % Figure Window
    S.fh = figure('Units','pixels','Pos',[600 500 370 225],...
    'Menubar','none','Resize','off');
    % Uipanel for buttons
    S.upB = uipanel('Title','Show buttons','Units','pixels','Pos',[10 90 351 65]);
    % Buttons check box
    S.cbB = findall(S.upB,'style','text');
    set(S.cbB,'Style','checkbox','Parent',S.fh,'Visible','on','userd',S.upB,...
    'Value',1,'Pos',[20 148 90 15],'Callback',{@cb_call});
    % Uipanel for stats
    S.upS = uipanel('Title','Show stats','Units','pixels','Pos',[10 10 351 65]);
    % Stats check box
    S.cbS = findall(S.upS,'style','text');
    set(S.cbS,'Style','checkbox','Parent',S.fh,'Visible','on','userd',S.upS,...
    'Value',1,'Pos',[20 68 90 15],'Callback',{@cb_call});
    % textbox
    S.txDisp = uicontrol('Style','text','Pos',[10 170 200 55]);
    S.txComp = uicontrol('Style','text','Pos',[225 178 115 33]);
    % cb_call -----------------------------------------------------------------
    function cb_call(varargin)
    H = varargin{1};
    P = get(H,'userd'); % The uipanel it is connected to.
    if get(H,'Value')
    resizeFig(get(P,'Pos') - 5,H,S.cbB,S.upB,S.txComp,S.txDisp)
    set(P,'Visible','on');
    else
    resizeFig(5 - get(P,'Pos'),H,S.cbB,S.upB,S.txComp,S.txDisp)
    set(P,'Visible','off');
    end
    % setFocusFig(H) % What is this for??
    end
    % resizeFig ---------------------------------------------------------------
    function resizeFig(varargin)
    H = varargin{1}(4);
    set(S.fh,'Pos', get(S.fh,'Pos') + [0 -H 0 H])
    for h = unique([varargin{2:end}])
    set(h,'Pos', get(h,'Pos') + [0 H 0 0])
    end
    end
    % setFocusFig -------------------------------------------------------------
    function setFocusFig(hObject)
    % Workaround to set focus to figure
    set(hObject, 'Enable', 'off');
    drawnow;
    set(hObject, 'Enable', 'on');
    end
    end