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

Matlab toolstrip – part 2 (ToolGroup App)

December 5, 2018 17 Comments

A while ago I posted the first of my planned miniseries on the Matlab toolstrip (ribbon). Today I will expand that post by discussing how toolstrips can be added to Matlab GUIs. This post will remain at a high-level as the previous post, with followup posts drilling into the technical details of the toolstrip components (inner packages and classes).
We can add a Matlab toolstrip to 3 types of Matlab GUI windows:

  1. To a Java-based Matlab figure (so-called “legacy” figures, created using GUIDE or the figure function)
  2. To a container window of docked Java-based figures, typically called an “App” (marketing name) or “Tool Group” (internal technical name)
  3. To a JavaScript/HTML-based Matlab figure (so called “web” figures, created using App Designer or the uifigure function)

Today I will show how to add a basic dynamic toolstrip to a ToolGroup (App, window type #2):

ToolGroup with clients and dynamic toolstrip
ToolGroup with clients and dynamic toolstrip

Figure containers (“Tool Groups”)

Most Matlab users are familiar with window types #1 and #3 (legacy and web-based figures), but type #2 may seem strange. In fact, it shouldn’t be: All the Matlab “Apps” and Desktop components use such a container of docked clients. For example, both the Matlab Editor and Desktop are containers of individual client windows (individual files in the Editor; Command Window, Workspace etc. in the desktop).
Similarly, when we dock figures, they dock as client windows into a container called “Figures” (this can be controlled programmatically: see my setFigDockGroup utility on the File Exchange). This is the basis for all Matlab “Apps”, as far as I am aware (some Apps may possibly use a different GUI container, after all there are ~100 Matlab Apps and I’m not familiar with all of them). Such Apps are basically stand-alone Tool Groups (client container windows) that contain one or more docked figures, a toolstrip, and a side-panel with controls (so-called “Data Browser”).
Note: MathWorks uses confusing terminology here, using the same term “App” for both MathWorks-created GUIs containers (that have toolstrips, Data Browser and docked figures) and also user-created utilities on the File Exchange (that do not have these). Unfortunately, MathWorks has chosen not [yet] to release to the general public its set of tools that enable creating true “Apps”, i.e. those that have a toolstrip, Data Browser and docked figures.
Today’s post will attempt to fill this gap, by showing how we can create user Apps that have a toolstrip and docked figures. I will ignore the Data Browser today, and will describe it in a future post. Since docking figures into a standalone user-created container is a solved problem (using my setFigDockGroup utility), this post will focus on adding a toolstrip to such a container.
A ToolGroup object (matlab.ui.internal.desktop.ToolGroup) is created either implicitly (by docking a figure into a group that has a new name), or explicitly (by invoking its constructor):

% Create a new non-visible empty App (Tool Group)
hToolGroup = matlab.ui.internal.desktop.ToolGroup('Toolstrip example on UndocumentedMatlab.com');

% Create a new non-visible empty App (Tool Group) hToolGroup = matlab.ui.internal.desktop.ToolGroup('Toolstrip example on UndocumentedMatlab.com');

Some things only work properly after the app is displayed, so let’s display the ToolGroup (however, note that for improved performance it is better to do whatever customizations and GUI updates that you can before the app is made visible):

% Display the ToolGroup window
hToolGroup.open();

% Display the ToolGroup window hToolGroup.open();

Basic empty ToolGroup (without toolstrip or clients)
Basic empty ToolGroup (without toolstrip or clients)

An annoying quirk with ToolGroups is that they automatically close when their reference handle is deleted from Matlab memory. The specific behavior changes depending on the contents of the container and the Matlab release, but in general it’s safest to preserve the hToolGroup variable, to prevent the window from closing, when this variable goes out of scope, when the function (in which we create the ToolGroup) returns. There are many ways to persist this variable. Here’s one alternative, in which we persist it in itself (or rather, attached to its internal Java peer control):

% Store toolgroup reference handle so that app will stay in memory
jToolGroup = hToolGroup.Peer;
internal.setJavaCustomData(jToolGroup, hToolGroup);

% Store toolgroup reference handle so that app will stay in memory jToolGroup = hToolGroup.Peer; internal.setJavaCustomData(jToolGroup, hToolGroup);

internal.setJavaCustomData is an undocumented Matlab function that adds a new custom property to a Java reference handle. In our case, it adds a CustomData property to the jToolGroup handle and sets its value to the Matlab hToolGroup handle. The source code for internal.setJavaCustomData is available in %matlabroot%/toolbox/shared/controllib/general/+internal/setJavaCustomData.m and is very simple: it essentially uses the old schema-based schema.prop method for adding new properties to handles. Schema is an old deprecated mechanism that is mostly replaced by the newer MCOS (Matlab Class Object System), but for some specific cases such as this it’s still very useful (the standard addprop function can add new properties to Matlab GUI handles, but not to Java reference handles).
Finally, let’s discard the Data Browser side panel (I’ll discuss it in a separate future post):

% Discard the Data-browser left panel
hToolGroup.disableDataBrowser();

% Discard the Data-browser left panel hToolGroup.disableDataBrowser();

Adding a toolstrip to the ToolGroup

Now that we have the basic container ready, let’s add a toolstrip. To simplify matters in this introductory post (after all, I have still not described the internal packages and classes that make up a toolstrip), we’ll use some of the tabs used in the showcaseToolGroup example that I discussed in my previous post. You can see the relevant source code in %matlabroot%/toolbox/matlab/toolstrip/+matlab/+ui/+internal/+desktop/*.m, in case you want to jump ahead and customize your own toolstrip tabs, groups and buttons. In the code snippet below, we first create an empty TabGroup, then add toolstrip tabs into it, and finally add this TabGroup into our ToolGroup using its addTabGroup(hTabGroup) method:

% Create a new tab group
%hTabGroup = matlab.ui.internal.desktop.showcaseBuildTabGroup('swing');
hTabGroup = matlab.ui.internal.toolstrip.TabGroup();
hTab1 = matlab.ui.internal.desktop.showcaseBuildTab_Buttons('swing');
hTabGroup.add(hTab1);
%hTabGroup.add(matlab.ui.internal.desktop.showcaseBuildTab_Gallery());
hTabGroup.add(matlab.ui.internal.desktop.showcaseBuildTab_Layout('swing'));
% Select tab #1 (common)
hTabGroup.SelectedTab = hTab1;
% Add the tab group to the built-in toolstrip
hToolGroup.addTabGroup(hTabGroup);

% Create a new tab group %hTabGroup = matlab.ui.internal.desktop.showcaseBuildTabGroup('swing'); hTabGroup = matlab.ui.internal.toolstrip.TabGroup(); hTab1 = matlab.ui.internal.desktop.showcaseBuildTab_Buttons('swing'); hTabGroup.add(hTab1); %hTabGroup.add(matlab.ui.internal.desktop.showcaseBuildTab_Gallery()); hTabGroup.add(matlab.ui.internal.desktop.showcaseBuildTab_Layout('swing')); % Select tab #1 (common) hTabGroup.SelectedTab = hTab1; % Add the tab group to the built-in toolstrip hToolGroup.addTabGroup(hTabGroup);

We now have an “App” that has a toolstrip, but no clients (yet), and a hidden Data Browser side-panel:

ToolGroup "App" with a simple toolstrip (no clients yet)

Now let’s add some clients (docked figures):

Adding clients (docked figures) to the ToolGroup

There are two easy variants for adding docked figures in a ToolGroup: The easiest is to use the ToolGroup’s addFigure(hFigure) method:

% Create a figure and dock it into the tool-group
hFig1 = figure('Name','3D');
surf(peaks);
hToolGroup.addFigure(hFig1);

% Create a figure and dock it into the tool-group hFig1 = figure('Name','3D'); surf(peaks); hToolGroup.addFigure(hFig1);

The second variant enables to dock a figure that has a specific set of toolstrip tabs attached to it. These tabs will only display in the toolstrip when that particular figure has focus. We do this by creating a new TabGroup (just as we have done above), and then add the figure and TabGroup to the container using the ToolGroup’s addClientTabGroup(hFigure,hTabGroup) method:

% Create the 2nd figure
hFig2 = figure('Name','2D');
plot(rand(5)); drawnow
% Add a few tabs that are only relevant to this specific figure
hTabGroup2 = matlab.ui.internal.toolstrip.TabGroup();
hTab2 = matlab.ui.internal.desktop.showcaseBuildTab_Selections();
hTabGroup2.add(hTab2);
hTabGroup2.add(matlab.ui.internal.desktop.showcaseBuildTab_EditValue());
% Add the figure and tabs to the ToolGroup
hToolGroup.addClientTabGroup(hFig2, hTabGroup2);

% Create the 2nd figure hFig2 = figure('Name','2D'); plot(rand(5)); drawnow % Add a few tabs that are only relevant to this specific figure hTabGroup2 = matlab.ui.internal.toolstrip.TabGroup(); hTab2 = matlab.ui.internal.desktop.showcaseBuildTab_Selections(); hTabGroup2.add(hTab2); hTabGroup2.add(matlab.ui.internal.desktop.showcaseBuildTab_EditValue()); % Add the figure and tabs to the ToolGroup hToolGroup.addClientTabGroup(hFig2, hTabGroup2);

ToolGroup with clients and dynamic toolstrip
ToolGroup with clients and dynamic toolstrip

In this example, the “Selection” and “Values” toolstrip tabs only appear when the 2nd figure (“2D”) has focus. A similar behavior exists in the Matlab Desktop and Editor, where some tabs are only shown when certain clients have focus.

Removing the View tab

Note that the “View” toolstrip tab (which enables setting the appearance of the docked figures: layout, tab positions (top/bottom/left/right), ordering etc.) is automatically added to the toolstrip and always appears last. We can remove this View tab using the ToolGroup’s hideViewTab() method. The tab will not immediately be removed, only when the toolstrip is repainted, for example, when we switch focus between the docked figures:

hToolGroup.hideViewTab;  % toolstrip View tab is still visible at this point
figure(hFig1);  % change focus to hFig1 - toolstrip is repainted without View tab

hToolGroup.hideViewTab; % toolstrip View tab is still visible at this point figure(hFig1); % change focus to hFig1 - toolstrip is repainted without View tab

Conclusion

It’s relatively easy to dock figures into a standalone “App” window that has a custom toolstrip, which can even be dynamically modified based on the figure which is currently in focus. Naturally, this has little benefit if we cannot customize the toolstrip components: labels, icons, control type, grouping and most importantly – callbacks. This topic deserves a dedicated post, which I plan to be the next in this miniseries. Stay tuned – hopefully the next post will not take me as long to publish as this post (I was quite busy recently)…

Related posts:

  1. Matlab toolstrip – part 5 (icons) – Icons can be specified in various ways for toolstrip controls and the app window itself. ...
  2. Matlab toolstrip – part 1 – Matlab contains extensive toolstrip (ribbon) functionality that can be integrated in user programs (GUI). ...
  3. Matlab toolstrip – part 9 (popup figures) – Custom popup figures can be attached to Matlab GUI toolstrip controls. ...
  4. Matlab toolstrip – part 8 (galleries) – Matlab toolstrips can contain customizable gallery panels of items. ...
  5. Matlab toolstrip – part 4 (control customization) – Matlab toolstrip components (controls) can be customized in various ways, including user-defined callbacks. ...
  6. Matlab toolstrip – part 7 (selection controls) – Matlab toolstrips can contain a wide variety of selection controls: popups, combo-boxes, and galleries. ...
Figure GUI schema.prop Toolstrip Undocumented feature
Print Print
« Previous
Next »
17 Responses
  1. Alex December 17, 2018 at 16:48 Reply

    Hi Yair,

    “hTabGroup2 = TabGroup();” in section “Adding clients (docked figures) to the ToolGroup” should be
    “hTabGroup2 = matlab.ui.internal.toolstrip.TabGroup();”

    Greetings Alex

    • Yair Altman December 17, 2018 at 17:06 Reply

      @Alex – thanks, fixed

  2. Henry December 19, 2018 at 08:20 Reply

    Hi, Yair

    Thanks for your introduction of this toolstrip. if this toolstrip can be deploy as a standalone application, it will be amazing.
    it is success to deploy the ToolGroupApp.exe (save all your commands as ToolGroupApp.m and ‘mcc -m ToolGroupApp’), but when running it, the two figures will jump out as two windows, not dock as two cilents in the toolgroup.
    is it possible to solve this problem, so that the wonderful toolstrip can demploy as a exe with beatuiful user interface?

    looking forward to your reply

    best
    Henry

    • Yair Altman December 21, 2018 at 02:13 Reply

      @Henry – for some unknown reason, MathWorks have chosen to intentionally prevent figure docking in compiled applications. There used to be a workaround for this, but it is no longer working (in other words, MathWorks have closed the loophole) in recent Matlab releases.

    • Henry December 22, 2018 at 10:39 Reply

      Hi Yair

      Thanks for your answer. Maybe MATHWORKS want to prevent their own APPs in the matlab. If they can be deployed, all the Apps can be used without license. But it is very pity, otherwise, matlab can build very wonderful apps to users.

  3. Tanguy December 19, 2018 at 20:26 Reply

    Hello Yair,

    minor correction (on the part you recently corrected, sorry):

    % hTabGroup2 = matlab.ui.internal.desktop.TabGroup();
    % should be :
    hTabGroup2 = matlab.ui.internal.toolstrip.TabGroup();

    % hTabGroup2 = matlab.ui.internal.desktop.TabGroup(); % should be : hTabGroup2 = matlab.ui.internal.toolstrip.TabGroup();

    Other than that great article. Just a note, for MATLAB R2016a, the “addClientTabGroup” method to add a specific tab linked with a figure has to be called after the figure is attached, so for this version the code becomes:

    % Add the figure and tabs to the ToolGroup
    hToolGroup.addFigure(hFig2);
    hToolGroup.addClientTabGroup(hFig2, hTabGroup2);

    % Add the figure and tabs to the ToolGroup hToolGroup.addFigure(hFig2); hToolGroup.addClientTabGroup(hFig2, hTabGroup2);

    Everything works fine after that.

    • Yair Altman December 19, 2018 at 21:08 Reply

      @Tanguy – thanks for the typo correction, now fixed.

  4. Arash Marashian March 30, 2019 at 18:46 Reply

    Hi, thanks for your good information,
    I have a question here:
    how can we set a specific initial view model?
    For example, I want to plot step resp. and impulse resp. together in one window (as we have “left/right” in the view tab).

    • Yair Altman April 1, 2019 at 17:15 Reply

      @Arash – I plan to discuss client layups in a future post of this mini-series. In the meantime you can play with this:

      jDesktop = com.mathworks.mlservices.MatlabDesktopServices.getDesktop;
      dockType = jDesktop.TILED;  % NONE=0, MAXIMIZED=1, TILED=2, FLOATING=3
      panelSize = java.awt.Dimension(2,1);  % 2 columns, 1 row  (leave =[] for non-TILED)
      jDesktop.setDocumentArrangement(hToolGroup.Name, dockType, panelSize);

      jDesktop = com.mathworks.mlservices.MatlabDesktopServices.getDesktop; dockType = jDesktop.TILED; % NONE=0, MAXIMIZED=1, TILED=2, FLOATING=3 panelSize = java.awt.Dimension(2,1); % 2 columns, 1 row (leave =[] for non-TILED) jDesktop.setDocumentArrangement(hToolGroup.Name, dockType, panelSize);

      • K January 24, 2023 at 05:20

        Is there a way to programmatically manage which figure gets placed where? Let’s say I have 5 figures docked, and I split it into 2 x 1, I want to place 3 specific figures on the ‘top row’, and 2 specific figures on the ‘bottom row’. I’ve had no luck finding any settings to dock to a specific tile pane, all figures are docked to the ToolGroup app/Group, then it’s being split up by some logic from there.
        This becomes more problematic if I’m modifying dimensions and merging columns. So I want row 1 to span 2 columns, and row 2 to have 2 separate columns. Sometimes this works fine, other times I can see figures just disappear, they’re still there via their handle checks but somehow invisible and I can’t get them back into a pane or appear anywhere. Some type of ‘assign figure to pane’ would be extremely useful. I’ll keep searching…

  5. Thomas Satterly April 24, 2019 at 20:49 Reply

    Thanks for writing this series, I’ve found using the ToolGroup very enjoyable in new lightweight apps. One issue/annoyance I’ve noticed is that conditional tab groups (using the addClientTabGroup() method) will remove and re-add themselves every time a new figure is selected that uses the tab group. This creates a “flashing” effect as the view is rendered during the removal and addition process. For reference, I’m using Matlab R2016b. Is this a unique issue, or are other people seeing the same effects?

  6. Rohit September 10, 2019 at 17:41 Reply

    Is there any way to display “Figure’s default Toolbar” when docked to “ToolGroup”? as it does when you use Matlab’s default docking option.

  7. Jacopo December 3, 2019 at 12:46 Reply

    I’m currently using Matlab 2019b.
    For the application (software) I’m currently developing, I would like to modify the toolstrip of a Simulink window I’m opening using new_system/load_system, but I don’t know how to retrieve the handle to that figure.
    I found something useful in an old post (http://undocumentedmatlab.com/articles/accessing-the-matlab-editor), but here you retrieve the “Editor” window handle (and, looking at the group/client titles I cannot find anything related to simulink).
    Does anyone know how to solve this problem?

  8. Prathep February 2, 2021 at 11:19 Reply

    Hi Yair,
    Thanks for your introduction on Matlab Toostrip. Is there any way to add Matlab toolstrip for uifigures as you have done already for figure?

  9. Kevin October 20, 2022 at 17:46 Reply

    I’m interested in removing the (X) close button from figures added to the Toolstrip. There’s a lot of functionality that can be programmed into docked figures, effectively becoming mini GUIs, but I don’t want the user to be able to close them. Obviously I can write a close function that does nothing, but preferably the (X) icon is not present either. I can see Mathworks is doing this in the Solver Profiler tool used for Simulink, there are figures added to what appears to be a GUI constructed using ToolGroup features (you can probe tiled sections using gcf), but the figures do not have the (X) close button. Can’t seem to find that property anywhere.

    • Kevin October 21, 2022 at 15:18 Reply

      Found it, findjobj utility was extremely helpful here, you can see there’s a CloseButton object there, just need to set the visible parameter to false. Easily done in the findjobj utility, will take some more time to figure out how to do it programmatically as my java is not particularly strong.
      It’s actually not part of the figure, it’s a tab close button, need to figure out how to navigate to that object’s location to set it.
      Very much appreciate all the material you’ve put out on this, no way I would’ve otherwise figured out (or known about) any of this!

      • Yair Altman October 27, 2022 at 17:14
        titleStr = char(hFig.Name);
        if strcmpi(hFig.NumberTitle,'on')
           prefix = ['Figure ' num2str(hFig.Number)];
           if ~isempty(titleStr)
              titleStr = [prefix ': ' titleStr];
           else
              titleStr = prefix;
           end
        end
         
        jToolGroup = hFig.JavaFrame_I.getFigurePanelContainer.getTopLevelAncestor;
        %alternative: =hToolGroup.SwingToolstrip.getComponent.getTopLevelAncestor;
         
        jTab = findjobj(jToolGroup, 'class','DTDocumentTabs$Tab', 'property',{'Text',titleStr});
        if ~isempty(jTab)
           jCloseButton = jTab.getComponent(0);
           jTab.remove(jCloseButton);  % or: jCloseButton.setVisible(false)
           jTab.repaint
        end

        titleStr = char(hFig.Name); if strcmpi(hFig.NumberTitle,'on') prefix = ['Figure ' num2str(hFig.Number)]; if ~isempty(titleStr) titleStr = [prefix ': ' titleStr]; else titleStr = prefix; end end jToolGroup = hFig.JavaFrame_I.getFigurePanelContainer.getTopLevelAncestor; %alternative: =hToolGroup.SwingToolstrip.getComponent.getTopLevelAncestor; jTab = findjobj(jToolGroup, 'class','DTDocumentTabs$Tab', 'property',{'Text',titleStr}); if ~isempty(jTab) jCloseButton = jTab.getComponent(0); jTab.remove(jCloseButton); % or: jCloseButton.setVisible(false) jTab.repaint end

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