- Undocumented Matlab - https://undocumentedmatlab.com -
Customizing combobox popups
Posted By Yair Altman On September 24, 2014 | 8 Comments
Last week I explained how we can use display custom items in a standard Matlab combobox [1] (popup/dropdown), using its underlying Java component. Today I will show how we can use this Java component for other nice customizations of the combobox’s popup:
The first step is to find the underlying Java component of the Matlab combobox (aka popup) uicontrol. This is done using my findjobj utility [6]:
% Create the Matlab combobox
items = {'Hello', 'world', ...
'What a', ...
'nice day!'};
hCombobox = uicontrol('Style','popup', 'Position',[10,100,120,20], 'String',items);
% Find the uicontrol's underlying Java component
jCombobox = findjobj(hCombobox);
For findjobj to work, the Matlab uicontrol needs to be visible – it will not have a Java component before it is rendered onscreen for the first time. If everything is successful, jCombobox should now be a reference to the underlying om.mathworks.hg.peer.ComboboxPeer$MLComboBox
Java component, which is an extension of the standard Swing JComboBox
[7], as can be seen using my checkClass utility [8]:
>> jCombobox.checkClass
private com.mathworks.hg.peer.ComboboxPeer$MLComboBox (uiinspect)
Superclass: com.mathworks.mwswing.MJComboBox
Superclass: javax.swing.JComboBox
Methods in JComboBox missing in ComboboxPeer$MLComboBox:
JComboBox()
JComboBox(java.lang.Object[])
JComboBox(java.util.Vector)
JComboBox(javax.swing.ComboBoxModel)
Methods in ComboboxPeer$MLComboBox missing in JComboBox:
ComboboxPeer$MLComboBox(com.mathworks.hg.peer.ComboboxPeer)
isPopupWidthConstrained() : boolean
isTipWhenTruncatedEnabled() : boolean
processEvent(java.awt.AWTEvent)
registerWithKeyBindingManager(com.mathworks.mwswing.binding.KeyBindingManager, java.lang.String)
setConstrainPopupWidth(boolean)
setEditorColumnCount(int)
setTipWhenTruncatedEnabled(boolean)
Methods inherited & modified by ComboboxPeer$MLComboBox:
getInsets() : java.awt.Insets
setBackground(java.awt.Color)
updateUI()
Interfaces in JComboBox missing in ComboboxPeer$MLComboBox:
java.awt.ItemSelectable
java.awt.event.ActionListener
javax.accessibility.Accessible
javax.swing.event.ListDataListener
We shall now use three properties of this object to customize the control’s popup:
The MaximumRowCount numeric property (default=20) sets the maximal number of drop-down items to display in the visible portion of the popup, before requiring a scrollbar. This basically controls the popup’s height:
% Get the current MaximumRowCount value
numItems = get(jCombobox, 'MaximumRowCount');
numItems = jCombobox.MaximumRowCount; % equivalent - access the property directly
numItems = jCombobox.getMaximumRowCount; % equivalent - use Java's accessor method (best way)
% Set the MaximumRowCount value
set(jCombobox,'MaximumRowCount',3);
jCombobox.MaximumRowCount = 3; % equivalent - access the property directly
jCombobox.setMaximumRowCount(3); % equivalent - use Java's accessor method (best way)
JComboBox
, so if we use a JComboBox
directly in our code (using javacomponent [9]) we will not have this feature. Creating the ComboboxPeer$MLComboBox
component instead is possible, but is beyond the scope of this article, because MathWorks chose for this class not to have JComboBox
‘s standard constructors but rather only a constructor that accepts a com.mathworks.hg.peer.ComboboxPeer
object.
The PopupVisible property (default=false) is a boolean flag which controls whether the popup window is currently (or should be) displayed. If this property is updated, then the focus is automatically transferred to the popup window for easy item selection using the keyboard (up/down/enter keys). There are also equivalent convenience methods showPopup()/hidePopup():
% Is the popup currently shown?
isShown = get(jCombobox, 'PopupVisible');
isShown = jCombobox.PopupVisible; % equivalent - access the property directly
isShown = jCombobox.isPopupVisible; % equivalent - use Java's accessor method (best way)
% Display the popup
set(jCombobox,'PopupVisible',true); % NOT 'on' - this is a Java property, not a Matlab HG one!
jCombobox.PopupVisible = true; % equivalent - access the property directly
jCombobox.setPopupVisible(true); % equivalent - use Java's accessor method (best way)
jCombobox.showPopup(); % equivalent - use Java's direct method
% Hide the popup
set(jCombobox,'PopupVisible',false); % NOT 'off' - this is a Java property, not a Matlab HG one!
jCombobox.PopupVisible = false; % equivalent - access the property directly
jCombobox.setPopupVisible(false); % equivalent - use Java's accessor method (best way)
jCombobox.hidePopup(); % equivalent - use Java's direct method
Note that PopUpVisible is not a Matlab extension – it exists in the original Swing JComboBox
. Unfortunately, it was not included in the list of properties that are exposed to the user by the high-level Matlab uicontrol, so we need to use the underlying Java component.
On a Windows platform the PopupVisible property is toggled, thereby showing/hiding the popup window, whenever the user clicks <Alt-Up> or <Alt-Down> when the combo-box has focus.
The PopupWidthConstrained property (default=false) is a boolean flag which is another Matlab extension to the standard Swing JComboBox
. It is apparently used to constrain the width of the drop-down list to the width of the text field. MathWorks took the trouble to add this feature because Swing JComboBox
‘s width is constrained, causing a difficulty in distinguishing between popup values when the control is relatively narrow; Matlab’s MJComboBox
‘s default unconstrained behavior is much more user-friendly:
>> set(jCombobox,'PopupWidthConstrained',true) ??? Changing the 'PopupWidthConstrained' property of javahandle_withcallbacks.com.mathworks.hg.peer.ComboboxPeer$MLComboBox is not allowed. >> jCombobox.setPopupWidthConstrained(true) ??? No appropriate method or public field setPopupWidthConstrained for class javahandle_withcallbacks.com.mathworks.hg.peer.ComboboxPeer$MLComboBox. >> jCombobox.setConstrainPopupWidth(true) % this is ok
For additional customizations of Matlab comboboxes, refer to section 6.7 of my Matlab-Java programming book [10].
We’re all eagerly awaiting the much-anticipated R2014b release. As you all know, this is an important release with major functionality and engine improvements. It is therefore not surprising that the release date (which should normally have been September 1) is somewhat delayed. MathWorkers are hard at work fixing problems in the pre-release beta. This delay was actually anticipated, as can be seen from the pre-release expiry date.
We should all be patient and let MathWorks fix these issues without pressure. This release could be a real home-run and MathWorks should do all it can to ensure that it works as transparently and as backward-compatible as possible so that it indeed becomes a home run rather than an outfield foul ball. Let’s not have a repeat of R2010b, which required two separate service-pack updates. I urge MathWorks to take their time – better safe than sorry. I urge everyone else to be patient – it’s worth the wait.
When 14b is finally out, I will be here with a planned series of articles explaining how we can make good use of all its new goodies. Start drooling…
Happy Jewish New Year everybody!
Categories: GUI, Java, Medium risk of breaking in future versions, UI controls, Undocumented feature
Article printed from Undocumented Matlab: https://undocumentedmatlab.com
URL to article: https://undocumentedmatlab.com/articles/customizing-combobox-popups
URLs in this post:
[1] custom items in a standard Matlab combobox: http://undocumentedmatlab.com/blog/customizing-listbox-combobox-items
[2] Getting the underlying Java component: http://undocumentedmatlab.com/blog/customizing-combobox-popups#underlying
[3] MaximumRowCount: http://undocumentedmatlab.com/blog/customizing-combobox-popups#MaximumRowCount
[4] PopupVisible: http://undocumentedmatlab.com/blog/customizing-combobox-popups#PopupVisible
[5] PopupWidthConstrained: http://undocumentedmatlab.com/blog/customizing-combobox-popups#PopupWidthConstrained
[6] findjobj utility: http://www.mathworks.com/matlabcentral/fileexchange/14317-findjobj-find-java-handles-of-matlab-graphic-objects
[7] JComboBox
: http://docs.oracle.com/javase/7/docs/api/javax/swing/JComboBox.html
[8] checkClass utility: http://undocumentedmatlab.com/blog/checkclass
[9] javacomponent: http://undocumentedmatlab.com/blog/javacomponent
[10] Matlab-Java programming book: http://undocumentedmatlab.com/matlab-java-book
[11] Customizing listbox/combobox items : https://undocumentedmatlab.com/articles/customizing-listbox-combobox-items
[12] Customizing listbox & editbox scrollbars : https://undocumentedmatlab.com/articles/customizing-listbox-editbox-scrollbars
[13] Customizing figure toolbar background : https://undocumentedmatlab.com/articles/customizing-figure-toolbar-background
[14] Customizing menu items part 3 : https://undocumentedmatlab.com/articles/customizing-menu-items-part-3
[15] Customizing menu items part 2 : https://undocumentedmatlab.com/articles/customizing-menu-items-part-2
[16] Customizing editboxes : https://undocumentedmatlab.com/articles/customizing-editboxes
Click here to print.
Copyright © Yair Altman - Undocumented Matlab. All rights reserved.
8 Comments To "Customizing combobox popups"
#1 Comment By Aurélien On September 24, 2014 @ 06:10
About 14b : it is definitely a major update. I already know that a lot of software here will not migrate into 14b. You were talking about 10b , for us the biggest gap was 11b to 12a (or any newer release) because TMW changed the behavior of matrix functions like setdiff, intersect, union, ismember … (fortunately we have the workaround LEGACY flag like -v6 !!)
I love new features but I hate compatibility issues
Maybe 14b will be alive in a few days before MATLAB Expo 2014 (2nd October @ Paris…and I will be there even if I am from south of France!!)
#2 Comment By oro77 On September 25, 2014 @ 00:44
I agree concerning 14b, I prefer stability, functionability and compabilities support more than new functions.
@Aurélien> More updates of your blog would be welcomed 🙂
#3 Comment By Andras On June 1, 2015 @ 05:58
Dear Yair!
I’ve run into a problem using your findjobj utility, I am trying to build a GUI with several popup menus. I build a popup menu using hComboBox=uicontrol(‘Style’,’popup’,…), but for some reason the findjobj(hComboBox) returns an empty handle. When I do the same in the command window it works perfectly (also when I call: findjobj(‘class’,’MLComboBox’). Is there a reason why is it acting like that when I call the findjobj in a function?
And secondly, why is it that when I declare the same Position property to a Matlab popup menu, and an EditBox, the height of the 2 object differ?
I am using R2014b version.
Thanks, for your reply!
#4 Comment By Yair Altman On June 1, 2015 @ 07:56
@Andras – perhaps the control is not yet visible by the time findjobj is called. Try calling drawnow; pause(0.05); and ensure you are not setting Visible=’off’.
Re the control height, this is how Matlab works internally; the height is automatic and cannot be controlled from Matlab. It is possible (but also not trivial) to do it in Java. You can search for this online.
#5 Comment By Andras On June 2, 2015 @ 01:23
Thanks, for the fast reply.
Sadly neither of those work, I still get an empty handle after calling findjobj.
I dont quite get your second answer, I thought the Position property sets [left bottom width height] the size of the object, but calling a simple JComboBox with javacomponent, or calling an MLComboBox with uicontrol, and then setting their position property to the exact same values, I still get 2 different height.
#6 Comment By Andras On June 2, 2015 @ 01:31
Alright, now I see, so the basic popup menu uicontrol height is not editable.
#7 Comment By Yair Altman On June 2, 2015 @ 01:40
Correct. Try keeping the uicontrol height at its standard value (20px) – maybe that will help findobj() to find it. You don’t care about the height value anyway because as you have seen it does not really affect the actual displayed control height.
#8 Comment By Andras On June 2, 2015 @ 01:46
I try to build my GUI using normalized units to set the position property (to avoid setting the ResizeFcn). My main concern is that there is always a label, and sometimes an editbox also next to the popup, and I need to keep them in the same line, and height, etc … , for the GUI to look OK.