| Products & Services | Industries | Academia | Support | User Community | Company |
| Download Product Updates | | | Get Pricing | | | Trial Software |
| Documentation → MATLAB |
| Contents | Index |
| Learn more about MATLAB |
This example shows how to implement a GUI that displays names and phone numbers, which it reads from a MAT-file.

The example demonstrates the following GUI programming techniques:
Uses open and save dialog boxes to provide a means for users to locate and open the address book MAT-files and to save revised or new address book MAT-files.
Defines callbacks written for GUI menus.
Uses the GUI's handles structure to save and recall shared data.
Uses a GUI figure resize function.
One of the key techniques illustrated in this example is how to keep track of information and make it available to the various subfunctions. This information includes:
The name of the current MAT-file.
The names and phone numbers stored in the MAT-file.
An index pointer that indicates the current name and phone number, which must be updated as the user pages through the address book.
The figure position and size.
The handles of all GUI components
The descriptions of the subfunctions that follow illustrate how to save and retrieve information from the handles structure. For more information on this structure, see handles Structure and GUI Data.
If you are reading this document in the MATLAB Help browser, you can access the example FIG-file and M-file by clicking the following links. If you are reading this on the Web or in PDF form, go to the corresponding section in the MATLAB Help Browser to use the links.
If you intend to modify the layout or code of this GUI example, first save a copy of its M-file and FIG-file to your current folder (You need write access to your current folder to do this.) Follow these steps to copy the example files to your current folder and then to open them:
Type guide address_book or click here to open the FIG-file in GUIDE.
Type edit address_book or click here to open the M-file in the Editor.
You can view the properties of any component by double-clicking it in the Layout Editor to open the Property Inspector for it. You can modify either the figure, the M-file, or both, and then save the GUI in your current folder using File > Save as from GUIDE. This saves both files, allowing you to rename them, if you choose.
To just inspect the GUI in GUIDE and run it, follow these steps instead:
Click here to add the example files to the MATLAB path (only for the current session).
Click here to display the GUI in the GUIDE Layout Editor (read only).
Click here to display the GUI M-file in the MATLAB Editor (read only).
Note Do not save GUI files to the examples folder where you found them or you will overwrite the original files. If you want to save GUI files, use File > Save as from GUIDE, which saves both the GUI FIG-file and the GUI M-file. |
The GUI is nonblocking and nonmodal because it is designed to be displayed while you perform other MATLAB tasks.
This GUI uses the following GUI option settings:
Resize behavior: User-specified
Command-line accessibility: Off
GUI M-file options selected:
Generate callback function prototypes
Application allows only one instance to run
You can call the GUI M-file with no arguments, in which case the GUI uses the default address book MAT-file, or you can specify an alternate MAT-file from which the GUI reads information. In this example, the user calls the GUI with a pair of arguments, address_book('book', 'my_list.mat'). The first argument, 'book', is a key word that the M-file looks for in the opening function. If the M-file finds the key word, it knows to use the second argument as the MAT-file for the address book. Calling the GUI with this syntax is analogous to calling it with a valid property-value pair, such as ('color', 'red'). However, since 'book' is not a valid figure property, in this example the opening function in the M-file includes code to recognize the pair ('book', 'my_list.mat').
It is not necessary to use the key word 'book'. You can program the M-file to accept just the MAT-file as an argument, using the syntax address_book('my_list.mat'). The advantage of calling the GUI with the pair ('book', 'my_list.mat') is that you can program the GUI to accept other user arguments, as well as valid figure properties, using the property-value pair syntax. The GUI can then identify which property the user wants to specify from the property name.
The following code shows how to program the opening function to look for the key word 'book', and if it finds the key word, to use the MAT-file specified by the second argument as the list of contacts.
function address_book_OpeningFcn(hObject, eventdata,...
handles, varargin)
% Choose default command line output for address_book
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% User added code follows
if nargin < 4
% Load the default address book
Check_And_Load([],handles);
% If the first element in varargin is 'book' and
& the second element is a MATLAB file, then load that file
elseif (length(varargin) == 2 && ...
strcmpi(varargin{1},'book') && ...
(2 == exist(varargin{2},'file')))
Check_And_Load(varargin{2},handles);
else
errordlg('File Not Found','File Load Error')
set(handles.Contact_Name,'String','')
set(handles.Contact_Phone,'String','')
endThere are two ways in which the GUI accesses an address book (text data stored in a MAT-file):
When starting the GUI, you can specify a MAT-file as an argument. For example,
address_book addrbook.mat
If you do not specify an argument, the GUI loads the default address book (addrbook.mat, one of the three example files).
From the File menu, select Open to display a file dialog box and browse for other MAT-files.
To be a valid address book, the MAT-file must contain a structure called Addresses that has two fields called Name and Phone. The Check_And_Load subfunction validates and loads the data with the following steps:
Loads (load) the specified file or the default if none is specified.
Determines if the MAT-file is a valid address book.
Displays the data if it is valid. If it is not valid, displays an error dialog box (errordlg).
Returns 1 for valid MAT-files and 0 if invalid (used by the Open menu callback).
Saves the following items in the handles structure:
The name of the MAT-file.
The Addresses structure.
An index pointer indicating which name and phone number are currently displayed
This is the Check_And_Load function:
function pass = Check_And_Load(file,handles)
% Initialize the variable "pass" to determine if this is
% a valid file.
pass = 0;
% If called without any file then set file to the default
% filename.
% Otherwise, if the file exists then load it.
if isempty(file)
file = 'addrbook.mat';
handles.LastFile = file;
guidata(handles.Address_Book,handles)
end
if exist(file) == 2
data = load(file);
end
% Validate the MAT-file
% The file is valid if the variable is called "Addresses"
% and it has fields called "Name" and "Phone"
flds = fieldnames(data);
if (length(flds) == 1) && (strcmp(flds{1},'Addresses'))
fields = fieldnames(data.Addresses);
if (length(fields) == 2) && ...
(strcmp(fields{1},'Name')) && ...
(strcmp(fields{2},'Phone'))
pass = 1;
end
end
% If the file is valid, display it
if pass
% Add Addresses to the handles structure
handles.Addresses = data.Addresses;
guidata(handles.Address_Book,handles)
% Display the first entry
set(handles.Contact_Name,'String',data.Addresses(1).Name)
set(handles.Contact_Phone,'String',data.Addresses(1).Phone)
% Set the index pointer to 1 and save handles
handles.Index = 1;
guidata(handles.Address_Book,handles)
else
errordlg('Not a valid Address Book','Address Book Error')
endThe address book GUI contains a File menu that has an Open submenu for loading address book MAT-files. When selected, Open displays a dialog box (uigetfile) that enables the user to browse for files. The dialog box displays only MAT-files, but users can change the filter to display all files.
The dialogbox returns both the file name and the path to the file, which is then passed to fullfile to ensure the path is properly constructed for any platform. Check_And_Load validates and load the new address book.
function Open_Callback(hObject, eventdata, handles)
[filename, pathname] = uigetfile( ...
{'*.mat', 'All MAT-Files (*.mat)'; ...
'*.*','All Files (*.*)'}, ...
'Select Address Book');
% If "Cancel" is selected then return
if isequal([filename,pathname],[0,0])
return
% Otherwise construct the fullfilename and Check and load
% the file
else
File = fullfile(pathname,filename);
% if the MAT-file is not valid, do not save the name
if Check_And_Load(File,handles)
handles.LastFIle = File;
guidata(hObject, handles)
end
endFfor information on creating the menu, see Creating Menus.
The Contact Name text box displays the name of the address book entry. If you type in a new name and press enter, the callback performs these steps:
If the name exists in the current address book, the corresponding phone number is displayed.
If the name does not exist, a question dialog box (questdlg) asks you if you want to create a new entry or cancel and return to the name previously displayed.
If you create a new entry, you must save the MAT-file using the File > Save menu.
This callback uses the handles structure to access the contents of the address book and to maintain an index pointer (handles.Index) that enables the callback to determine what name was displayed before it was changed by the user. The index pointer indicates what name is currently displayed. The address book and index pointer fields are added by the Check_And_Load function when the GUI is run.
If the user adds a new entry, the callback adds the new name to the address book and updates the index pointer to reflect the new value displayed. The updated address book and index pointer are again saved (guidata) in the handles structure.
function Contact_Name_Callback(hObject, eventdata, handles)
% Get the strings in the Contact Name and Phone text box
Current_Name = get(handles.Contact_Name,'string');
Current_Phone = get(handles.Contact_Phone,'string');
% If empty then return
if isempty(Current_Name)
return
end
% Get the current list of addresses from the handles structure
Addresses = handles.Addresses;
% Go through the list of contacts
% Determine if the current name matches an existing name
for i = 1:length(Addresses)
if strcmp(Addresses(i).Name,Current_Name)
set(handles.Contact_Name,'string',Addresses(i).Name)
set(handles.Contact_Phone,'string',Addresses(i).Phone)
handles.Index = i;
guidata(hObject, handles)
return
end
end
% If it's a new name, ask to create a new entry
Answer=questdlg('Do you want to create a new entry?', ...
'Create New Entry', ...
'Yes','Cancel','Yes');
switch Answer
case 'Yes'
Addresses(end+1).Name = Current_Name; % Grow array by 1
Addresses(end).Phone = Current_Phone;
index = length(Addresses);
handles.Addresses = Addresses;
handles.Index = index;
guidata(hObject, handles)
return
case 'Cancel'
% Revert back to the original number
set(handles.Contact_Name,'String',Addresses(handles.Index).Name
)
set(handles.Contact_Phone,'String',Addresses(handles.Index).Pho
ne)
return
endThe Contact Phone # text box displays the phone number of the entry listed in the Contact Name text box. If you type in a new number and click one of the push buttons, the callback opens a question dialog box that asks you if you want to change the existing number or cancel your change.
Like the Contact Name text box, this callback uses the index pointer (handles.Index) to update the new number in the address book and to revert to the previously displayed number if the user clicks Cancel in the question dialog box. Both the current address book and the index pointer are saved in the handles structure so that this data is available to other callbacks.
If you create a new entry, you must save the MAT-file with the File > Save menu.
function Contact_Phone_Callback(hObject, eventdata, handles)
Current_Phone = get(handles.Contact_Phone,'string');
% If either one is empty then return
if isempty(Current_Phone)
return
end
% Get the current list of addresses from the handles structure
Addresses = handles.Addresses;
Answer=questdlg('Do you want to change the phone number?', ...
'Change Phone Number', ...
'Yes','Cancel','Yes');
switch Answer
case 'Yes'
% If no name match was found create a new contact
Addresses(handles.Index).Phone = Current_Phone;
handles.Addresses = Addresses;
guidata(hObject, handles)
return
case 'Cancel'
% Revert back to the original number
set(handles.Contact_Phone,...
'String',Addresses(handles.Index).Phone)
return
endBy clicking the Prev and Next buttons you can page back and forth through the entries in the address book. Both push buttons use the same callback, Prev_Next_Callback. You must set the Callback property of both push buttons to call this subfunction, as the following illustration of the Prev push button Callback property setting shows.

The callback defines an additional argument, str, that indicates which button, Prev or Next, was clicked. For the Prev button Callback property, the Callback string includes 'Prev' as the last argument. The Next button Callback string includes 'Next' as the last argument. The value of str is used in case statements to implement each button's functionality (see the code listing that follows).
Prev_Next_Callback gets the current index pointer and the addresses from the handles structure and, depending on which button the user clicks, the index pointer is decremented or incremented and the corresponding address and phone number are displayed. The final step stores the new value for the index pointer in the handles structure and saves the updated structure using guidata.
function Prev_Next_Callback(hObject, eventdata,handles,str) % Get the index pointer and the addresses index = handles.Index; Addresses = handles.Addresses; % Depending on whether Prev or Next was clicked, % change the display switch str case 'Prev' % Decrease the index by one i = index - 1; % If the index is less than one then set it equal to the index % of the last element in the Addresses array if i < 1 i = length(Addresses); end case 'Next' % Increase the index by one i = index + 1; % If the index is greater than the size of the array then % point to the first item in the Addresses array if i > length(Addresses) i = 1; end end % Get the appropriate data for the index in selected Current_Name = Addresses(i).Name; Current_Phone = Addresses(i).Phone; set(handles.Contact_Name,'string',Current_Name) set(handles.Contact_Phone,'string',Current_Phone) % Update the index pointer to reflect the new index handles.Index = i; guidata(hObject, handles)
When you make changes to an address book, you need to save the current MAT-file, or save it as a new MAT-file. The File submenus Save and Save As enable you to do this. These menus, created with the Menu Editor, use the same callback, Save_Callback.
The callback uses the menu Tag property to identify whether Save or Save As is the callback object (i.e., the object whose handle is passed in as the first argument to the callback function). You specify the menu's Tag property with the Menu Editor.
The handles structure contains the Addresses structure, which you must save (handles.Addresses) as well as the name of the currently loaded MAT-file (handles.LastFile). When the user makes changes to the name or number, the Contact_Name_Callback or the Contact_Phone_Callback updates handles.Addresses.
If the user selects Save, the save command is called to save the current MAT-file with the new names and phone numbers.
If the user selects Save As, a dialog box is displayed (uiputfile) that enables the user to select the name of an existing MAT-file or specify a new file. The dialog box returns the selected file name and path. The final steps include:
Using fullfile to create a platform-independent path name.
Calling save to save the new data in the MAT-file.
Updating the handles structure to contain the new MAT-file name.
Calling guidata to save the handles structure.
function Save_Callback(hObject, eventdata, handles)
% Get the Tag of the menu selected
Tag = get(hObject, 'Tag');
% Get the address array
Addresses = handles.Addresses;
% Based on the item selected, take the appropriate action
switch Tag
case 'Save'
% Save to the default addrbook file
File = handles.LastFile;
save(File,'Addresses')
case 'Save_As'
% Allow the user to select the file name to save to
[filename, pathname] = uiputfile( ...
{'*.mat';'*.*'}, ...
'Save as');
% If 'Cancel' was selected then return
if isequal([filename,pathname],[0,0])
return
else
% Construct the full path and save
File = fullfile(pathname,filename);
save(File,'Addresses')
handles.LastFile = File;
guidata(hObject, handles)
end
endThe Create New menu clears the Contact Name and Contact Phone # text fields to facilitate adding a new name and number. After making the new entries, the user must then save the address book with the Save or Save As menus. This callback sets the text String properties to empty strings:
function New_Callback(hObject, eventdata, handles) set(handles.Contact_Name,'String','') set(handles.Contact_Phone,'String','')
The address book defines its own resize function. To use this resize function, you must set the Application Options dialog box Resize behavior to User-specified, which in turn sets the figure's ResizeFcn property to:
address_book('ResizeFcn',gcbo,[],guidata(gcbo))Whenever the user resizes the figure, MATLAB software calls the ResizeFcn subfunction in the address book M-file (address_book.m)
The resize function allows users to make the figure wider, enabling it to accommodate long names and numbers, but does not allow the figure to be made narrower than its original width. Also, users cannot change the height. These restrictions simplify the resize function, which must maintain the proper proportions between the figure size and the components in the GUI.
When the user resizes the figure and releases the mouse, the resize function executes. At that point, the resized figure's dimensions are saved. The following sections describe how the resize function works.
If the new width is greater than the original width, set the figure to the new width.
The size of the Contact Name text box changes in proportion to the new figure width. This is accomplished by:
Changing the Units of the text box to normalized.
Resetting the width of the text box to be 78.9% of the figure's width.
Returning the Units to characters.
If the new width is less than the original width, use the original width.
If the user attempts to change the height, use the original height. However, because the resize function is triggered when the user releases the mouse button after changing the size, the resize function cannot always determine the original position of the GUI on screen. Therefore, the resize function applies a compensation to the vertical position (second element in the figure Position vector) by adding the vertical position to the height when the mouse is released and subtracting the original height.
When the figure is resized from the bottom, it stays in the same position. When resized from the top, the figure moves to the location where the mouse button is released.
The resize function calls movegui to ensure that the resized figure is on screen regardless of where the user releases the mouse.
The first time it runs, the GUI is displayed at the size and location specified by the figure Position property. You can set this property with the Property Inspector when you create the GUI.
function ResizeFcn(hObject, eventdata, handles)
% Get the figure size and position
Figure_Size = get(hObject, 'Position');
% Set the figure's original size in character units
Original_Size = [ 0 0 94 19.230769230769234];
% If the resized figure is smaller than the
% original figure size then compensate.
if (Figure_Size(3)<Original_Size(3)) | ...
(Figure_Size(4) ~= Original_Size(4))
if Figure_Size(3) < Original_Size(3)
% If the width is too small then reset to origianl width.
set(hObject, 'Position',...
[Figure_Size(1), Figure_Size(2), ...
Original_Size(3), Original_Size(4)])
Figure_Size = get(hObject, 'Position');
end
if Figure_Size(4) ~= Original_Size(4)
% Do not allow the height to change.
set(hObject, 'Position',...
[Figure_Size(1),...
Figure_Size(2)+Figure_Size(4)-Original_Size(4),...
Figure_Size(3), Original_Size(4)])
end
end
% Adjust the size of the Contact Name text box.
% Set the units of the Contact Name field to 'Normalized'.
set(handles.Contact_Name,'units','normalized')
% Get its Position.
C_N_pos = get(handles.Contact_Name,'Position');
% Reset it so that it's width remains normalized.
% relative to figure.
set(handles.Contact_Name,'Position',...
[C_N_pos(1) C_N_pos(2) 0.789 C_N_pos(4)])
% Return the units to 'Characters'.
set(handles.Contact_Name,'units','characters')
% Reposition GUI on screen.
movegui(hObject, 'onscreen')
![]() | A GUI to Set Simulink Model Parameters | Using a Modal Dialog Box to Confirm an Operation | ![]() |

Includes the most popular MATLAB recorded presentations with Q&A sessions led by MATLAB experts.
| © 1984-2009- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |