Matlab toolstrip – part 1

The Matlab toolstrip (ribbon) has been around officially since R2012a, and unofficially for a couple of years earlier. Since then, I blogged about the toolstrip only rarely (example). I believe the time has come to start a short mini-series about this functionality, eventually showing how users can use toolstrips in their own custom applications.

My plan is to start the miniseries with a discussion of the built-in showcase examples, followed by a post on the built-in classes that make up the toolstrip building-blocks. Finally, I’ll describe how toolstrips can be added to figures, not just in client/tool groups.

Matlab’s internal showcase examples

I start the discussion with a description of built-in examples for the toolstrip functionality, located in %matlabroot%/toolbox/matlab/toolstrip/+matlab/+ui/+internal/+desktop/. The most important of these are showcaseToolGroup.m and showcaseMPCDesigner.m, both of which use Java-based (Swing) containers and controls. Readers who wish to integrate toolstrips into their app immediately, without waiting for my followup posts in this series, are welcome to dig into the examples’ source-code and replicate it in their programs:

1. showcaseToolGroup
h = matlab.ui.internal.desktop.showcaseToolGroup

showcaseToolGroup built-in example

2. showcaseMPCDesigner
>> h = matlab.ui.internal.desktop.showcaseMPCDesigner
 
h =
  showcaseMPCDesigner with properties:
 
    ToolGroup: [1×1 matlab.ui.internal.desktop.ToolGroup]
       Dialog: [1×1 toolpack.component.TSTearOffPopup]
      Figure1: [1×1 Figure]
      Figure2: [1×1 Figure]

showcaseMPCDesigner built-in example

3. showcaseHTML and showcaseCEF

In addition to these showcase examples, the folder also contains a showcaseHTML.m and showcaseCEF.m files, that are supposed to showcase the toolstrip functionality in JavaScript-based containers (browser webpage and uifigure apps, respectively). Unfortunately, on my system running these classes displays blank, although the toolstrip is indeed created, as seen below (if you find out how to make these classes work, please let me know):

>> h = matlab.ui.internal.desktop.showcaseHTML
building toolstrip hierarchy...
rendering toolstrip...
 
h = 
  Toolstrip with properties:
 
               SelectedTab: [1×1 matlab.ui.internal.toolstrip.Tab]
              DisplayState: 'expanded'
    DisplayStateChangedFcn: @PropertyChangedCallback
                       Tag: 'toolstrip'
 
>> hs = struct(h)
Warning: Calling STRUCT on an object prevents the object from hiding its implementation details and should thus be avoided.
Use DISP or DISPLAY to see the visible public details of an object. See 'help struct' for more information.
(Type "warning off MATLAB:structOnObject" to suppress this warning.)
 
hs = 
  struct with fields:
 
                         SelectedTab: [1×1 matlab.ui.internal.toolstrip.Tab]
                        DisplayState: 'expanded'
              DisplayStateChangedFcn: @PropertyChangedCallback
                 DisplayStatePrivate: 'expanded'
                        QABIdPrivate: '2741bf89'
               QuickAccessBarPrivate: [1×1 matlab.ui.internal.toolstrip.impl.QuickAccessBar]
       DisplayStateChangedFcnPrivate: @PropertyChangedCallback
         SelectedTabChangedListeners: [1×1 event.listener]
                                 Tag: 'toolstrip'
                                Type: 'Toolstrip'
                          TagPrivate: 'toolstrip'
    WidgetPropertyMap_FromMCOSToPeer: [3×1 containers.Map]
    WidgetPropertyMap_FromPeerToMCOS: [3×1 containers.Map]
                              Parent: [0×0 matlab.ui.internal.toolstrip.base.Node]
                            Children: [1×1 matlab.ui.internal.toolstrip.TabGroup]
                             Parent_: []
                           Children_: [1×1 matlab.ui.internal.toolstrip.TabGroup]
                                Peer: [1×1 com.mathworks.peermodel.impl.PeerNodeImpl]
                   PropertySetSource: [1 java.util.HashMap]
                    PeerModelChannel: '/ToolstripShowcaseChannel'
                   PeerEventListener: [1×1 handle.listener]
                 PropertySetListener: [1×1 handle.listener]
 
>> hs.Peer
ans =
PeerNodeImpl{id='4a1e4b08', type='Toolstrip', properties={displayState=expanded, hostId=ToolStripShowcaseDIV, tag=toolstrip, QABId=2741bf89}, parent=878b0e2b, children=[
    PeerNodeImpl{id='5bb9632c', type='TabGroup', properties={QAGroupId=ea9b628c, tag=, selectedTab=f90db10c}, parent=4a1e4b08, children=[
        PeerNodeImpl{id='f90db10c', type='Tab', properties={mnemonic=, tag=tab_buttons, title=BUTTONS}, parent=5bb9632c, children=[
            PeerNodeImpl{id='1ccc9246', type='Section', properties={collapsePriority=0.0, mnemonic=, tag=sec_push, title=PUSH BUTTON}, parent=f90db10c, children=[
                PeerNodeImpl{id='8323f06e', type='Column', properties={horizontalAlignment=left, width=0.0, tag=}, parent=1ccc9246, children=[
                    PeerNodeImpl{id='af368d7b', type='PushButton', properties={textOverride=, descriptionOverride=, mnemonic=, actionId=230d471b, iconOverride=, tag=pushV, iconPathOverride=}, parent=8323f06e, children=[]}]}
                PeerNodeImpl{id='a557a712', type='Column', properties={horizontalAlignment=left, width=0.0, tag=}, parent=1ccc9246, children=[
                    PeerNodeImpl{id='f0d6a9fc', type='EmptyControl', properties={tag=}, parent=a557a712, children=[]}
                    PeerNodeImpl{id='74bc4cd2', type='PushButton', properties={textOverride=, descriptionOverride=, mnemonic=, actionId=12d6a26a, iconOverride=, tag=pushH, iconPathOverride=}, parent=a557a712, children=[]}
                    PeerNodeImpl{id='bcb5a9d0', type='EmptyControl', properties={tag=}, parent=a557a712, children=[]}]}]}
            PeerNodeImpl{id='0e515319', type='Section', properties={collapsePriority=0.0, mnemonic=, tag=sec_dropdown, title=DROP DOWN BUTTON}, parent=f90db10c, children=[
                PeerNodeImpl{id='80482225', type='Column', properties={horizontalAlignment=left, width=0.0, tag=}, parent=0e515319, children=[
                    PeerNodeImpl{id='469f469a', type='DropDownButton', properties={textOverride=, descriptionOverride=, mnemonic=, actionId=c6ca7335, iconOverride=, tag=dropdownV, iconPathOverride=}, parent=80482225, children=[]}]}
                ...

Note: showcaseCEF has been removed in 2018, but is available in older Matlab releases.

Levels of toolstrip encapsulation

Matlab currently has several levels of encapsulation for toolstrip components:

  • Top-level m-file classes for showcasing the toolstrip functionality and creating toolstrips in Java-based containers and web-based apps – these are located in %matlabroot%/toolbox/matlab/toolstrip/+matlab/+ui/+internal/+desktop/
  • Mid-level m-file classes that contain the toolstrip building blocks (tabs, sections, controls) – these are located in %matlabroot%/toolbox/matlab/toolstrip/+matlab/+ui/+internal/+toolstrip/
  • Low-level Java classes that implement the underlying user-interface for Java-based UI – these are located in %matlabroot%/java/jar/toolstrip.jar. I discussed this briefly in a post few years ago.

The top- and mid-level m-file classes are provided with full source code that is quite well-documented internally (as m-file source-code comments). However, note that it is not officially documented or supported (i.e., semi-documented in this blog’s parlance).

The low-level Java classes on the other hand are compiled without available source code – we can inspect these classes (e.g., using uiinspect or checkClass), but we cannot see their original source-code. Luckily, the higher-level m-file classes provide us with plenty of hints and usage examples that we could use to tailor the appearance, functionality and integration of toolstrip components into our app.

Robyn Jackey’s Widgets Toolbox

Users who hesitate to mess around with the built-in toolstrip functionality may find interest in MathWorker Robyn Jackey’s Toolstrip look-alike, which is part of his open-source Widgets Toolbox on the Matlab File Exchange. Unlike other parts of Robyn’s toolbox, which use undocumented functionality, his Toolstrip class seems to use documented components (panels, uicontrols etc.), with just a small reliance on undocumented functionality (matlab.ui.* for example). This has a fair chance to continue working well into future releases, even if Matlab’s built-in toolstrip functionality changes:

Robyn Jackey's Toolstrip look-alike

Strong caution

Over the years, Matlab’s internal toolstrip interface has changed somewhat, but not dramatically. This could change at any time, since the toolstrip uses deeply undocumented functionality. What I will demonstrate over the next few posts might stop working in R2019a, or in R2025b – nobody really knows, perhaps not even MathWorks at this stage. Something that we do know for a fact is that Matlab is slowly transitioning away from Java-based user interfaces to web-based (HTML/JavaScript/CSS) interfaces, and this could have a drastic effect on the toolstrip functionality/API. It seems reasonable to assume that even if MathWorks would one day open up the toolstrip functionality, this would only be for the new web-based uifigure apps (not legacy Java-based figures), and might well have a different API than the one that I’ll discuss in this miniseries. Still, users could use the unofficial/undocumented information that I present here in their own Java figures today and quite possibly also in near-term upcoming releases.

Despite the many unknowns regarding future supportability/roadmap of the built-in toolstrip API, I believe that my readers are smart enough to decide for themselves whether they want to take the associated risks to improve their Matlab programs today, or wait until a documented API will possibly be provided sometime in the future. The choice is yours, as it always is when using undocumented tips from my blog.

With this warning stated, let’s start having fun with Matlab’s built-in toolstrip!

Categories: Desktop, GUI, High risk of breaking in future versions, Semi-documented feature

Tags: , , ,

Bookmark and SharePrint Print

5 Responses to Matlab toolstrip – part 1

  1. Paul Andrews says:

    Yair,

    This post is great. Thanks you for sharing this. I’ve been interested in building application with the toolstrip for quite a while, and I am really happy to see that it is possible. 😉
    Now, I tried compiling the showcaseMPCDesigner to see if the toolstrip would work in a compile application.
    I was able to compile it, and the toolstrip appears to work well. However, the figures will not dock when compiled. Do you know if there is a way around this?
    The work around discussed in your https://undocumentedmatlab.com/blog/docking-figures-in-compiled-applications#comment-442454 post don’t seem to work in the newer releases.

    Thank you in advance,

    Paul

  2. Ramiro Massol says:

    hi Yair,
    it’s been a long time that i don’t write to you, too much work and not enough time to put my hands on Matlab. I’m very glad that you are taking a loot at the toolstrip. When are you posting part 2 of this series?
    best regards,
    Ramiro

  3. Brett says:

    Yair,
    Thanks for sharing so much information on the toolstrip. This is really helpful.
    Do you know if it’s possible to change the icon on the ToolGroup object? I see the class has a setIcon() method, but I haven’t been able to make it work.
    Thanks,
    Brett

  4. Gang YAO says:

    showcaseToolGroup.m is gone in R2019a…

Leave a Reply

Your email address will not be published. Required fields are marked *