Lists of Items in a Programmatic GUI

About the Example

This GUI creates and manages lists, such as to-do lists, phone numbers, or any set of items. It has these features:

  • Ability to create new GUIs from an existing List Master GUI

  • A scrolling list box containing a numbered or unnumbered sequence of items

  • A text box and push buttons enabling GUI users to edit, add, delete, and reorder list items

  • Capability to import and export list data and to save a list by saving the GUI itself

  • A File menu for creating, opening, and saving GUIs.

The left image below shows the items available under the File menu. The right image shows a sample list.

The File Menu Items

GUI Containing a Sample List

View the Example Code

The example includes one code file, two MAT-files and a text file:

  • listmaster.m — The GUI code file, containing all required local functions

  • listmaster_icons.mat — Three icons, used as CData for push buttons

  • senators110cong.mat — A cell array containing phone book entries for United States senators

  • senators110th.txt — A text file containing the same data as senators110cong.mat

List Master looks for the listmaster_icons.mat MAT-file when creating a new GUI (from File > New menu). The files senators110cong.mat and senators110th.txt are not required to create or operate a GUI; you can use either one to populate a new List Master GUI with data using File > import list.

To obtain copies of the files for this example, follow these steps:

  1. Set your current folder to one in which you have write access.

  2. Copy the example files and open listmaster.m in the Editor by executing these commands:

    copyfile(fullfile(docroot,'techdoc','creating_guis','examples',...
       'listmaste*.*'),pwd), fileattrib('listmaste*.*','+w'),
    copyfile(fullfile(docroot,'techdoc','creating_guis','examples',...
       'senators110*.*'),pwd),fileattrib('senators110*.*','+w'),
    edit listmaster.m
    

Use the GUI

The GUI can create new instances of itself with File > New at any time, and any number of these instances can be open at the same time.

Start List Master

To start using List Master, make sure listmaster.m is on your path, and run the main function.

  1. >> listmaster
    
    ans =
         1

    The function opens a blank GUI with the title ListMaster and a File menu and returns its figure handle.

  2. Select New from the File menu to set up the GUI to handle list data.

    The GUI presents a dialog box (using inputdlg).

  3. Type a name for the list you want to create and click OK.

The New menu item's callback, lmnew, prompts the user for a list name and creates the GUI window with all the UI components.

Because the positions of all controls are specified in normalized Units, the GUI is resizable. Only the button icons and the text fonts have a fixed size.

Import Data into List Master

You can import data into the GUI at any time. If the GUI already contains data, the data you import replaces it.

You can import data from a cell array in the MATLAB® workspace. Each element of the cell array must contain a line of text corresponding to a single list item. For example, you can define a list of grocery items as follows:

groceries = {'1 dozen large eggs';
             '1/2 gallon milk';
             '5 lb whole wheat flour';
             '1 qt. vanilla ice cream';};

If you load the example MAT-file senators110cong.matand display it in the Variables editor, you can see it is structured this way.

Use spaces as separators between words in lists. If a list contains tab characters, the list box does not display them.

As it exists, you cannot import data from a text file using the List Master example code as supplied. It does contain a commented-out File menu item for this purpose and a callback for it (lmfileimport) containing no code. See Add an "Import from File" Option to List Master for more information.

You do not need to import data to work with List Master. The GUI allows you to create lists by selecting the Add radio button, typing items in the edit text box one at a time, and pressing Return to add each one to the list. You can export any list you create.

Export Data from List Master

You can use FileExport listto workspace to save the current list to a cell array in the MATLAB workspace. The lmwsexport callback performs this operation, calling the assignin function to create the variable after you specify its name. If you only want to export a single list item, perform these steps:

  1. Click on the list box item you want to copy or select the item's text in the edit box.

  2. Type Ctrl+C to copy the item.

  3. Open a document into which you want to paste the item

  4. Place the cursor where you want to paste the item and type Ctrl+V.

You cannot paste from the system clipboard into the list box, because the content of a list box can only be changed programmatically, by setting its String property. This means that to paste new items into a list, you must add them one at a time via the edit text box. It also means you cannot copy the entire list and then paste it into another document.

You can save the entire contents of a list to a text file using File > Export list > to file. That menu item's callback (lmfileexport) opens a standard file dialog to navigate to a folder and specify a file name. Then, lmfileexport calls fopen, fprintf, and fclose to create, write, and close the file.

Save the GUI

You do not need to export a list to save it. The Save and Save as menu options save lists by saving the entire GUI. They call the saveas function to write the figure and all its contents as a FIG-file to disk. You can reopen the saved GUI by double-clicking it in the Current Folder browser, or by calling hgload('figfilename.fig') from the Command Line.

Program List Master

The List Master GUI code file contains 22 functions, organized into five groups, which are described below.

List Master Main Program

The main function, listmaster, opens a figure window. Then, listmaster calls the local function, lm_make_file_menu, to create the File menu. The following table describes the menu items and lists their callbacks.

Menu ItemHow UsedCallback
Open...Opens an existing List Master figurelmopen
New...Creates a List Master by adding controls to the initial GUI or to a new figure if the existing one already contains a listlmnew
Import list...Loads list data from a workspace cell arraylmwsimport
Export list...Creates a cell array or text file containing the current listlmwsexport, lmfileexport
SaveSaves current List Master and its contents as a FIG-filelmsave
Save as...Saves current List Master to a different FIG-filelmsaveas
QuitExits List Master, with option to save firstlmquit

After creating a blank GUI with a File menu, the listmaster function exits.

The main function sets up the figure as follows:

fh = figure('MenuBar','none', ...
        'NumberTitle','off', ...
               'Name','ListMaster', ...
                'Tag','lmfigtag', ...
    'CloseRequestFcn', @lmquit, ...
              'Units','pixels', ...
           'Position', pos);

Turning off the MenuBar eliminates the default figure window menus, which the program later replaces with its own File menu. NumberTitle is turned off to eliminate a figure number in its title bar.

Here is the code that calculates the initial position of the GUI window:

su = get(groot,'Units');
set(groot,'Units','pixels')
scnsize = get(groot,'ScreenSize');
scnsize(3) = min(scnsize(3),1280);  % Limit superwide screens
figx = 264; figy = 356;             % Default (resizable) GUI size
pos = [scnsize(3)/2-figx/2 scnsize(4)/2-figy/2 figx figy];
...
set(groot,'Units',su)       % Restore default root screen units

The Open menu option only opens figures created by listmaster.m. Every List Master figure has its Tag set to lmfigtag. When the program opens a FIG-file, it uses this property value to determine that figure is a List Master GUI. If the Tag has any other value, the program closes the figure and displays an error.

The Quit menu option closes the GUI after checking whether the figure needs to be saved. If the contents have changed, its callback (lmquit) calls the lmsaveas callback to give the user an opportunity to save. The figure's CloseRequestFcn also uses the lmquit callback when the user clicks the figure's close box.

List Master Setup Functions

Although the initial GUI has no controls other than a menu, the user can select File > Save as to save a blank GUI as a FIG-file. Opening the saved FIG-file has the same result as executing the listmaster function.

The user can create a new list by selecting File > New. This executes setup functions that populate the GUI with uicontrols. The lmnew callback manages these tasks, calling setup functions in the following sequence. The three setup functions are listed and described below.

Setup FunctionHow Used
lm_get_list_nameCalls inputdlg to get name for new list, enforcing size limit of 32 characters
lm_make_ctrl_btnsCreates three push buttons for list navigation and a check box to control line numbering. This function also loads listmaster_icons.mat and adds icons to the to push buttons. Finally, it sets each button's callback functions.
lm_make_edit_panelCreates a button group with two radio buttons that control the editing mode. This function also places default text in the edit text box.

lmnew then calls the enable_updown function. The enable_updown function sets the Enable property of the pair of push buttons that migrate items higher or lower in the list box. It disables the Move Up button when the selected item is at the top of the list. It also disables the Move Down button when the selected item is at the bottom of the list. Then, the enable_updown function copies the current list selection into the edit text box. Finally, it sets the "dirty" flag in the figure's application data to indicate that the GUI's data or state has changed.

Having set up the GUI to receive data, the lmnew function enables the File > Import list menu option and its submenu

List Master Menu Callbacks

List Master has seven menu items and three submenu items. To obtain user input, the menu callbacks call these MATLAB functions:

The New menu item has two modes of operation, depending on whether the GUI is blank or already contains a list box and controls. The lmnew callback determines the state of the GUI by examining the figure's Name property:

  • If the GUI is blank, the name is "ListMaster".

  • If the GUI contains a list, the name is "Listmaster-" followed by a list name.

Called from a blank GUI, the function requests a name, and then populates the figure with all controls. Called from a GUI that contains a list, lmnew calls the main listmaster function to create a new GUI, and uses that figure's handle (instead of its own) when populating it with controls.

List Master List Callbacks

The six callbacks not associated with menu items are listed and described in this table.

Callback FunctionHow Used
move_list_itemCalled by the Move Up and Move Down push buttons to nudge items up and down list
enable_updownCalled from various local functions to enable and disable the Move Up and Move Down buttons and to keep the edit text box and list box synchronized.
delete_list_itemCalled from the Delete button to remove the currently selected item from the list; it keeps it in the edit text box in case the GUI user decides to restore it.
enter_editA KeypressFcn called by the edit text box when GUI user types a character; it sets the application data Edit flag when the GUI user types Return.
commit_editA Callback called by the edit text box when a GUI user types Return or clicks elsewhere; it checks the application data Edit flag set by enter_edit and commits the edit text to the list only if Return was the last key pressed. This avoids committing edits inadvertently.
toggle_list_numbersCallback for the lmnumlistbtn check box, which prefixes line numbers to list items or removes them, depending on value of the check box

Identify Component Handles.  A common characteristic of these and other List Master local functions is their way of obtaining handles for components. Rather than using the guidata function, which many GUIs use to share handles and other data for components, these local functions get handles they need dynamically by looking them up from their Tags, which are hard-coded and never vary. The code that finds handles uses the following pattern:

% Get the figure handle and from that, the listbox handle
fh = ancestor(hObject,'figure'); 
lh = findobj(fh,'Tag','lmtablisttag1');

Here, hObject is whatever object issued the callback that is currently executing, and 'lmtablisttag1' is the hard-coded Tag property of the list box. Always looking up the figure handle with ancestor assures that the current List Master is identified. Likewise, specifying the figure handle to findobj assures that only one list box handle is returned, regardless of how many List Master instances are open at the same time.

List Master Utility Functions

Certain callbacks rely on four small utility functions that are listed and described in this table.

Utility FunctionHow Used
number_listCalled to generate line numbers whenever a list updates and line numbering is on
guidirtySets the Boolean dirty flag in the figure's application data to true or false to indicate difference from saved version
isguidirtyReturns logical state of the figure's dirty flag
make_list_output_nameConverts the name of a list (obtained from the figure Name property) into a valid MATLAB identifier, which serves as a default when saving the GUI or exporting its data

List numbering works by adding five spaces before each list entry, then substituting numerals for characters 3, 2, and 1 of these blanks (as needed to display the digits) and placing a period in character 4. The numbers are stripped off the copy of the current item that displays in the text edit box, and then prepended again when the edit is committed (if the Number list check box is selected). This limits the size of lists that can be numbered to 999 items. You can modify number_list to add characters to the number field if you want the GUI to number lists longer than that.

    Note:   You should turn off the numbering feature before importing list data if the items on that list are already numbered. In such cases, the item numbers display in the list, but moving list items up or down in the list does not renumber them.

The guidirty function sets the figure's application data using setappdata to indicate that it has been modified, as follows:

function guidirty(fh,yes_no)
% Sets the "Dirty" flag of the figure to true or false

setappdata(fh,'Dirty',yes_no);
% Also disable or enable the File->Save item according to yes_no
saveitem = findobj(fh,'Label','Save');
if yes_no
    if isgraphics(saveitem)
      saveitem.Enable = 'on';
    end
else
    if isgraphics(saveitem)
      saveitem.Enable = 'off';
    end
end

The isguidirty function queries the application data with getappdata to determine whether the figure needs to be saved in response to closing the GUI.

Add an "Import from File" Option to List Master

If you want to round out List Master's capabilities, try activating the File > Import list > from file menu item. You can add this feature yourself by removing comments from lines 106-108 (enabling a File > Import list > from file menu item) and adding your own code to the callback. For related code that you can use as a starting point, see the lmfileexport callback for File > Export list > to file.

Add a "Rename List" Option to List Master

When you import data to a list, you replace the entire contents of the list with the imported text. If the content of the new list is very different, you might want to give a new name to the list. (The list name appears above the list box). Consider adding a menu item or context menu item, such as Rename list. The callback for this item might perform these tasks:

  • Call lm_get_list_name to get a name from the GUI user (perhaps after modifying it to let the caller specify the prompt string.)

  • Do nothing if the GUI user cancels the dialog.

  • Obtain the handle of the uipanel with tag 'lmtitlepaneltag'.

  • Set the Title property of the uipanel to the string that the user specifies.

After renaming the list, the user can save the GUI to a new FIG-file by selecting Save as. If the GUI had been saved previously, saving it to a new file preserves that version of the GUI with its original name and contents.

Was this topic helpful?