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

uisplittool & uitogglesplittool callbacks

December 15, 2010 3 Comments

Last week, I presented the undocumented uisplittool and uitogglesplittool functions and showed how they can be added to a Matlab figure toolbar. Today I wish to conclude this topic by explaining how these controls can be customized with user-defined callbacks and pop-up menus.

Callback functionality

Both uisplittool and uitogglesplittool have a Callback property, in addition to the standard ClickedCallback property that is available in uipushtools and uitoggletools.
The standard ClickedCallback is invoked when the main button is clicked, while Callback is invoked when the narrow arrow button is clicked. uitogglesplittool, like uitoggletool, also has settable OnCallback and OffCallback callback properties.
The accepted convention is that ClickedCallback should invoke the default control action (in our case, an Undo/Redo of the topmost uiundo action stack), while Callback should display a drop-down of selectable actions.
While this can be done programmatically using the Callback property, this functionality is already pre-built into uisplittool and uitogglesplittool for our benefit. To access it, we need to get the control’s underlying Java component.
Accessing the underlying Java component is normally done using the findjobj utility, but in this case we have a shortcut: the control handle’s hidden JavaContainer property that holds the underlying com.mathworks.hg.peer.SplitButtonPeer (or .ToggleSplitButtonPeer) Java reference handle. This Java object’s MenuComponent property returns a reference to the control’s drop-down sub-component (which is a com.mathworks.mwswing.MJPopupMenu object):

>> jUndo = get(hUndo,'JavaContainer')
jUndo =
com.mathworks.hg.peer.SplitButtonPeer@f09ad5
>> jMenu = get(jUndo,'MenuComponent')  % or: =jUndo.getMenuComponent
jMenu =
com.mathworks.mwswing.MJPopupMenu[Dropdown Picker ButtonMenu,...]

>> jUndo = get(hUndo,'JavaContainer') jUndo = com.mathworks.hg.peer.SplitButtonPeer@f09ad5 >> jMenu = get(jUndo,'MenuComponent') % or: =jUndo.getMenuComponent jMenu = com.mathworks.mwswing.MJPopupMenu[Dropdown Picker ButtonMenu,...]

Let’s add a few simple textual options:

jOption1 = jMenu.add('Option #1');
jOption1 = jMenu.add('Option #2');
set(jOption1, 'ActionPerformedCallback', 'disp(''option #1'')');
set(jOption2, 'ActionPerformedCallback', {@myCallbackFcn, extraData});

jOption1 = jMenu.add('Option #1'); jOption1 = jMenu.add('Option #2'); set(jOption1, 'ActionPerformedCallback', 'disp(''option #1'')'); set(jOption2, 'ActionPerformedCallback', {@myCallbackFcn, extraData});

setting uisplittool & uitogglesplittool popup-menus
setting uisplittool & uitogglesplittool popup-menus

Popup-menus are described in more detail elsewhere (and in future articles). In the past I have already explained how icons and HTML markup can be added to menu items. Sub-menus can also be added.

A complete example

Let’s now use this information, together with last year’s set of articles about Matlab’s undocumented uiundo functionality, to generate a complete and more realistic example, of undo/redo toolbar buttons.
Undo and redo are actions that are particularly suited for uisplittool, since its main button enables us to easily undo/redo the latest action (like a simple toolbar button, by clicking the main uisplittool button) as well as select items from the actions drop-down (like a combo-box, by clicking the attached arrow button) – all this using a single component.

% Display our GUI
hEditbox = uicontrol('style','edit', 'position',[20,60,40,40]);
set(hEditbox, 'Enable','off', 'string','0');
hSlider = uicontrol('style','slider','userdata',hEditbox);
set(hSlider,'Callback',@test_uiundo);
% Display the figure toolbar that was hidden by the uicontrol function
set(gcf,'Toolbar','figure');
% Add the Undo/Redo buttons
hToolbar = findall(gcf,'tag','FigureToolBar');
hUndo = uisplittool('parent',hToolbar);
hRedo = uitogglesplittool('parent',hToolbar);
% Load the Redo icon
icon = fullfile(matlabroot,'/toolbox/matlab/icons/greenarrowicon.gif');
[cdata,map] = imread(icon);
% Convert white pixels into a transparent background
map(find(map(:,1)+map(:,2)+map(:,3)==3)) = NaN;
% Convert into 3D RGB-space
cdataRedo = ind2rgb(cdata,map);
cdataUndo = cdataRedo(:,[16:-1:1],:);
% Add the icon (and its mirror image = undo) to latest toolbar
set(hUndo, 'cdata',cdataUndo, 'tooltip','undo','Separator','on', ...
           'ClickedCallback','uiundo(gcbf,''execUndo'')');
set(hRedo, 'cdata',cdataRedo, 'tooltip','redo', ...
           'ClickedCallback','uiundo(gcbf,''execRedo'')');
% Re-arrange the Undo/Redo buttons
jToolbar = get(get(hToolbar,'JavaContainer'),'ComponentPeer');
jButtons = jToolbar.getComponents;
for buttonIdx = length(jButtons)-3 : -1 : 7  % end-to-front
   jToolbar.setComponentZOrder(jButtons(buttonIdx), buttonIdx+1);
end
jToolbar.setComponentZOrder(jButtons(end-2), 5);    % Separator
jToolbar.setComponentZOrder(jButtons(end-1), 6);    % Undo
jToolbar.setComponentZOrder(jButtons(end), 7);      % Redo
jToolbar.revalidate;
% Retrieve redo/undo object
undoObj = getappdata(gcf,'uitools_FigureToolManager');
if isempty(undoObj)
   undoObj = uitools.FigureToolManager(gcf);
   setappdata(gcf,'uitools_FigureToolManager',undoObj);
end
% Populate Undo actions drop-down list
jUndo = get(hUndo,'JavaContainer');
jMenu = get(jUndo,'MenuComponent');
undoActions = get(undoObj.CommandManager.UndoStack,'Name');
jMenu.removeAll;
for actionIdx = length(undoActions) : -1 : 1    % end-to-front
    jActionItem = jMenu.add(undoActions(actionIdx));
    set(jActionItem, 'ActionPerformedCallback', @myUndoCallbackFcn);
end
jToolbar.revalidate;
% Drop-down callback function
function myUndoCallbackFcn(jActionItem,hEvent)
    % user processing needs to be placed here
end  % myUndoCallbackFcn

% Display our GUI hEditbox = uicontrol('style','edit', 'position',[20,60,40,40]); set(hEditbox, 'Enable','off', 'string','0'); hSlider = uicontrol('style','slider','userdata',hEditbox); set(hSlider,'Callback',@test_uiundo); % Display the figure toolbar that was hidden by the uicontrol function set(gcf,'Toolbar','figure'); % Add the Undo/Redo buttons hToolbar = findall(gcf,'tag','FigureToolBar'); hUndo = uisplittool('parent',hToolbar); hRedo = uitogglesplittool('parent',hToolbar); % Load the Redo icon icon = fullfile(matlabroot,'/toolbox/matlab/icons/greenarrowicon.gif'); [cdata,map] = imread(icon); % Convert white pixels into a transparent background map(find(map(:,1)+map(:,2)+map(:,3)==3)) = NaN; % Convert into 3D RGB-space cdataRedo = ind2rgb(cdata,map); cdataUndo = cdataRedo(:,[16:-1:1],:); % Add the icon (and its mirror image = undo) to latest toolbar set(hUndo, 'cdata',cdataUndo, 'tooltip','undo','Separator','on', ... 'ClickedCallback','uiundo(gcbf,''execUndo'')'); set(hRedo, 'cdata',cdataRedo, 'tooltip','redo', ... 'ClickedCallback','uiundo(gcbf,''execRedo'')'); % Re-arrange the Undo/Redo buttons jToolbar = get(get(hToolbar,'JavaContainer'),'ComponentPeer'); jButtons = jToolbar.getComponents; for buttonIdx = length(jButtons)-3 : -1 : 7 % end-to-front jToolbar.setComponentZOrder(jButtons(buttonIdx), buttonIdx+1); end jToolbar.setComponentZOrder(jButtons(end-2), 5); % Separator jToolbar.setComponentZOrder(jButtons(end-1), 6); % Undo jToolbar.setComponentZOrder(jButtons(end), 7); % Redo jToolbar.revalidate; % Retrieve redo/undo object undoObj = getappdata(gcf,'uitools_FigureToolManager'); if isempty(undoObj) undoObj = uitools.FigureToolManager(gcf); setappdata(gcf,'uitools_FigureToolManager',undoObj); end % Populate Undo actions drop-down list jUndo = get(hUndo,'JavaContainer'); jMenu = get(jUndo,'MenuComponent'); undoActions = get(undoObj.CommandManager.UndoStack,'Name'); jMenu.removeAll; for actionIdx = length(undoActions) : -1 : 1 % end-to-front jActionItem = jMenu.add(undoActions(actionIdx)); set(jActionItem, 'ActionPerformedCallback', @myUndoCallbackFcn); end jToolbar.revalidate; % Drop-down callback function function myUndoCallbackFcn(jActionItem,hEvent) % user processing needs to be placed here end % myUndoCallbackFcn

undo/redo buttons implemented using uisplittool
undo/redo buttons implemented using uisplittool

In a real-world application, the code-segment above that populated the drop-down list would be placed within the slider’s test_uiundo() callback function, and we would set a similar drop-down for the hRedu button. In addition, we would dynamically modify the button tooltips. As a final customization, we could modify the figure’s main menu. Menu customization will be discussed in a future separate set of articles.
Have you used uisplittool or uitogglesplittool in your GUI? If so, please tell us what use you have made of them, in a comment below.

Related posts:

  1. uisplittool & uitogglesplittool – Matlab's undocumented uisplittool and uitogglesplittool are powerful controls that can easily be added to Matlab toolbars - this article explains how...
  2. 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....
  3. Matlab callbacks for Java events – Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...
  4. Enabling user callbacks during zoom/pan – Matlab zoom, pan and rotate3d modes hijack the user's figure callbacks, but this can be overridden. ...
  5. Matlab callbacks for Java events in R2014a – R2014a changed the way in which Java objects expose events as Matlab callbacks. ...
  6. Uicontrol callbacks – This post details undocumented callbacks exposed by the underlying Java object of Matlab uicontrols, that can be used to modify the control's behavior in a multitude of different events...
Callbacks Hidden property Java Toolbar uitools uiundo Undocumented function
Print Print
« Previous
Next »
3 Responses
  1. Chris July 30, 2011 at 19:21 Reply

    Hello Yair,

    this site is great!

    I am using the togglesplittool in my GUI. First I had problems, Matlab 2010a shutting down. I was able to solve this by putting a “pause(0.01)” before calling “get(hUndo,’JavaContainer’)”.

    You know a way to put a sign like you have on uimenus by setting the ‘checked’-property to ‘on’?

    Greetings Chris

    • Yair Altman July 30, 2011 at 23:32 Reply

      @Chris – I don’t follow you: where do you want the check sign and under which conditions do you want it to appear/disappear?

  2. Chris July 31, 2011 at 00:19 Reply

    Exactly, i give different options the user can choose from the togglesplittool associated drop-down-menu. After choosing one can click the togglebutton. Now it would be nice if the user can see the actually selected option. This i would like to do by putting a sign check to the last selected option from the drop-down-menu. I hope you got what i mean?

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