Do you ever get a feeling when designing a Matlab GUI, that existing components/controls are simply not enough to achieve the desired functionality/appearance?
Such a case happened to me, when a consulting client asked me to integrate an auto-completion widget in a GUI that I designed for them. The idea was simple enough: the user selects a class of financial assets from a drop-down, then one or more actual financial securities from a dynamically-populated drop-down (based on the asset class), then the date range and analysis function, and finally the results are plotted in the main panel. The idea was for Matlab to automatically auto-complete the financial instruments matching the entered text, as it is being typed, similarly to other standard auto-completion widgets (e.g., Google’s search box), including the use of wildcards and regular expressions:

Interactive Matlab auto-completion widget
Note that in this particular case, I use the term “auto-completion” loosely. The correct term should actually be “auto-winnowing” or “auto-filtering”. Auto-completion is usually reserved for the case of the user-entered text being automatically completed as they type, whereas auto-winnowing only updates the drop-down options on-the-fly. These two functionalities are often correlated, and today’s article will discuss both.
AutoCompletionList
Before I dive into details of the implementation I ended up with, note that there are simpler alternatives. For example, we can use Matlab’s internal com.mathworks.widgets.AutoCompletionList
widget:
strs = {'This','is','test1','test2'}; strList = java.util.ArrayList; for idx = 1 : length(strs), strList.add(strs{idx}); end jPanelObj = com.mathworks.widgets.AutoCompletionList(strList,''); javacomponent(jPanelObj.getComponent, [10,10,200,100], gcf);

AutoCompletionList widget
The AutoCompletionList
control is actually a list (rather than a drop-down), where the user types an entry in the header row. The control automatically selects the first corresponding list item and auto-completes the rest of the entry. Invalid user entries generate a beep and are not allowed by default (unless the widget’s Strict property is cleared: jPanelObj.setStrict(false)
). The visible list size can be controlled by setting the widget’s VisibleRowCount property (jPanelObj.setVisibleRowCount(6)
).
Items can be selected by either typing in the header row, by selecting a list item, or programmatically (jPanelObj.setSelectedValue('test1')
). The currently selected item is retrieved via the same SelectedValue property (selectedValue = char(jPanelObj.getSelectedValue)
). As with many other actionable Java controls, we can attach a callback on the ActionPerformed event:
set(handle(jPanelObj,'callbackproperties'), 'ActionPerformedCallback', @myMatlabCallbackFunc);
We can attach a similar callback to key-typing within the header row (text field), by accessing the widget’s internal component (which is the one that is actually being displayed via the javacomponent function):
set(handle(jPanelObj.getComponent,'callbackproperties'), 'KeyTypedCallback', @myMatlabCallbackFunc);
SearchTextField
For my client’s purposes, however, AutoCompletionList
could not be used. We wanted a drop-down selector that takes up far less space than a listbox. The first thought was to use a modified drop-down (editable combo-box). This turned out to be less effective than hoped, because of the interference between the Matlab KeyTypedCallback function and the automatic behavior of the combo-box. I do not rule out the use of such an editable combo-box in other use-cases, but for this implementation I chose to use a different control, namely Matlab’s internal com.mathworks.widgets.SearchTextField
, which has some nice additional features such as an optional light-gray prompt, and a clickable search icon that changes its appearance and behavior based on the entered text:
jPanelObj = com.mathworks.widgets.SearchTextField('Enter search term:'); [jhPanel,hContainer] = javacomponent(jPanelObj.getComponent, [10,10,150,25], gcf);
![]() SearchTextField initial view | ![]() user clicks in entry box (prompt text disappears) | ![]() user types something |
An optical illusion
As with a regular combo-box, the dropdown-menu integration in Matlab proved a bit difficult, especially due to the auto-completion feature. Again, I do not rule out using it in other use-cases, but for this implementation I chose to use a visual illusion: an actual combo-box is placed beneath (hidden by) the SearchTextField
control. So basically, we are seeing two disparate parts of two separate components: the edit-box of the SearchTextField
and the dropdown panel (a JPopupMenu
) of the hidden combo-box. They appear attached, providing the optical illusion of being a single widget, when in fact they are not. Neat, right?
Callback events are used to synchronize the components, update the combo-box’s dropdown options and display the dropdown panel. We attach the same callback function to 3 separate events: MouseClickedCallback on the search button (icon), KeyPressedCallback on the search text-box, and another KeyPressedCallback on the combo-box’s text-box (which is not visible, but automatically receives focus when the user interacts with the popup menu (drop-down panel):
% Create the SearchTextField component (after the hidden combo was created) jAssetChooser = com.mathworks.widgets.SearchTextField('Enter search:'); jAssetComponent = jAssetChooser.getComponent; [jhAssetComponent, hContainer] = javacomponent(jAssetComponent,[],hPanel); % Set callbacks hjSearchButton = handle(jAssetComponent.getComponent(1), 'CallbackProperties'); set(hjSearchButton, 'MouseClickedCallback', {@updateSearch,jCombo,jAssetChooser}); hjSearchField = handle(jAssetComponent.getComponent(0), 'CallbackProperties'); set(hjSearchField, 'KeyPressedCallback', {@updateSearch,jCombo,jAssetChooser}); jComboField = handle(jCombo.getComponent(2), 'CallbackProperties'); set(jComboField, 'KeyPressedCallback', {@updateSearch,jCombo,[]});
The user can now select an item either from the combo-box’s dropdown panel, or by typing in the search text-box. Here is the implementation of the updateSearch()
callback function:
% Asset search popup combo button click callback function updateSearch(hObject, eventData, jCombo, jAssetChooser) %#ok<INUSL> persistent lastSearchText if isempty(lastSearchText), lastSearchText = ''; end try % event occurred on the search field component try searchText = jAssetChooser.getSearchText; jSearchTextField = jAssetChooser.getComponent.getComponent(0); catch % Came via asset change - always update jSearchTextField = jAssetChooser.getComponent(0); searchText = jSearchTextField.getText; lastSearchText = '!@#$'; end catch try % event occurred on the jCombo-box itself searchText = jCombo.getSelectedItem; catch % event occurred on the internal edit-field sub-component searchText = jCombo.getText; jCombo = jCombo.getParent; end jSearchTextField = jCombo.getComponent(jCombo.getComponentCount-1); end searchText = strrep(char(searchText), '*', '.*'); % turn into a valid regexp searchText = regexprep(searchText, '<[^>]+>', ''); if strcmpi(searchText, lastSearchText) && ~isempty(searchText) jCombo.showPopup; return; % maybe just clicked an arrow key or Home/End - no need to refresh the popup panel end lastSearchText = searchText; assetClassIdx = getappdata(handles.cbAssetClass, 'assetClassIdx'); if isempty(assetClassIdx) jCombo.hidePopup; return; elseif isempty(searchText) assetNamesIdx = assetClassIdx; else searchComponents = strsplit(searchText, ' - '); assetCodeIdx = ~cellfun('isempty',regexpi(data.header.AssetCode(assetClassIdx),searchComponents{1})); assetNameIdx = ~cellfun('isempty',regexpi(data.header.AssetName(assetClassIdx),searchComponents{end})); if numel(searchComponents) > 1 assetNamesIdx = assetClassIdx(assetCodeIdx & assetNameIdx); else assetNamesIdx = assetClassIdx(assetCodeIdx | assetNameIdx); end end setappdata(handles.cbAssetSearch, 'assetNameIdx', assetNamesIdx); if isempty(assetNamesIdx) jCombo.hidePopup; jSearchTextField.setBackground(java.awt.Color.yellow); jSearchTextField.setForeground(java.awt.Color.red); newFont = jSearchTextField.getFont.deriveFont(uint8(java.awt.Font.BOLD)); jSearchTextField.setFont(newFont); return; else jSearchTextField.setBackground(java.awt.Color.white); jSearchTextField.setForeground(java.awt.Color.black); newFont = jSearchTextField.getFont.deriveFont(uint8(java.awt.Font.PLAIN)); jSearchTextField.setFont(newFont); end % Compute the filtered asset names (highlight the selected search term) assetNames = strcat(data.header.AssetCode(assetNamesIdx), ' -=', data.header.AssetName(assetNamesIdx)); assetNames = regexprep(assetNames, '(.+) -=\1', '$1', 'ignorecase'); assetNames = unique(strrep(assetNames, ' -=', ' - ')); if ~isempty(searchText) assetNames = regexprep(assetNames, ['(' searchText ')'], '<b><font color=blue>$1</font></b>', 'ignorecase'); assetNames = strcat('<html>', assetNames); end % Redisplay the updated combo-box popup panel jCombo.setModel(javax.swing.DefaultComboBoxModel(assetNames)); jCombo.showPopup; end % updateSearch
Here is the final result:

Matlab GUI with integrated auto-completion & date selection widgets
Would you believe that this entire program is only 400 lines of code?!
Conclusion
I’ve heard it say on occasion that Matlab GUI is not really suited for professional applications. I completely disagree, and hope that today’s article proves otherwise. You can make Matlab GUI do wonders, in various different ways. Matlab does have limitations, but they are nowhere close to what many people believe. If you complain that your GUI sucks, then it is likely not because of Matlab’s lack of abilities, but because you are only using a very limited portion of them. This is no different than any other programming environment (admittedly, such features are much better documented in other environments).
In short, to improve your GUI’s functionality and appearance, you just need to spend a bit of time searching for the right components (possibly using my book), or hire a professional consultant to do it for you. But of course, just bitching about Matlab’s supposed limitations is much easier…
Do you have a GUI that you find hard to believe can be done (or improved) in Matlab? Contact me for a consulting proposal and let me surprise you!
Related posts:
- Class object tab completion & improper field names Tab completions and property access can be customized for user-created Matlab classes. ...
- Plot-type selection components Several built-in components enable programmatic plot-type selection in Matlab GUI - this article explains how...
- Animated busy (spinning) icon An animated spinning icon label can easily be embedded in Matlab GUI. ...
- FindJObj GUI – display container hierarchy The FindJObj utility can be used to present a GUI that displays a Matlab container's internal Java components, properties and callbacks....