- Undocumented Matlab - https://undocumentedmatlab.com -

Customizing menu items part 1

Posted By Yair Altman On April 25, 2012 | 6 Comments

Over the past years, I have not posted articles dealing with menu items. I have shown how to directly access menu items’ hidden handles [1], but not much more than that. A year ago I promised [2] a mini-series on menu customizations, and it’s time to keep my promise. In today’s article, the first in the mini-series, I will present several undocumented menu customization topics that rely on pure-Matlab (i.e, no Java today). The next article in this series will focus on Java-based customizations.

Invoking menu item callbacks

As noted above, a figure window’s menu items can be directly accessed. Once we access a menu item’s handle, we can extract its Callback property and directly invoke it (for example, using the semi-documented hgfeval function [3]). Note that menu callbacks are kept in Callback, while toolbar callbacks are kept in ClickedCallback.
Menu callbacks generally use internal semi-documented [4] functions (i.e., having a readable help section but no doc, online help, or official support), which are part of Matlab’s uitools folder. These functions are specific to each top-level menu tree: filemenufcn, editmenufcn, viewmenufcn, insertmenufcn, toolsmenufcn, desktopmenufcn, winmenu, and helpmenufcn implement the figure’s eight respective top-level menu trees’ callbacks. These functions accept an optional figure handle (otherwise, gcbf is assumed), followed by a string specifying the specific menu item whose action needs to be run. webmenufcn implements the Help menu’s Web Resources sub-menu callbacks in a similar manner.
Use of these functions makes it easy to invoke a menu action directly from our Matlab code: instead of accessing the relevant menu item and invoking its Callback, we simply find out the menu item string in advance and use it directly. For example,

filemenufcn FileClose;
editmenufcn(hFig,'EditPaste');

uimenufcn is a related fully-undocumented (built-in) function, available since Matlab R11 (late 1990s). It accepts a figure handle (or the zero [0] handle to indicate the desktop) and action name. For example, the fully-documented commandwindow function uses the following code to bring the Command Window into focus:

uimenufcn(0, 'WindowCommandWindow');

Customizing menus via uitools

makemenu is another semi-documented uitool function that enables easy creation of hierarchical menu trees with separators and accelerators. It is a simple and effective wrapper for uimenu. makemenu is a useful function that has been made obsolete (grandfathered) without any known replacement.
makemenu accepts four parameters: a figure handle, a char matrix of labels (‘>’ indicating sub item, ‘>>’ indicating sub-sub items etc.; ‘&’ indicating keyboard shortcut; ‘^x’ indicating an accelerator key; ‘-‘ indicating a separator line), a char matrix of callbacks, and an optional char matrix of tags (empty by default). makemenu makes use of another semi-documented grandfathered function, menulabel, to parse the specified label components. makemenu returns an array of handles of the created uimenu items:

labels = str2mat('&File', ...    % File top menu
           '>&New^n', ...           % File=>New
           '>&Open', ...            % File=>Open
           '>>Open &document^d', ...    % File=>Open=>doc
           '>>Open &graph^g', ...       % File=>Open=>graph
           '>-------', ...          % File=>separator line
           '>&Save^s', ...          % File=>Save
           '&Edit', ...		% Edit top menu
           '&View', ...		% View top menu
           '>&Axis^a', ...          % View=>Axis
           '>&Selection region^r'); % View=>Selection
calls = str2mat('', ...		% no action: File top menu
           'disp(''New'')', ...
           '', ...			% no action: Open sub-menu
           'disp(''Open doc'')', ...
           'disp(''Open graph'')', ...
           '', ...			% no action: Separator
           'disp(''Save'')', ...
           '', ...			% no action: Edit top menu
           '', ...			% no action: View top menu
           'disp(''View axis'')', ...
           'disp(''View selection region'')');
handles = makemenu(hFig, labels, calls);
set(hFig,'menuBar','none');

A simple figure menu
A simple figure menu

Customizing menus via HTML

Since menu items share the same HTML/CSS support feature [5] as all Java Swing labels, we can specify font size/face/color, bold, italic, underline, superscript/subscript, and practically any HTML formatting.
Note that some features, such as the font or foreground/background colors, have specific properties that we can set using the Java handle, instead of using HTML. The benefit of using HTML is that it enables setting all the formatting in a single property. HTML does not require using Java – just pure Matlab (see the following example).
Multi-line menu items can easily be done with HTML: simply include a <br> element in the label – the menu item will split into two lines and automatically resize vertically when displayed:

txt1 = 'Save';
txt2 = 'this file';
txt3 = '
this file as...'; set(findall(hFig,'tag','figMenuFileSave'), 'Label',[txt1,txt2]); set(findall(hFig,'tag','figMenuFileSaveAs'), 'Label',[txt1,txt3]);

A multi-line HTML-rendered menu item
A multi-line HTML-rendered menu item

set(hMenuItem, 'Label',['&2: C:\My Documents\doc.txt
' '   ' 'Date: 15-Jun-2011 13:23:45
   Size: 123 KB
']);

HTML-rendered menu items
HTML-rendered menu items

Much more complex customizations can be achieved using Java. So stay tuned to part 2 of this mini-series…
Note: Menu customization is explored in depth in section 4.6 of my book [6].

Categories: Figure window, GUI, Low risk of breaking in future versions, Semi-documented function


6 Comments (Open | Close)

6 Comments To "Customizing menu items part 1"

#1 Comment By quant On April 26, 2012 @ 13:55

HI Yair,
not related to this post, but was curious if you
Have you ever worked on the solution to this :

[13]

#2 Comment By Yair Altman On April 26, 2012 @ 14:08

no…

#3 Comment By Malcolm Lidierth On April 28, 2012 @ 05:26

It is not a bug, it is expected behaviour

firstfunction accepts a copy of a MATLAB double array, modifies that copy and returns without altering anything in the MyClass instance.

secondfunction gets a reference to a java.lang.Double array as input- so MATLAB sees the changes made to that object

#4 Comment By Yair Altman On April 28, 2012 @ 10:14

@Malcolm, I believe the OP does not dispute the fact that this is the expected behavior, he/she was simply asking whether there is any way to circumvent or modify this behavior. I do not know of any, but this is not saying that there isn’t any…

#5 Pingback By Customizing menu items part 2 | Undocumented Matlab On May 2, 2012 @ 04:57

[…] Last week I explained how to customize Matlab’s menu items using some undocumented tricks that do not need Java […]

#6 Pingback By Customizing the standard figure toolbar, menubar | Undocumented Matlab On January 9, 2013 @ 13:02

[…] We can take this idea even further by employing HTML formatting, as I have shown in my first article of the menubar mini-series: HTML-rendered menu items […]

#7 Comment By Yaroslav On September 9, 2019 @ 16:45

Hi Yair,

Do you know how to add a separator to a pop-up control (combo box)? I tried:

hPopup     = uicontrol('Style','popup','String',{'A','B','C'});
jCombobox  = findjobj(hPopup);
jSeparator = javax.swing.JSeparator(javax.swing.JSeparator.HORIZONTAL);
%
jCombobox.addItem(jSeparator);

But, alas, it didn’t work as expected (it added jSeparator.toString() instead). Where did I go wrong?

Kindest regards, Yaroslav

#8 Comment By Yair Altman On September 10, 2019 @ 13:26

@Yaroslav – instead of customizing the built-in Matlab uicontrol, create a standard javax.swing.JComboBox (where adding a JSeparator is easy), then add it to your figure window using javacomponent.

#9 Comment By Yaroslav On September 10, 2019 @ 20:52

Hi Yair,

Unfortunately, javacomponent did not solve the problem. The culprit is actually the renderer, as suggested [14]. After installing the java classes SeparatorComboBoxRenderer and SeparatorComboBoxListener therein (with slight adjustments), the following modification worked:

sep_txt    = '--------';
hPopup     = uicontrol('Style','popup','String',{'A','B',sep_txt,'C'});
%
jCombobox  = findjobj(hPopup);
jSeparator = javax.swing.JSeparator();
%
jCombobox.setRenderer(SeparatorComboBoxRenderer());
jCombobox.addActionListener(SeparatorComboBoxListener(jCombobox));
%
jCombobox.insertItemAt(jSeparator,2);
jCombobox.removeItemAt(3);  % this is required to keep the indices valid

A similar version with javax.swing.JComboBox and javacomponent also worked.

In any case, I thank you for the prompt response and the recommendation to work directly with java. It gave me the motivation to dig into some java code and find the solution.

Kindest regards, Yaroslav

#10 Comment By Yair Altman On September 10, 2019 @ 21:01

A simple alternative that does not require any Java is to use simple HTML. For example:

uicontrol('Style','popup', 'String',{'A', 'B
', 'C'});

Article printed from Undocumented Matlab: https://undocumentedmatlab.com

URL to article: https://undocumentedmatlab.com/articles/customizing-menu-items-part-1

URLs in this post:

[1] directly access menu items’ hidden handles: http://undocumentedmatlab.com/blog/modifying-default-toolbar-menubar-actions/

[2] promised: http://undocumentedmatlab.com/blog/2010-perspective/

[3] hgfeval function: http://undocumentedmatlab.com/blog/hgfeval/

[4] semi-documented: http://undocumentedmatlab.com/blog/legend-semi-documented-feature/#Semi-documented

[5] HTML/CSS support feature: http://undocumentedmatlab.com/blog/html-support-in-matlab-uicomponents/

[6] book: http://undocumentedmatlab.com/matlab-java-book/

[7] Customizing menu items part 2 : https://undocumentedmatlab.com/articles/customizing-menu-items-part-2

[8] Customizing menu items part 3 : https://undocumentedmatlab.com/articles/customizing-menu-items-part-3

[9] Customizing listbox/combobox items : https://undocumentedmatlab.com/articles/customizing-listbox-combobox-items

[10] Customizing uitree nodes – part 1 : https://undocumentedmatlab.com/articles/customizing-uitree-nodes

[11] Customizing the standard figure toolbar, menubar : https://undocumentedmatlab.com/articles/customizing-standard-figure-toolbar-menubar

[12] Customizing uitree : https://undocumentedmatlab.com/articles/customizing-uitree

[13] : http://stackoverflow.com/questions/5554518/can-matlab-not-read-back-a-double-array-from-java

[14] : http://esus.com/creating-a-jcombobox-with-a-divider-separator-line/

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.