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

Listbox layout customization

November 13, 2013 14 Comments

I haven’t written on listboxes in a long while, and since I’ve recently posted on related controls (editbox, combo-box), I thought of following up with an article on customizing Matlab listbox layout. By the end of today’s article, you should be able to customize the layout of items within your listbox, such as the following:

Customized listbox layout   Customized listbox layout
Customized listbox layouts


For the following hacks, we need to gain access to the listbox control’s underlying Java component, which is a MathWorks class that extends the standard JList. We can get this component’s reference using the findjobj utility:

>> hListbox = uicontrol('Style','List', 'String',{'item #1','item #2'});
>> jScrollPane = java(findjobj(hListbox))
jScrollPane =
com.mathworks.hg.peer.utils.UIScrollPane[...]
>> jListbox = jScrollPane.getViewport.getView
jListbox =
com.mathworks.hg.peer.ListboxPeer$UicontrolList[...]

>> hListbox = uicontrol('Style','List', 'String',{'item #1','item #2'}); >> jScrollPane = java(findjobj(hListbox)) jScrollPane = com.mathworks.hg.peer.utils.UIScrollPane[...] >> jListbox = jScrollPane.getViewport.getView jListbox = com.mathworks.hg.peer.ListboxPeer$UicontrolList[...]

Like multi-line editboxes, listboxes are actually composed of a container (a com.mathworks.hg.peer.utils.UIScrollPane object) that includes three children, as expected from any JScrollPane: a javax.swing.JViewport that contains the ListboxPeer$UicontrolList component, and horizontal/vertical scrollbars. I explained how to customize the scrollbars in an article back in early 2010.
Today we are not interested in the scroll-pane or scollbars, but rather the jListbox component that takes up the view-port’s contents. This component includes many useful properties that we can access and modify, including several that control the layout of the list items:
LayoutOrientation sets the layout of listbox items within the viewport. Possible values include:

  • The default value (jListbox.VERTICAL=0) indicates the regular top-to-bottom arrangement
  • jListbox.VERTICAL_WRAP=1 sets a horizontal item layout, wrapping to a new row as necessary for the maximum number of rows determined by the VisibleRowCount property (default=8)
  • jListbox.HORIZONTAL_WRAP=2 sets a vertical item layout, wrapping to a new column at row number VisibleRowCount

For example:

jListbox.setLayoutOrientation(jListbox.HORIZONTAL_WRAP);
jListbox.setVisibleRowCount(3);
set(jListbox, 'LayoutOrientation',2, 'VisibleRowCount',3);  % equivalent alternative

jListbox.setLayoutOrientation(jListbox.HORIZONTAL_WRAP); jListbox.setVisibleRowCount(3); set(jListbox, 'LayoutOrientation',2, 'VisibleRowCount',3); % equivalent alternative


LayoutOrientation = VERTICAL = 0
VisibleRowCount is irrelevant

LayoutOrientation = VERTICAL_WRAP = 1
VisibleRowCount = 3

LayoutOrientation = HORIZONTAL_WRAP = 2
VisibleRowCount = 3

FixedCellHeight and FixedCellWidth hold the listbox’s cells height (default=13 pixels) and width (default=-1). A value of -1 means that the actual size is determined by the default platform-dependent CellRenderer size:


FixedCellHeight = -1
FixedCellWidth = -1

FixedCellHeight = 10
FixedCellWidth = 30

FixedCellHeight = 16
FixedCellWidth = 50

We can use these properties to display a selection matrix of icons. For example, let’s display the icons in Matlab standard icons folder:

% Prepare the list of ImageIcon objects
iconsFolder = fullfile(matlabroot,'toolbox/matlab/icons');
imgs = dir(fullfile(iconsFolder,'*.gif'));
for iconIdx = 1 : length(imgs)
   iconFilename = fullfile(iconsFolder,imgs(iconIdx).name);
   iconFilename = strrep(iconFilename, '\', '/');
   htmlStr{iconIdx} = ['<html><img src="file:/' iconFilename '"/>'];  % no need for </html>
end
% Display in a standard one-column listbox
hListbox = uicontrol('style','list', 'string',htmlStr, 'position',[10,10,160,90]);
% Modify the listbox layout to display 18x18-pixel cells
jScrollPane = findjobj(hListbox);
jListbox = jScrollPane.getViewport.getView;
jListbox.setLayoutOrientation(jListbox.HORIZONTAL_WRAP)
jListbox.setVisibleRowCount(4)
jListbox.setFixedCellWidth(18)   % icon width=16  + 2px margin
jListbox.setFixedCellHeight(18)  % icon height=16 + 2px margin
jListbox.repaint  % refresh the display

% Prepare the list of ImageIcon objects iconsFolder = fullfile(matlabroot,'toolbox/matlab/icons'); imgs = dir(fullfile(iconsFolder,'*.gif')); for iconIdx = 1 : length(imgs) iconFilename = fullfile(iconsFolder,imgs(iconIdx).name); iconFilename = strrep(iconFilename, '\', '/'); htmlStr{iconIdx} = ['<html><img src="file:/' iconFilename '"/>']; % no need for </html> end % Display in a standard one-column listbox hListbox = uicontrol('style','list', 'string',htmlStr, 'position',[10,10,160,90]); % Modify the listbox layout to display 18x18-pixel cells jScrollPane = findjobj(hListbox); jListbox = jScrollPane.getViewport.getView; jListbox.setLayoutOrientation(jListbox.HORIZONTAL_WRAP) jListbox.setVisibleRowCount(4) jListbox.setFixedCellWidth(18) % icon width=16 + 2px margin jListbox.setFixedCellHeight(18) % icon height=16 + 2px margin jListbox.repaint % refresh the display

Customized listbox layout
Customized listbox layout

Other interesting things that we can do with listboxes (among others):

  • Customize the scrollbars, as noted above
     
  • Display HTML-formatted list items:
    uicontrol('Style','list', 'Position',[10,10,70,70], 'String', ...
       {'<html><font color="red">Hello</font></html>', 'world', ...
        '<html><font style="font-family:impact;color:green"><i>What a', ...   % note: </i></font></html> are not needed
        '<html><font color="blue" face="Comic Sans MS">nice day!</font>'});   % note: </html> is not needed

    uicontrol('Style','list', 'Position',[10,10,70,70], 'String', ... {'<html><font color="red">Hello</font></html>', 'world', ... '<html><font style="font-family:impact;color:green"><i>What a', ... % note: </i></font></html> are not needed '<html><font color="blue" face="Comic Sans MS">nice day!</font>'}); % note: </html> is not needed

    Listbox with HTML'ed items
    Listbox with HTML colored items
  • Setting dynamic tooltips and right-click context-menus:
    Listbox dynamic tooltip
    Listbox dynamic tooltip
       
    Listbox dynamic context (right-click) menu
    Listbox dynamic context (right-click) menu

Note that while the code above used the underlying Java component, absolutely no knowledge of Java is required to understand it or use it. In fact, the entire code above is pure Matlab, simply setting the component’s properties and calling its methods, and using its inherent support of HTML strings.
Much more advanced customizations are possible at the Java level, especially using a dedicated CellRenderer. 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.
If you’d like me to personally add similar magic to your GUI, email me to see if I can help.

Advanced listbox CellRenderer customization
Advanced listbox CellRenderer customization

Now tell the truth – doesn’t Matlab’s standard listbox look kinda boring after all this? 🙂

Related posts:

  1. Setting listbox mouse actions – Matlab listbox uicontrol can be modified to detect mouse events for right-click context menus, dynamic tooltips etc....
  2. Customizing listbox & editbox scrollbars – Matlab listbox and multi-line editbox uicontrols have pre-configured scrollbars. This article shows how they can be customized....
  3. Customizing listbox/combobox items – Matlab listboxes can be customized using custom Java cell-renderers. ...
  4. Listbox selection hacks – Matlab listbox selection can be customized in a variety of undocumented ways. ...
  5. Smart listbox & editbox scrollbars – Matlab listbox and multi-line editbox scrollbars can easily be made smarter, for improved appearance. ...
  6. Button customization – Matlab's button uicontrols (pushbutton and togglebutton) are basically wrappers for a Java Swing JButton object. This post describes how the buttons can be customized using this Java object in ways that are impossible using pure Matlab....
FindJObj GUI Java uicontrol
Print Print
« Previous
Next »
14 Responses
  1. Robert Cumming November 14, 2013 at 10:56 Reply

    Yair,

    Excellent stuff

    I don’t know if you’ve seen the FEX utility which I created which uses some of the items I learn’t on your site about formating and customising listboxes?

    The utility uses pure matlab code with an API to make multi column (formatable) listboxes.

    Regards

    • Yair Altman November 14, 2013 at 16:00 Reply

      @Robert – I haven’t seen it until now, but it looks impressive…
      uimulticollist FEX utility

  2. michael March 22, 2014 at 09:44 Reply

    Hi Yair,

    thanks for this powerful tips and tricks, so far i was not a big fan of Matlab mainly because of very limited GUI functions, but now i start to believe in it.
    I ordered your book, meanwhile i have a few questions if you don’t mind me to ask:
    – is that possible to have a listbox with Popup menu and submenu to give options on Font/ color…
    – i can not find how to change list row color with Javax.
    rgds,
    Michael

    • Yair Altman March 22, 2014 at 10:02 Reply

      @Michael –

      1) you can set the UIContextMenu property of the listbox with whatever functionality that you wish – see the documentation.

      2) you can use HTML formatting for this – see here.

      • Michael March 22, 2014 at 15:29

        Hi Yair,
        I’m already using javax to customize the ListBox and other uicontrol …..is there any way to add popup menu and submenu with javax ? same for change listbox row color.

        rgds,
        Michael

      • Yair Altman March 22, 2014 at 15:37

        Of course you can do all that in Java (I don’t know why you call it javax), it’s called a JPopupMenu. But this is a Matlab blog, not a Java blog. So if you insist in using Java for this then I suggest that you check one of the numerous Java resources, either online or offline (books). You can start here.

  3. Sebastian February 26, 2019 at 14:32 Reply

    I have an issue here. I also use a Listbox with HTML code in it, and my figure resizes the listbox whenever the figure size is changed. Now it seems that the value set with ‘setFixedCellHeight’ is reset after resizing. Do you have an idea why?

    And something else: On a colleagues PC the HTML text is cut-off at the bottom. Now I found out that he is using a larger Windows font size. Do you have an idea how to detect the needed list item height depending on the used default font?

    Best regards,
    Sebastian

    • Yair Altman February 26, 2019 at 14:53 Reply

      The component is reset/repainted by Matlab when it determines that a component resize is required. You can trap this in the containing panel’s SizeChangedFcn or possibly the Java component’s ComponentResizedCallback callbacks, where you can reapply all the customizations.

      Regarding the font size, you can use the Java FontMetrics class to get the necessary information (details)

    • Sebastian February 28, 2019 at 16:31 Reply

      Oh all right. I thought I did something wrong and the settings should be consistent after repaints.

      Also the FontMetrics class works like a charm. Thanks a lot for your quick help!

    • Alex August 11, 2019 at 10:39 Reply

      Hi Yair,
      I am having a similar issue with Sebastian, for my GUI, I need to add/remove elements to the listbox interactively, causing the cell height to be reverted. I believe this is because MATLAB doesn’t have an addElement method for UIControls, meaning that the listbox needs to be redrawn everytime listbox.String is updated, resetting to the default MATLAB values for cell height and width. I can call ‘setFixedCellHeight’ for every callback that changes the listbox, but this causes flickering and you can see the cells change size everytime it is updated, do you have any suggestions for avoiding this issue?

      Thanks

    • Alex August 11, 2019 at 10:49 Reply

      Hi Yair,
      I am having a similar issue to Sebastian, where cell height is reset when listbox.String is updated. I believe MATLAB redraws the listbox whenever the String field is updated, as it doesn’t provide a ‘addElement’ method. I can manually use ‘setFixedCellHeight’ in callbacks following an update of the elements of the listbox, but the resize down to default and the resize back to the fixed height is clearly visible as a flicker, I am wondering if you have any suggestions in fixing this problem?

      I tried using the addElement method of the DefaultListModel used in the listbox, but the ListModel is tied to updates in listbox.String field, rather than the other way around.

      Many thanks,
      Alex

      • Yair Altman August 11, 2019 at 11:50

        There is no simple solution. I think that if you call setFixedCellHeight immediately after updating the String property, without an intervening drawnow or repaint, then there should be no flicker. The flicker indicates that one or both of drawnow or repaint are being called between these two actions.

    • Alex August 13, 2019 at 02:59 Reply

      Hi Yair,
      Thanks for your response. Annoyingly, and somewhat interestingly, a String update immediately followed by a setFixedCellHeight means that the listbox does NOT update its height at all, if you call getFixedCellHeight the value is still the default MATLAB value. I am not sure why this is.
      One way to I found reduce to the flicker is adding a pause(0.01) before setFixedCellHeight call, which does allow the cell height to be set, but it isn’t much of a solution.

      • Yair Altman August 15, 2019 at 23:54

        Alex – the reason is probably that when updating the String property, the Matlab engine places a call to setFixedCellHeight (or some other method that eventually sets the cell height) on the Event Dispatch (EDT queue), and this gets executed in a separate thread asynchronously, a few millisecs later. So if you directly call setFixedCellHeight after setting String, your call is being overridden by the EDT call a few millisecs later and only then the listbox gets repainted, so in the end you see no visible change.
        When you add a pause(0.01) before setFixedCellHeight, the EDT call gets executed before your direct call, and so this does produce the requested effect, but due to the intervening listbox repaint you will necessarily see a flicker.

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
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) uitable (6) uitools (20) Undocumented feature (187) Undocumented function (37) Undocumented property (20)
Recent Comments
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