Optimized tabs in MATLAB GUI

tashuhka picture tashuhka · Feb 4, 2013 · Viewed 7.6k times · Source

I am working in a GUI in MATLAB and I use tabs to organize the information. As the tabs are not supported in MATLAB GUIDE, I just create several uipanels and change their 'Visible' field. However, when the number of controls within each panel is large, it takes some time to switch between panels. Does anybody know a way to make tab switching faster?

I include a simple example of the tab-based interface.

tab_example_gui.m

% Figure
handles.figure_window = figure(...
    'Units','characters',...
    'Tag','figure_window',...
    'Position',[50 50 80 25],...
    'Name','Tab Example',...
    'DockControls','off',...
    'IntegerHandle','off',...
    'MenuBar','none',...
    'NumberTitle','off',...
    'Resize','off');

% Buttons
handles.tab_panel = uibuttongroup(...
    'Parent',handles.figure_window,...
    'Tag','tab_panel',...
    'Units','characters',...
    'Position',[0 23 80 2],...
    'SelectionChangeFcn',@(hObject,eventdata)tab_example_callback(hObject,eventdata,guidata(hObject)),...
    'BorderType','none');
handles.tab_a = uicontrol(...
    'Parent',handles.tab_panel,...
    'Tag','tab_a',...
    'Units','characters',...
    'Position',[0 0 40 2],...
    'Style','togglebutton',...
    'String','Tab A');
handles.tab_b = uicontrol(...
    'Parent',handles.tab_panel,...
    'Tag','tab_b',...
    'Units','characters',...
    'Position',[40 0 40 2],...
    'Style','togglebutton',...
    'String','Tab B');


% Panel A
handles.panel_a = uipanel(...
    'Parent',handles.figure_window,...
    'Tag','panel_menu',...
    'Units','characters',...
    'Position',[0.1 0 79.8 23],...
    'Visible','On');
handles.panel_a_text = uicontrol(...
    'Parent',handles.panel_a,...
    'Tag','panel_menu_load_id_text',...
    'Units','characters',...
    'Position',[0 0 77 22],...
    'Style','text',...
    'String','This is the tab A');

% Panel B
handles.panel_b = uipanel(...
    'Parent',handles.figure_window,...
    'Tag','panel_menu',...
    'Units','characters',...
    'Position',[0.1 0 79.8 23],...
    'Visible','Off');
handles.panel_b_text = uicontrol(...
    'Parent',handles.panel_b,...
    'Tag','panel_menu_load_id_text',...
    'Units','characters',...
    'Position',[0 0 77 22],...
    'Style','text',...
    'String','This is the tab B');

guidata(handles.figure_window, handles);

tab_example_callback.m

function tab_example_callback(hObject,eventdata,handles)
    switch get(get(hObject,'SelectedObject'),'Tag')
        case 'tab_a', set(handles.panel_a,'Visible','On'); set(handles.panel_b,'Visible','Off');
        case 'tab_b', set(handles.panel_a,'Visible','Off'); set(handles.panel_b,'Visible','On');
    end
    guidata(handles.figure_window, handles);
end

Note: The GUI is to introduce parameters for a simulation in 5 tabs. In each tab, I have around 15 rows; and each row has one text, one checkbox and three edits. It does not look overcrowded for me. Besides, I have made the layout and callbacks on my own with the minimum amount of code and overhead. But, it still has very annoying tab transitions.

Answer

julietKiloRomeo picture julietKiloRomeo · Mar 15, 2013

Maybe if you put the handles in an array. That way you do not have to go through each one of them. This seems fast to me, but 'fast' can mean a lot of things :)

I removed some of the properties to make the example shorter...

function test(N) % N is the number of tabs
if nargin == 0
    N = 3;
end

% Figure
handles.figure_window = figure(...
    'Units','characters',...
    'Position',[50 50 80 25]);
% Buttons
handles.tab_panel = uibuttongroup(...
    'Parent',handles.figure_window,...
    'Units','characters',...
    'Position',[0 23 80 2]);

alpha = 'ABCDEFGHIJKLMNOPQRSTUVXYZ';
for i_tab=1:N
    % button
    handles.tabs(i_tab) = uicontrol(...
        'Parent',handles.tab_panel,...
        'Units','characters',...
        'Position',[80/N*(i_tab-1) 0 80/N 2],...
        'Style','togglebutton',...
        'String',['Tab ' alpha(i_tab)]);

    % Panel i
    handles.panels(i_tab) = uipanel(...
        'Parent',handles.figure_window,...
        'Units','characters',...
        'Position',[0.1 0 79.8 23],...
        'Visible','Off');
    handles.panel_a_text = uicontrol(...
        'Parent',handles.panels(i_tab),...
        'Units','characters',...
        'Position',[0 0 77 22],...
        'Style','text',...
        'String',['This is the tab ', alpha(i_tab)]);
end
% set callback for all buttons
set(handles.tabs, 'callback', {@tab_example_callback  handles})
% choose tab 1 as active
set(handles.panels(1), 'Visible','On');
guidata(handles.figure_window, handles);

function tab_example_callback(hObject,eventdata,handles)
% set everything invisible
set(handles.panels,'Visible','Off');
% turn on selected panel
set(handles.panels(handles.tabs == hObject), 'Visible','On');
guidata(handles.figure_window, handles);

Does that help you out?