Undocumented Matlab
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT

Editable combo-box

October 9, 2013 20 Comments

In previous articles, I explained how we can use findjobj to customize a Matlab uicontrol’s underlying Java control, thereby improving its appearance and functionality. My two previous articles on the Matlab editbox were a classic example of this mechanism. Unfortunately, this technique does not always work well, and an alternative mechanism needs to be used. One such case in point is the subject of today’s article.
Matlab combo-box (a.k.a. “popup-menu” or “drop-down”) controls are very simple controls that accept a list of strings from which a user can select. This is a very simple control that answers a wide range of use-cases. Unfortunately, it is quite limited. Among other limitations, we cannot modify the popup-panel’s appearance/functionality; we cannot select multiple items; and we cannot type-in a value in the control’s editbox. Today’s article will focus on the latter limitation, namely how to use an editable combo-box.

Trying to make Matlab’s standard combobox editable

We can indeed use findjobj to get a Matlab combo-box’s underlying Java control. This turns out to be a com.mathworks.hg.peer.ComboboxPeer$MLComboBox object, which extends the standard Java Swing JComboBox:

>> hCombo = uicontrol('Style','popup', 'String',{'a','b','c'});
>> jCombo = findjobj(hCombo)
jCombo =
	javahandle_withcallbacks.com.mathworks.hg.peer.ComboboxPeer$MLComboBox

>> hCombo = uicontrol('Style','popup', 'String',{'a','b','c'}); >> jCombo = findjobj(hCombo) jCombo = javahandle_withcallbacks.com.mathworks.hg.peer.ComboboxPeer$MLComboBox

This jCombo control has the Editable property that we can then try to override (the default value is false):

>> jCombo.setEditable(true);
>> jCombo.Editable = true;          % equivalent alternative
>> set(jCombo,'setEditable',true);  % equivalent alternative

>> jCombo.setEditable(true); >> jCombo.Editable = true; % equivalent alternative >> set(jCombo,'setEditable',true); % equivalent alternative

Editable combo-box control
Editable combo-box control

The bad news is that the moment we enter some value (as in the screenshot here) that is not already a member of the pop-up panel (i.e., the cell-array in the String property), then the control disappears and a warning message is issued to the Matlab console:

Warning: popupmenu control requires that Value be an integer within String range
Control will not be rendered until all of its parameter values are valid
(Type "warning off MATLAB:hg:uicontrol:ParameterValuesMustBeValid" to suppress this warning.)

Warning: popupmenu control requires that Value be an integer within String range Control will not be rendered until all of its parameter values are valid (Type "warning off MATLAB:hg:uicontrol:ParameterValuesMustBeValid" to suppress this warning.)


The reason for this behavior is that when the combo-box object detects that the text field’s content match none of the popup list items, it automatically sets jCombo‘s SelectedIndex to -1 and Matlab’s corresponding HG Value property to 0. At this point the Matlab implementation kicks in, hiding the uicontrol since it considers 0 an invalid value for the Value property. This is similar to the check being done to test for an empty HG String value (=no items):

>> set(hCombo, 'string', [])
popupmenu control requires a non-empty String
Control will not be rendered until all of its parameter values are valid.

>> set(hCombo, 'string', []) popupmenu control requires a non-empty String Control will not be rendered until all of its parameter values are valid.

We can clear these particular warnings via:

warning('off','MATLAB:hg:uicontrol:ParameterValuesMustBeValid')

warning('off','MATLAB:hg:uicontrol:ParameterValuesMustBeValid')

but this does not prevent the control from being hidden – it just prevents the warning from showing on the Command Window.
We can dive deeper and try to modify the underlying data model and disassociate the Java control from HG, but let’s stop at this point since there is really no point considering the fact that there is a much simpler alternative.
Note: if you do decide to make the standard Matlab uicontrol editable, read here for a related customization that I posted several years ago.

The pure-Java alternative

Rather than customizing Matlab’s uicontrol, we can easily create an identical-looking control using the standard Java Swing JComboBox, which has none of these problems/limitations. We can create and display the component in one go using the semi-documented javacomponent function:

position = [10,100,90,20];  % pixels
hContainer = gcf;  % can be any uipanel or figure handle
options = {'a','b','c'};
model = javax.swing.DefaultComboBoxModel(options);
jCombo = javacomponent('javax.swing.JComboBox', position, hContainer);jCombo.setModel(model);jCombo.setEditable(true);

position = [10,100,90,20]; % pixels hContainer = gcf; % can be any uipanel or figure handle options = {'a','b','c'}; model = javax.swing.DefaultComboBoxModel(options); jCombo = javacomponent('javax.swing.JComboBox', position, hContainer); jCombo.setModel(model); jCombo.setEditable(true);

We can use a variant of javacomponent to create the component with the model in one go, replacing the highlighted lines above:

jCombo = javacomponent({'javax.swing.JComboBox',model}, position, hContainer);

jCombo = javacomponent({'javax.swing.JComboBox',model}, position, hContainer);

Once we have the control ready, all we need to do is set its ActionPerformedCallback property to our Matlab callback function and we’re pretty-much set. We can get the currently-selected text using char(jCombo.getSelectedItem) and the selected list index (0-based) using jCombo.getSelectedIndex (which returns -1 if we entered a non-listed value, 0 for the first list item, 1 for the second etc.). More information can be found here.

Lesson learnt

In the past 20+ years of my professional life as engineer and development manager, my number one rule has always been:

DON’T FIX IT, IF IT AIN’T BROKE!

But sometimes, we should also remember an alternative version:
DON’T FIX IT, IF IT’S EASIER TO REPLACE!

Available report – “Advanced Customizations of Matlab Uicontrols”

Interested readers can find more information about these and other possible customizations in my report on “Advanced Customizations of Matlab Uicontrols“. This 90-page PDF report can be purchased here ($29, please allow 24 hours for delivery by email). The report explains how to customize Matlab’s uicontrols in ways that are simply not possible using documented Matlab properties. This includes treatment of push buttons, toggle buttons, radio buttons, checkboxes, editboxes, listboxes, popup menus (aka combo-boxes/drop-downs), sliders, labels, and tooltips. Much of the information in the report is also available in hard-copy format in chapter 6 of my Matlab-Java programming book.

Related posts:

  1. Using JIDE combo-boxes – Matlab includes many custom JIDE combo-box controls that can be used in Matlab GUIs out of the box. ...
  2. Common javacomponent problems – The javacomponent function is very useful for placing Java components on-screen, but has a few quirks. ...
  3. Additional uicontrol tooltip hacks – Matlab's uicontrol tooltips have several limitations that can be overcome using the control's underlying Java object....
  4. Auto-completion widget – Matlab includes a variety of undocumented internal controls that can be used for an auto-completion component. ...
  5. The javacomponent function – Matlab's built-in javacomponent function can be used to display Java components in Matlab application - this article details its usages and limitations...
  6. GUI integrated HTML panel – Simple HTML can be presented in a Java component integrated in Matlab GUI, without requiring the heavy browser control....
GUI Java Semi-documented function uicontrol
Print Print
« Previous
Next »
20 Responses
  1. moshe February 20, 2014 at 01:48 Reply

    shalom Yair,
    first of all – I enjoy your fruitfull and interesting ideas
    second, regarding the editable combobox – is there a way to search the list as one types the words ‘online’ so he needs not scroll the whole list. i have a list of over 3000 to search…

    best
    moshe

    • Yair Altman February 20, 2014 at 02:23 Reply

      @Moshe – you can either update the combo’s list items in the control’s KeyTypedCallback, or use a dedicated control that does it for you. One example is Matlab’s internal com.mathworks.widgets.AutoCompletionList, but this component does not exist in all Matlab releases.

      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);

      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

      I explain this and other alternatives in pages 296-297 and 407-416 of my book.

      • moshe February 23, 2014 at 02:27

        shalom Yair,
        as i struggle with the AutoCompletionList, a few questions are arised:
        1. how do i retrieve the value, string one chooses?
        2. can it be modified to look and behave like combobox?

        looking forward to hearing from you…
        moshe

      • moshe February 23, 2014 at 02:47

        another questions
        is there a way to search with wild cards and make the list shorter, as the user types the search?

      • Yair Altman February 23, 2014 at 15:17

        @Moshe – I do not have additional information to what I wrote above and in my book. I’m afraid that you will need to investigate this by yourself for the time being, since I do not plan to write an article about this in the foreseeable future, sorry.

      • moshe March 11, 2014 at 19:42

        I succeeded thanks to your suggestion to make use of the various optional Callbacks, when i’m done with the code i’ll be glad to publish it here

    • Steven Tsai September 3, 2014 at 20:28 Reply

      Hi, Yair,
      “you can either update the combo’s list items in the control’s KeyTypedCallback”
      I tried set the jCombo’s KeyTypeCallback property, but it does not work:

      position = [10,100,90,20];  % pixels
      hContainer = gcf;  % can be any uipanel or figure handle
      options = {'a','b','c'};
      model = javax.swing.DefaultComboBoxModel(options);
      jCombo = javacomponent('javax.swing.JComboBox', position, hContainer);
      jCombo.setModel(model);
      jCombo.setEditable(true);
      jComboh = handle(jCombo,'CallbackProperties');
      set(jComboh,'KeyTypedCallback','disp(''Hello, Yair'')')

      position = [10,100,90,20]; % pixels hContainer = gcf; % can be any uipanel or figure handle options = {'a','b','c'}; model = javax.swing.DefaultComboBoxModel(options); jCombo = javacomponent('javax.swing.JComboBox', position, hContainer); jCombo.setModel(model); jCombo.setEditable(true); jComboh = handle(jCombo,'CallbackProperties'); set(jComboh,'KeyTypedCallback','disp(''Hello, Yair'')')

      could you explain more details, thanks so much.

      • Yair Altman September 4, 2014 at 01:42

        @Steven – You need to specify the KeyTypedCallback on the combo-box’es editbox (text-field) sub-component, not on the top-level component. Namely:

        jComboField = handle(jCombo.getComponent(jCombo.getComponentCount-1), 'CallbackProperties');
        set(jComboField, 'KeyTypedCallback', @myCallbackFunc);

        jComboField = handle(jCombo.getComponent(jCombo.getComponentCount-1), 'CallbackProperties'); set(jComboField, 'KeyTypedCallback', @myCallbackFunc);

  2. Steven Tsai September 3, 2014 at 02:13 Reply

    Hi Yair,

    I was trying to use a ◾TreeComboBox in my GUI, but it seems something is wrong:

    • Yair Altman September 3, 2014 at 02:16 Reply

      What’s wrong exactly?

  3. King September 15, 2014 at 12:16 Reply

    Hi Yair

    Firstly, thank you for your website.
    I found a lot of useful hints from your website.

    At this time, I try to call a MATLAB function when an item was selected in combo box’s drop down list. (mouse or up/down key pressed)
    I know I can do that in Java by adding ‘addactionlistener’ or ‘additemlistener’.

    How can I do the same job in MATLAB GUI?

    Thanks,

    King

    • Yair Altman September 15, 2014 at 13:51 Reply

      @King –

      set(jCombo, 'ActionPerformedCallback', @myCallbackFcn)

      set(jCombo, 'ActionPerformedCallback', @myCallbackFcn)

    • King September 15, 2014 at 20:21 Reply

      Thanks! It works!
      Before I saw your solution, I figure out I can use KeyReleasedCallBack as my callback property
      However, it still not solve the mouse click issue.
      Your one get the job done perfectly!
      Furthermore, instead of clicking mouse on the item, moving mouse on item then fire the callback?
      I tried jCombo.getcomponent(2) and added mouselistener, but it doesn’t help.
      Maybe I am in a right approach but missing some lines?

      Thanks!

  4. King September 24, 2014 at 07:51 Reply

    Hi Yair

    set(jCombo, ‘ActionPerformedCallback’, @myCallbackFcn)

    This commandline can handle the callback.
    But I want to handle the user input more precisely.
    I try to hear ‘Up’ ‘Down’ ‘Enter’key pressed or mouse left click.
    Therefore, I can assign different function to different user input.
    Is it possible to do that in combo box? If so, how?

    Thanks a lot.

    • Yair Altman September 27, 2014 at 12:27 Reply

      @King – see my answer above to Steven Tsai.

  5. Buer December 3, 2014 at 01:43 Reply

    Hi Yair,

    Thanks for the great information. However I want to ask if I have two combobox, how can I put them inside one figure instead of two?

    Meanwhile, if I want to have a label for each combbox. How can I do that? I checked around, did not find anything about that.

    Thanks.

    • Yair Altman December 3, 2014 at 15:13 Reply

      @Buer – you can use the Position property of the uicontrol to place it anywhere in your figure, and place separate uicontrols in separate locations. You can use other calls to uicontrol to place text labels. Look it up in the documentation.

  6. Eric August 11, 2017 at 20:31 Reply

    I created a plotter using three popup menus: one for X-variable, one for Y, and one for a figure name. When a figure name (number) is selected, its callback function grabs strings from X and Y popup menus, search these from a loaded dataset, and plots them.

    What I want to do is multiple-selection on a popup menu. I researched quite a bit and learned that popup menu doesn’t have that capability as you also mentioned on the top in the regular documented way.

    The reason why I don’t want and almost can’t use list box is my GUI has many panels from top to bottom; each containing the three popup menus mentioned above. Each panel represents one dataset. This means if I select and load ten .MAT files, a GUI will be created with 10 panels from top to bottom. Each dataset can have as many as 100 or more variables. Unless I completely scrub the current GUI generation code, listbox won’t work. Say each listbox shows ten variables and a scroll bar. The height of it and some margins above and below times 10 will create a gigantic GUI that will be basically unusable.

    Do you know a work-around? Thank you in advance.

    • Yair Altman August 12, 2017 at 20:44 Reply

      @Eric – you can integrate a com.jidesoft.combobox.MultiSelectListComboBox or MultilineStringComboBox. If you need consulting assistance, contact me by email.

  7. Amit November 6, 2017 at 17:44 Reply

    Hi Yair,

    How can I use JIDE’s DateComboBox as the celleditor for a column in a jide table? So basically a table column having a combobox dropdown as a date selector(calendar), I have set the column class as date and made it to accept different date formats, but couldn’t get calendar dropdown to work in a table.

    Thanks,
    Amit

Leave a Reply
HTML tags such as <b> or <i> are accepted.
Wrap code fragments inside <pre lang="matlab"> tags, like this:
<pre lang="matlab">
a = magic(3);
disp(sum(a))
</pre>
I reserve the right to edit/delete comments (read the site policies).
Not all comments will be answered. You can always email me (altmany at gmail) for private consulting.

Click here to cancel reply.

Useful links
  •  Email Yair Altman
  •  Subscribe to new posts (feed)
  •  Subscribe to new posts (reader)
  •  Subscribe to comments (feed)
 
Accelerating MATLAB Performance book
Recent Posts

Speeding-up builtin Matlab functions – part 3

Improving graphics interactivity

Interesting Matlab puzzle – analysis

Interesting Matlab puzzle

Undocumented plot marker types

Matlab toolstrip – part 9 (popup figures)

Matlab toolstrip – part 8 (galleries)

Matlab toolstrip – part 7 (selection controls)

Matlab toolstrip – part 6 (complex controls)

Matlab toolstrip – part 5 (icons)

Matlab toolstrip – part 4 (control customization)

Reverting axes controls in figure toolbar

Matlab toolstrip – part 3 (basic customization)

Matlab toolstrip – part 2 (ToolGroup App)

Matlab toolstrip – part 1

Categories
  • Desktop (45)
  • Figure window (59)
  • Guest bloggers (65)
  • GUI (165)
  • Handle graphics (84)
  • Hidden property (42)
  • Icons (15)
  • Java (174)
  • Listeners (22)
  • Memory (16)
  • Mex (13)
  • Presumed future risk (394)
    • High risk of breaking in future versions (100)
    • Low risk of breaking in future versions (160)
    • Medium risk of breaking in future versions (136)
  • Public presentation (6)
  • Semi-documented feature (10)
  • Semi-documented function (35)
  • Stock Matlab function (140)
  • Toolbox (10)
  • UI controls (52)
  • Uncategorized (13)
  • Undocumented feature (217)
  • Undocumented function (37)
Tags
ActiveX (6) AppDesigner (9) Callbacks (31) Compiler (10) Desktop (38) Donn Shull (10) Editor (8) Figure (19) FindJObj (27) GUI (141) GUIDE (8) Handle graphics (78) HG2 (34) Hidden property (51) HTML (26) Icons (9) Internal component (39) Java (178) JavaFrame (20) JIDE (19) JMI (8) Listener (17) Malcolm Lidierth (8) MCOS (11) Memory (13) Menubar (9) Mex (14) Optical illusion (11) Performance (78) Profiler (9) Pure Matlab (187) schema (7) schema.class (8) schema.prop (18) Semi-documented feature (6) Semi-documented function (33) Toolbar (14) Toolstrip (13) uicontrol (37) uifigure (8) UIInspect (12) uitools (20) Undocumented feature (187) Undocumented function (37) Undocumented property (20)
Recent Comments
  • Nicholas (7 days 2 hours ago): Hi Yair, Thanks for the reply. I am on Windows 10. I also forgot to mention that this all works wonderfully out of the editor. It only fails once compiled. So, yes, I have tried a...
  • Nicholas (7 days 2 hours ago): Hi Yair, Thanks for the reply. I am on Windows 10. I also forgot to mention that this all works wonderfully out of the editor. It only fails once compiled. So, yes, I have tried a...
  • Yair Altman (7 days 9 hours ago): Nicholas – yes, I used it in a compiled Windows app using R2022b (no update). You didn’t specify the Matlab code location that threw the error so I can’t help...
  • Nicholas (8 days 5 hours ago): Hi Yair, Have you attempted your displayWebPage utility (or the LightweightHelpPanel in general) within a compiled application? It appears to fail in apps derived from both R2022b...
  • João Neves (11 days 10 hours ago): I am on matlab 2021a, this still works: url = struct(struct(struct(struct(hF ig).Controller).PlatformHost). CEF).URL; but the html document is empty. Is there still a way to do...
  • Yair Altman (14 days 8 hours ago): Perhaps the class() function could assist you. Or maybe just wrap different access methods in a try-catch so that if one method fails you could access the data using another...
  • Jeroen Boschma (14 days 11 hours ago): Never mind, the new UI components have an HTML panel available. Works for me…
  • Alexandre (14 days 12 hours ago): Hi, Is there a way to test if data dictionnatry entry are signal, simulink parameters, variables … I need to access their value, but the access method depends on the data...
  • Nicholas (15 days 2 hours ago): In case anyone is looking for more info on the toolbar: I ran into some problems creating a toolbar with the lightweight panel. Previously, the Browser Panel had an addToolbar...
  • Jeroen Boschma (18 days 9 hours ago): I do not seem to get the scrollbars (horizontal…) working in Matlab 2020b. Snippets of init-code (all based on Yair’s snippets on this site) handles.text_explorer...
  • Yair Altman (46 days 11 hours ago): m_map is a mapping tool, not even created by MathWorks and not part of the basic Matlab system. I have no idea why you think that the customizations to the builtin bar function...
  • chengji chen (46 days 18 hours ago): Hi, I have tried the method, but it didn’t work. I plot figure by m_map toolbox, the xticklabel will add to the yticklabel at the left-down corner, so I want to move down...
  • Yair Altman (54 days 11 hours ago): @Alexander – this is correct. Matlab stopped including sqlite4java in R2021b (it was still included in 21a). You can download the open-source sqlite4java project from...
  • Alexander Eder (60 days 6 hours ago): Unfortunately Matlab stopped shipping sqlite4java starting with R2021(b?)
  • K (66 days 17 hours ago): Is there a way to programmatically manage which figure gets placed where? Let’s say I have 5 figures docked, and I split it into 2 x 1, I want to place 3 specific figures on the...
Contact us
Captcha image for Custom Contact Forms plugin. You must type the numbers shown in the image
Undocumented Matlab © 2009 - Yair Altman
This website and Octahedron Ltd. are not affiliated with The MathWorks Inc.; MATLAB® is a registered trademark of The MathWorks Inc.
Scroll to top