Did you ever wish to modify Matlab’s default toolbar/menubar items?
I recently consulted to a client who needed to modify the default behavior of the legend action in the toolbar, and the corresponding item on the main menu (Insert / Legend). The official version is that only user-added items can be customized, whereas standard Matlab items cannot.
Luckily, this can indeed be done using simple pure-Matlab code. The trick is to get the handles of the toolbar/menubar objects and then to modify their callback properties.
Using the toolbar/menubar item handles
Getting the handles can be done in several different ways. In my experience, using the object’s tag string is often easiest, fastest and more maintainable. Note that the Matlab toolbar and main menu handles are normally hidden (HandleVisibility = ‘off’). Therefore, in order to access them we need to use the findall function rather than the better-known findobj function. Also note that to set the callbacks we need to access differently-named properties: ClickedCallback for toolbar buttons, and Callback for menu items:
hToolLegend = findall(gcf,'tag','Annotation.InsertLegend'); set(hToolLegend, 'ClickedCallback',{@cbLegend,hFig,myData}); hMenuLegend = findall(gcf,'tag','figMenuInsertLegend'); set(hMenuLegend, 'Callback',{@cbLegend,hFig,myData}); |
As a side note, two undocumented/unsupported functions, uitool(hFig,tagName) and uigettoolbar, also retrieve toolbar items. Since using findall is so simple and more supported, I suggest using the findall approach.
To see the list of available toolbar/menubar tags, use the following code snippet:
% Toolbar tag names: >> hToolbar = findall(gcf,'tag','FigureToolBar'); >> get(findall(hToolbar),'tag') ans = 'FigureToolBar' 'Plottools.PlottoolsOn' 'Plottools.PlottoolsOff' 'Annotation.InsertLegend' 'Annotation.InsertColorbar' 'DataManager.Linking' 'Exploration.Brushing' 'Exploration.DataCursor' 'Exploration.Rotate' 'Exploration.Pan' 'Exploration.ZoomOut' 'Exploration.ZoomIn' 'Standard.EditPlot' 'Standard.PrintFigure' 'Standard.SaveFigure' 'Standard.FileOpen' 'Standard.NewFigure' '' % Menu-bar tag names: >> get(findall(gcf,'type','uimenu'),'tag') ans = 'figMenuHelp' 'figMenuWindow' 'figMenuDesktop' 'figMenuTools' 'figMenuInsert' 'figMenuView' 'figMenuEdit' 'figMenuFile' 'figMenuHelpAbout' 'figMenuHelpPatens' 'figMenuHelpTerms' 'figMenuHelpActivation' 'figMenuDemos' 'figMenuTutorials' 'figMenuHelpUpdates' 'figMenuGetTrials' 'figMenuWeb' 'figMenuHelpPrintingExport' 'figMenuHelpAnnotatingGraphs' 'figMenuHelpPlottingTools' 'figMenuHelpGraphics' '' '' < = Note the missing tag names... '' 'figMenuToolsBFDS' <= note the duplicate tag names... 'figMenuToolsBFDS' 'figDataManagerBrushTools' 'figMenuToolsAlign' 'figMenuToolsAlign' ... (plus many many more...) |
Unfortunately, as seen above, Matlab developers forgot to assign tags to some default toolbar/menubar items. Luckily, in my particular case, both legend handles (toolbar, menu) have valid tag names that can be used: ‘Annotation.InsertLegend’ and ‘figMenuInsertLegend’.
If an item’s tag is missing, you can always find its handle using its Parent, Label, Tooltip or Callback properties. For example:
hPrintMenuItem = get(findall(gcf,'Label','&Print...')); |
Note that property values, such as the tag names or labels, are unsupported and undocumented. They may change without warning or notice between Matlab releases, and have indeed done so in the past. Therefore, if your code needs to be compatible with older Matlab releases, ensure that you cover all the possible property values, or use a different way to access the handles. While using the tag name or label as shown above is considered “Low risk” (I don’t expect it to break in the near future), their actual values should be considered somewhat more risky and we should therefore code defensively.
Another simple example: Print Preview
As another simple and very useful example, let’s modify the default Print action (and tooltip) on the figure toolbar to display the Print-Preview window rather than send the figure directly to the printer:
hToolbar = findall(gcf,'tag','FigureToolBar'); hPrintButton = findall(hToolbar,'tag','Standard.PrintFigure'); set(hPrintButton, 'ClickedCallback','printpreview(gcbf)', 'TooltipString','Print Preview'); |
More advanced customization of the toolbar and menu items are possible, but require a bit of Java code. Examples of toolbar customizations were presented in past articles (here and here). A future article will explain how to customize menu items.
Have you found a nifty way to customize the menubar or toolbar? If so, please share it in the comments section below.
Hello Yair!
I would like to ask you in what way I can alter the Standard.PrintFigure properties so as to be valid for every figure window and not only for the current one(gcf).
Like getting assimilated into the default figure toolbar.
Thank you for your help.
@lux – there is no official way to do this, but of course (as always) there’s a back-door: you can simply add your code to the printdlg.m file. This will get executed whenever the user tries to print any figure.
In Matlab releases up to R2009b you can add your code to the built-in figureToolbarCreateFcn.m function. Unfortunately, this back-door was closed in R2010a onward…
You should also take a look at http://undocumentedmatlab.com/blog/customizing-print-setup/, which explains how to programmatically modify the default print setup.
Hello Yair,
Is there a way of performing these sort of modifications on the main Matlab toolbar rather than on figure toolbars.
Thanks for your help
@Andi – Of course you can modify the main Matlab desktop toolbar, just like a figure toolbar. Here is one way to get a reference to the toolbar container, which is a standard
com.mathworks.mwswing.MJToolBar
object:You may of need to adapt the code for docking etc., but this should be enough to get you started.
Is there a way to get a cut push button to my figure?
@klimmbimm – adding simple buttons to the figure toolbar can be done using the uipushtool function
[…] I need to manually remove several unuseful toolbar controls. I do this by directly accessing the toolbar control handles […]
[…] image to a Matlab variable (2D RGB image), an image file, system clipboard, or the printer. We can easily modify the <Print> toolbar button and menu item to use this utility rather than the builtin print function:Matlab's default toolbar Print […]
Hi,
My problem is: after clicking on brushing tool, I select data by dragging over the data-points. Now, when I right click it gives me a 5 to 6 options: remove data, replace with , delete create variables etc. Can I customize these options and create callbacks for these options? because I don’t want all these options in my objective.
with regards,
Akshay Kumar