Quantcast
Channel: Undocumented Matlab
Viewing all articles
Browse latest Browse all 219

Editable combo-box

$
0
0

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

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

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.

We can clear these particular warnings via:

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

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

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 ($39, 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. 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...
  3. Figure toolbar components Matlab's toolbars can be customized using a combination of undocumented Matlab and Java hacks. This article describes how to access existing toolbar icons and how to add non-button toolbar components....
  4. GUI integrated HTML panel Simple HTML can be presented in a Java component integrated in Matlab GUI, without requiring the heavy browser control....
 

Viewing all articles
Browse latest Browse all 219

Trending Articles